Forum: Compiler & IDEs HINWEIS: abgekündigte Funktionen/Makros verschwinden bald


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jörg Wunsch (Gast)


Lesenswert?

Nur als Hinweis:

avr-libc 1.2.0 steht vor der Tür.  Da diese Version im Gegensatz zur
eben bereitgestellten 1.0.5 auch die aktuellen AVRs
(ATmega{48,88,168}, AT90CAN128, ATtiny13, ATtiny2313, ...)
unterstützt, will Eric Weddington sie als Basis für die nächste
WinAVR-Version benutzen.  (In der letzten Version hat er das alles mit
privaten Patches realisiert.)

Damit werden dann endgültig alle schon lange abekündigten Makros,
Funktionen, Header-Dateien usw. verschwinden, insbesondere:

. cbi, sbi
. inp, outp, inb, outb, inw, outw
. BV
. eeprom_{rb,rw,wb}
. PRG_RDB
. <avr/timer.h>
. Headerdateien aus ${PREFIX}/avr/include, die nach
  ${PREFIX}/avr/include/avr umgezogen sind (also z. B.
  <io.h> heißt jetzt <avr/io.h>)

von Stefan May (Gast)


Lesenswert?

Hallo Jörg,

Wodurch sind die in avr/timer.h enthaltenen Routinen denn zu ersetzen?
Workaround? Oder muß ich das jetzt selber definieren?

Und wann wurde das denn deprecated erklärt?

ciao, Stefan.

von Peter D. (peda)


Lesenswert?

Da es ja Macros sind, steht es jedem frei, diese weiterhin zu
verwenden.

Sie sind bloß nicht mehr in den Standard-Includes vordefiniert, d.h.
man muß sie sich selber in ein privates Include reinkopieren, das man
dann vorzugsweise mit im Projektverzeichnis ablegt.


Auch steht es jedem frei die Standard-Includes ein Verzeichnis nach
oben zu kopieren um sich damit das avr/ zu sparen.

Ich mache das z.B. immer so, da ich oft Quellcode auf mehreren MCs
verwende und deshalb kein Lust habe, immer sämtliche #include anpassen
zu müssen, wenns mal auf dem ARM oder 8051 wechselt.


Peter

von Stefan May (Gast)


Lesenswert?

Na das mit dem kopieren ist mir ja nix. Da würde ich lieber den
Quellcode mit Präprozessoranweisungen verändern. Aber das ist ja
Geschmackssache. Ich verändere ungern Standard-Libraries, weil ein
Update dann umso schwieriger wird.

Die Makros und Konstanten habe ich mir jetzt in meinem eigenen
Quelltext definiert.

ciao, Stefan.

von Peter D. (peda)


Lesenswert?

"Na das mit dem kopieren ist mir ja nix."

Da hast Du mich mißverstanden.

Ich meinte, alles von "...AVR/INCLUDE/AVR" nach "...AVR/INCLUDE"
kopieren.

Damit kannst Du dann schreiben:

#include<stdio.h>

usw. und es läuft auf dem AVR als auch auf dem 8051.

Sonst müßte man immer schreiben:

#ifdef Blabla_keil
#include<stdio.h>
#endif
#ifdef Blabla_avr
#include<avr/stdio.h>
#endif

d.h. Du müßtest Dir erstmal dieses Blabla... definieren.


Ich habe mir z.B. einen Multimaster I2C-Treiber mit Interrupt
geschrieben, der läuft auf 8051, AVR und ARM, weil das Hardware I2C
völlig identisch ist.
Beim Philips-ARM war das klar, aber das Atmel das I2C von Philips
abgekupfert hat, find ich lustig.


Peter

von Stefan May (Gast)


Lesenswert?

Doch, ich habe es genauso verstanden. :-)

Ich entwickle aber kaum für unterschiedliche Mikrocontroller. Insofern
tritt das Problem bei mir nicht so stark auf.

Daß der I2C-Teil bei Atmel und Philips gleich ist, wundert mich nicht
so sehr. Fertige I2C-Controller kann man als IP-Core kaufen und dann in
eigenen Chips einsetzen.

