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>)
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.
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
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.
"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
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.
> 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).
@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....?????
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.)
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.
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
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.
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.
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.