ciao, Stefan.

von Jörg Wunsch (Gast)


Lesenswert?

> Wodurch sind die in avr/timer.h enthaltenen Routinen denn zu
> ersetzen?

Die Dinger haben nie wirklich richtig funktioniert.  Das Setzen der
TCNT-Register startet oder stopt den Timer in keiner Weise, das war
schon immer Unfug.  Die Bitdefinitionen stimmen nur für einige AVRs,
andere wie z. B. der ATmega128 brauchen für die gleiche Funktion
andere Bitwerte (bzw. implementieren gänzlich andere Vorteilerwerte).

Da das Ganze schließlich nur für den Timer 0 überhaupt da drin stand,
war es zudem noch so unvollständig, dass es keinen Sinn hatte, sowas
überhaupt noch weiter als Bestandteil der Bibliothek pflegen zu
wollen.

Letztlich wird sich jeder für die entsprechende Funktionalität seine
eigenen Makros oder (inline) Funktionen schreiben (müssen).

von Erni (Gast)


Lesenswert?

@peter dannegger:
wie kannst du denn die dateien von "...AVR/INCLUDE/AVR" nach
"...AVR/INCLUDE" kopieren (z.B. stdio.h) die stdio.h is doch im
verzeichniss AVR/INCLUDE schon drinne....?????

von Jörg Wunsch (Gast)


Lesenswert?

Die Trennung wurde übrigens sehr bewusst vorgenommen.  Wenn in
irgendwelchem Code ein

#include <signal.h>

stehen sollte, dann meint der Autor dieses Codes garantiert nicht
das, was er unter

#include <avr/signal.h>

finden kann.  <signal.h> ist vom C-Standard gesetzt, hat aber im
AVR-Kontext zumindest ohne Betriebssystem keinen Sinn.  Andersrum,
sollte ein Betriebssystem existieren und <signal.h> implementieren, so
wären plötzlich <signal.h> und <avr/signal.h> existent und zwei sehr
verschiedene Dinge.

Die Motivation, warum einer das Subdir in #include <avr/...> nicht
schreiben will, verstehe ich nicht (sorry Peter), aber wenn das schon
sein muss, dann nehmt bitte -I Compiler-Optionen dafür.  (Die sollte
wohl auch jeder Compiler verstehen, ältere Compiler nur ohne
Leerzeichen nach dem -I.)

von Marcus Maul (Gast)


Lesenswert?

Hallo Jörg,

wann wirds denn die neue WinAVR Version geben?

Gruß und guten Rutsch 2 all.

Marcus

von Jörg Wunsch (Gast)


Lesenswert?

Das musst Du Eric fragen -- ich mache ja WinAVR nicht selbst.

Da er es aber auch als reine Freizeitarbeit macht, einen Job hat und
nicht wenige Kinder :), zieht sich sowas immer ein wenig länger hin,
als man ursprünglich beabsichtigt.

von Holger Gerwenat (Gast)


Lesenswert?

Hallo,

erstmal allseits ein gesundes Neues Jahr.

An dieser Stelle möcht ich mal meinen Senf dazugeben:Ich entdecke
langsam AVRGCC für mich (schon ca. ein Jahr lang). Ja! ich bin kein
professioneller Programmierer, ich hab C nie gelernt, ich hab auch
nicht die Zeit um mich täglich mit C zu beschäftigen. Ich versuche
einfach
viel zu lesen und dann zu probieren. Im Netz gibt es verschiedene Kurse
und Infos zu dem Thema. Wenn dann Beispiele nicht mehr funktionieren,
weil GCC irgendwelche Befehle nicht mehr kennt, find ich das nicht
gut.
Neu eingeführte Makros sind in ihrer Schreibweise nicht unbedingt
verständlicher. Jedenfalls aus der Sicht eines Anfängers. Meine Frage
ist: warum muss überhaupt ständig irgendwas geändert werden? Stichwort
Abwärtskompatibilität! Warum kann GCC nicht (SBI) UND (_BV) verstehen
und verarbeiten?
Das Ganze kommt mir so wie die Diskussion um Eagle vor: Version 4.13
kann keine Bibliothek mehr von Version 4.xy lesen. Willst Du das musst
Du über irgendwelche Scriptfunktionen ex- und importieren oder Hex Wert
ABC ändern - echt SCH...

Gruss Holger

von mthomas (Gast)


Lesenswert?

Für C-Anfänger ist der Wegfall von Funktionen/Makros wie inb/outb/sbi
etc. und BV eigentlich von Vorteil (_BV gibt's sogar scheinbar
weiterhin). Man kann in jedem C-Buch nachlesen, wie Bits
gesetzt/gelöscht werden und muss sich nicht noch zusätzlich mit avrgcc
oder libc "Extrawürsten" auseinandersetzen. Das einige alte
Beispielcodes dann nicht mehr ohne weiteres compiliert werden können,
ist vielleicht etwas störend, aber immer noch besser, als ständig
irgendwelche Altlasten mitzuschleppen. Die Möglichkeit die
"entrümpelten" Makros durch selbtdefinierte zu ersetzen, wurde ja
schon erwähnt. Als Vorteil lassen sich viele Beispielcodes von Atmel
(Datenblätter/AppNotes meist für IAR) inzwischen deutlich leichter an
avrgcc/avr-libc anpassen. Nicht das jeder Atmel-Code immer die beste
Lösung ist, aber fast immer Informativ.

von Jörg Wunsch (Gast)


Lesenswert?

Auch, wenn ich's schon x-mal vorgekaut habe:

Die historischen Makros sind zu einer Zeit entstanden, da der AVR-GCC
einfach noch nicht in der Lage war, sowas wie

PORTB = 42;

DDRB |= (1 << 4);

zu verarbeiten.  Als Krücke, damit man überhaupt auf die IO-Ports
sinnvoll zugreifen kann, entstanden dann diese Makros (die damals
reine inline-Assembler-Hacks waren).

Seit geraumer Zeit kann AVR-GCC (+ avr-libc) diese Funktionalität, und
dies ist (wie Martin bemerkt) erstens die Standard-C-Methode (wie man
sie also auch beispielsweise in einem Unix-Kernel massig findet,
wenn dort irgendwo ein Bit in einem Port-Register geändert werden
muss) und stimmt zweitens vor allem mit der Atmel-Schreibweise
überein.

Für eine Übergangszeit wurden zur Erleichterung der Umgewöhnung die
alten Makros noch bereitgestellt -- übrigens nicht mehr als
inline-asm-Hacks, sondern sbi(r, b) war halt wirklich weiter nix als
(r) |= (1 << (b)), mit allen Seiteneffekten (erweiterter Wertebereich
gegenüber dem Hardware-SBI, Hardware-SBI wurde nur generiert, wenn
auch die Optimierung eingeschaltet ist).

Diese Übergangszeit ist nun einfach mal vorbei.  Die Abkündigung liegt
zweieinhalb Jahre zurück.  Die Umstellung des entsprechenden
historischen Ballasts ist mit einem geeigneten Editor eine Sache von
wenigen Minuten pro Datei.

Neben der Rückkehr zu Standards möchten wir damit übrigens auch die
Leute zum Nachdenken anregen über ihren Code.  Ich habe schon genügend
Beispiele gesehen der Art:

sbi(DDRB, 0);
sbi(DDRB, 1);
sbi(DDRB, 2);
sbi(DDRB, 3);

wo es beim Hinschreiben von

DDRB |= (1 << 0);
DDRB |= (1 << 1);
DDRB |= (1 << 2);
DDRB |= (1 << 3);

vielleicht manch einem ja dämmert, dass es einfacher und schneller
sein könnte, gleich

DDRB |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);

oder ggf. gar (je nach Ausgangszustand von DDRB)

DDRB = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);

zu schreiben.  Schon wird der generierte Code kürzer und schneller.

Gleichermaßen bin ich überzeugt, dass nach einer Übergangszeit all die
__attribute__((progmem)) Hacks verschwinden werden, wenn der GCC denn
endlich mal multiple memory spaces kann, sodass man den ROM ordentlich
mit Standard-C-Syntax explizit angeben kann.  Aber da reden wir über
einen Zeitraum von Jahren.

von Holger Gerwenat (Gast)


Lesenswert?

@Jörg:

Nicht böse sein! Ja hast Du schon zig mal geschrieben. Aber kann man
nicht mal eine andere Meinung haben? Ich kann's Dir nicht erklären!!!
Wirklich nicht! aber:

sbi(DDRB, 0);
sbi(DDRB, 1);
sbi(DDRB, 2);
sbi(DDRB, 3);

liest sich für mich einfacher und verständlicher(Alles klar: setze Bit
in I/O Register DDRB,0 ...) als:

DDRB |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);

Hie wird was verodert und Bits werden geschoben. Ich nehm Dir mal
ungesehen ab, das das Gleiche wie oben passiert.

>Schon wird der generierte Code kürzer und schneller.

Ja , das Argument verstehe ich - ist OK!

>Gleichermaßen bin ich überzeugt, dass nach einer Übergangszeit all
die
__attribute__((progmem)) Hacks verschwinden werden, wenn der GCC denn
endlich mal multiple memory spaces kann, sodass man den ROM ordentlich
mit Standard-C-Syntax explizit angeben kann.  Aber da reden wir über
einen Zeitraum von Jahren.

Diese Ausführungen sind Böhmische Dörfer für mich!

Im Endeffekt ist GCC ja nur ein Werkzeug. Ich würde zum Blech biegen
auch den Hammer mit dem krummen 30cm Stiel nehmen. Mit dem kann ich
eben gut. Auch wenn die EU "Normgerechte Hämmer mit 20cm Stiel, rot
lackiert" vorschreibt.

Ich will ja auch bitte keine Diskussion entfachen, ich weiss nur zu gut
wie viel Arbeit(kann es mir wenigstens vorstellen) in so einem Projekt
steckt. Das die Macher vom AVRGCC diesen bereitstellen ist nicht mit
Gold aufzuwiegen!! Euch für Eure unermüdliche Arbeit vielen Dank!

Eigentlich wollte ich nur noch sagen, ich wünsche mir eine
"oldstyle.h" oder "kompat.h". Oben mit include eingebunden und ALLE
alten Code gehen - ohne Nachdenken, ohne Änderungen im Quellcode.

Vielleicht bin ich ja auch der Einzige, der so denkt.

Und GUT jetzt.

Grüsse Holger

von Jörg Wunsch (Gast)


Lesenswert?

Damit wirst Du den alten Schrott aber nie los.  Es ist eine Last, wenn
man ewig zu 300 % rückwärtskompatibel bleiben muss.

Erkenntnis aus 12 oder so Jahren Opensource-Arbeit: neue Dinge musst
Du den Leuten aufdrängeln.  Danach finden sie's dann irgendwann ganz
gut.

sbi(foo, bar) liest sich nur solange besser, solange Du beim AVR bist,
weil Du es ganz zufällig mit seinem natürlichen SBI-Befehl verknüpfst.
Spätestens, wenn Du mal Code lesen musst, der für einen anderen
Prozessor geschrieben worden ist oder Deinen eigenen Code gar
irgendwann auf einen anderen Prozessor portierst, liest es sich gar
nicht mehr so natürlich.

Wie gesagt, Unix-Kernelprogrammierer (die bereits seit vielen Jahren
Bitmanipulationen in C schreiben müssen) haben Null Probleme, Code wie

foo |= BAR;
foo &= ~BAR;

zu verstehen, weil es halt generisches C ist.  Wenn AVR-GCC nicht
irgendwann mal die Krücke mit sbi und cbi und so gebraucht hätte,
hätte die AVR-GCC-Gemeinde sicher auch gar keine Probleme damit, weil
sie sich von vornherein an die natürliche C-Schreibweise gewöhnt
hätte.

Wenn Du's unbedingt brauchst, ist es Dir ja unbenommen, Dein eigenes
Headerfile damit zu pflegen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.