Hallo,
ich möchte jetzt ein paar Projekte mit verschieden AVR Controller in C
realisieren.
Welche der Folgenden C Compiler ist der Beste, für mich spielt die
Codezize und Workingspeed gefolgt von der unterstützung der
verschiedenen Controller ung Qualität der IDE eine Rolle.
Alles mal abgesehen vom anschaffungspreis der Compiler.
1. AVRGCC
2. CodeVision AVR Prof.
3. ImageCraft AVR C
Wo liegen die vor und nachteile dieser Compiler? Gibt es irgendwo
Benchmarkes? So in etwa auf jedem Compiler der selbe C code und dann
messen welcher am schnellsten ist und welche Codezize am geringsten
ist.
Ich habe bis jetzt zu 80% alles in ASM gemacht und komme damit auch
sehr gut zurecht, aber die entwicklungszeit der SW ist doch sehr lang
im vergleich zu einer SW die man teilweise in C schreiben kann.
Danke
MfG
Sebastian
einen effektiven Vergleich kann es gar nicht geben, jeder wird Stärken
und Schwächen haben, den ultimativen besten wird es nicht geben. Es
kann sein, du wählst Testbedingungen, in der ein Compiler besondere
Schwächen hat und besondere Vorzüge gar nicht zum Tragen kommen -
Ergebnis: Compiler ist Sch...
Stimmt aber gar nicht, mit anderen Testbedingungen hätte es ganz anders
ausgesehen. Ausserdem sind Compiler immer Baustellen, welche mit jedem
feedback von den usern besser wird, kein Programmierer kann von Hause
aus optimale Algorithmen einbauen.
Bei mir stand die Wahl zwischen CodeVision und IAR, CodeVision hat mir
sehr zugesagt, letztendlich war auch der Preis ein Argument.
sagen wirs mal anders, wo liegen den die vor und nachteile von
bestimmten compilern, die bekommt man ja meist erst nach einiger zeit
und intensiver benutzung mit. Was mich zb. an GCC etwas stört bzw. was
es in meiner gunst sinken lässt ist die unübersichtlichkeit der
Biblioteken und dern handling, zum mal was basteln is es ja ok, aber
wenn man was ernsthaftes machen will muss man sich ja wenigstends auf
eine komponente verlassen können und nicht noch im compiler ständig
nach fehlern suchen.
Bei der Effizienz der Compiler geht es mir Hauptsächlich darum wie gut
sie zb. ein paar verschatelte Schleifen auflösen und eine Handvoll
signed Integer Operationen, hat schon mal jemand getestet wie groß da
die unterschiede zw. den Compilern sind?
nö, habe ich nicht, da wird der Unterschied auch nicht besonders groß
sein, das ist trivial.
Deutliche Unterschiede wird vielleicht bei komplizierten math.
Funktionen mit float-Variablen geben, da könnte ich mir schon
vorstellen, dass es da ein paar 100 Takte Unterschied gibt, die
vielleicht bei der nächsten Funktion wieder wettgemacht werden. Wenns
aber so eng wird, dass das einem Design den Garaus macht, hat von
Anfang an zu eng (oder gar nicht) geplant.
Codegröße und Laufzeit kann man auch selbst stark beeinflussen, da
gibts einmal die Compileroptionen und zum anderen die eigene
Programmierweise.
@Andreas
ich finde zwar diesen Open Source gedamken toll, aber meines erachtens
ist der GCC für mich nicht übersichtlich genug, desweiteren treten
zwischen mit verschiedenen Versionen von Compilierten inkopatiblitäten
und die seltsammsten Fehler auf, die werden zwar dann nach und nach
ergründet, aber das ist dann auch kein Trost wenn man schnell ein
Ergebniss abliefern muss.
Ich werde mir jetzt mal selbst ein Bild davon machen inwiefern die
3Compiler meinen Anforderungen gerecht werden.
Von Inkompatiblitäten ist mir nichts bekannt. Die Funktionen inp(),
outp() und noch ein paar andere wurden für veraltet erklärt, ein paar
.h-Dateien wurden umbenannt, aber trotzdem kompilieren meine alten
Programme noch (zwar mit Warnungen, aber sie kompilieren). Mag sein
dass es beim Umstieg von gcc-2.95 auf 3.0 Probleme gab, aber vor 3.0
war der AVR-GCC sowieso nicht viel mehr als beta. Und leider haben
viele die uralten Windows-Versionen von http://8bit.at/avr/ und
avrfreaks.net noch lange weiterverwendet.
Im Moment ist der Compiler jedenfalls sehr gut benutzbar, die Libraries
sind ausgereift, und der Support ist super. Allerdings haben viele
Windows-User nach wie vor Probleme. Was für einen Unixer
selbstverständlich ist, kann für einen Windows-User völlig
unverständlich sein...
Da muss ich Dir Recht geben. Ich habe zwar erst vor ca. 2 Monaten mit
dem AVRGCC angefangen (Version 3.3), bin aber sehr zufrieden damit. Die
Dokumentation ist sehr übersichtlich und der erzeugte Code ist
erstaunlich effizient. Besonders begeistert mich die Mathelibrary, mit
der man auch höhere mathematische Funktionen problemlos implementieren
kann. Ich habe die AVR´s bisher wegen der üblichen Vorurteile auch nur
mit Assembler programmiert, werde das aber in Zukunft nur noch in
Ausnahmefällen tun. Die anderen Compiler kenne ich (noch) nicht.
Gruß Andreas
Vorab:
Ich würde Dir den AVRGCC nahelegen; da bekommst Du hier die beste
Unterstützung.
Da Du schon Assembler programmiert hast, sind die beiden anderen
Compiler nicht so interesant für Dich. Mit denen kann man aber gut
lernen (wie man es nicht macht).
Z.B.: long i; for(i=0;i<70000;i++);
Ein Compiler zeigt Dir ganz genau wie es geht:
Unterprogramm aufrufen, um i mit 0 zu laden
Schleife:
{
Unterprogramm aufrufen, um 70000 zu laden
Unterprogramm aufrufen, um Vergleich durchzuführen
Unterprogramm aufrufen, um i zu inkrementieren
}
Das braucht dann so seine 100 Byte und viel, viel Zeit.
Der andere Compiler zeigt Dir das Gegenteil:
Bei jeder Zuweisung long -> float wird hier 'schneller' Inline-Code
erzeugt. Jedesmal. Ein Unterprogramm würde ja den Lerneffekt
verhindern.
Einer der Compiler optimiert den erzeugten Code am Ende noch einmal.
Nur, wenn man einen µP mit 8K Flash angegeben hat und vor der
Optimierung 8,1K generiert wurden, gibt es keine Optimierung, sondern
Fehler.
Einer schafft bei float Berechnungen nur fünf gültige Stellen: mager.
Persönlich verwende ich den, den crazy horse nicht genommen hat. Der
optimiert teilweise so gut, daß selbst relevante Anweisungen
verschwinden. Aber nicht sofort, sondern erst wenn die Routine
erfolgreich getestet wurde und das Programm anschließend weiter
wächst.
Fazit: s.o. und Du kommst nicht umhin, Dich mit dem Compiler Deiner
Wahl intensiv auseinanderzusetzen, vor und nach der Anschaffung.
Mit so einem "Programm" Compiler vergleichen zu wollen, ist völlig
sinnlos, eine leere for-Schleife hat doch keinerlei Funktion.
Nur eine Sache die mir aufgefallen ist:
000077 5fef SUBI R30,LOW(-0x1)
000078 4fff SBCI R31,HIGH(-0x1)
Der GCC macht stattdessen einfach "adiw R30, 1".
Mit welchem Compiler ich welches Verhalten hatte (s.o.) weiß ich nicht
mehr. Ich war 'bedient' und hatte beide wieder von der Platte
entfernt.
So sieht das bei mir aus, wobei ich eine while-Schleife nehmen mußte,
um ein Inkrementieren zu erzwingen. Bei for wird optimiert, indem i mit
dem Endwert geladen und bis 0 gezählt wird. Da ich die Schleife in ein
ATmega-Programm gesteckt habe, werden die MOVW eingesetzt.
Nun gut, beim AVR wird man keine char feld[10000] löschen wollen
(können). Aber eine langsame Schleife wird auch nicht schneller, wenn
sie mit Inhalt gefüllt wird.
946 void verz()
947 {
948 long i=0;
\ verz:
\ 00000000 E040 LDI R20,0
\ 00000002 E050 LDI R21,0
\ 00000004 E060 LDI R22,0
\ 00000006 E070 LDI R23,0
949 while(i++ < 70000);
\ ??verz_0:
\ 00000008 018A MOVW R17 : R16,R21 : R20
\ 0000000A 019B MOVW R19 : R18,R23 : R22
\ 0000000C 5F4F SUBI R20,255
\ 0000000E 4F5F SBCI R21,255
\ 00000010 4F6F SBCI R22,255
\ 00000012 4F7F SBCI R23,255
\ 00000014 3700 CPI R16,112
\ 00000016 4111 SBCI R17,17
\ 00000018 4021 SBCI R18,1
\ 0000001A 4030 SBCI R19,0
\ 0000001C F3AC BRLT ??verz_0
950 }
\ 0000001E 9508 RET
Wenn Ihr Lust habt, ein reales Programm zu vergleichen, hier eine
Vorgabe. http://www.mino-elektronik.de/fmeter/fm_software.htm
Wenn alles gut geht, läuft es auf einem 2313.
Da ich noch einen 'alten' Compiler wiedergefunden hatte (ImageC), habe
ich in ein Demoprogramm '8515intr' die besagte Schleife eingefügt.
Das Listing besser als Anlage. Ob man auf min. Code oder max. Speed
einstellt ändert nichts an der prinzipiellen Vorgehensweise. Soll jeder
für sich bewerten, ob die Codeerzeugung in seinem Sinne und
empfehlenswert ist.
Wie schon gesagt, ich finde so eine leere Schleife völlig ungeeignet für
Compilervergleiche. Manche Compiler werden z.B. erkennen dass in der
Schleife nichts passiert und sie einfach durch i=70000 ersetzen,
teilweise "aufrollen" (so ähnlich macht es der GCC) usw.
Andreas:
Hast Du vielleicht mein o.g. Programm durch AVRGCC 'mal compiliert ?
Das würde mich interessieren und doch auch mehr zeigen.
Natürlich ist eine Bewertung eines Compilats eine andere Sache, aber
irgendwo muß man doch versuchen, eine Bewertung anzusetzen. Oder ist
und bleibt das ein Tabu ?
Hi
habs eben mal probiert.
Nachdem ich den AVRGCC dann davon überzeugen konnte das Ding mit
diversen Warnings zu kompilieren warf er eine Codegröße von etwa 5700
Byte aus. War aber bei der Verwendung von float als Datentyp zu
erwarten. Da ist der AVRGCC AFAIK noch nicht besonders gut optimiert.
Außerdem hab ich das flash als Speicherort einfach entfernt und die
Variablen somit ins RAM verlagert. Im Anhang mal die Datei die mit ein
paar warnings vom GCC compiliert wird.
Matthias
Danke Matthias, obwohl die Größe etwas heftig ist. In wager Erinnerung
ist mir bei ImageC so ca. 2,5K, bei CodeV etwas weniger.
GCC habe ich sonst bei 68K und H8S eingesetzt; dort sieht der Code sehr
gut aus und ist geschickt optimiert. Die 8-Bitter sind eben etwas
anders zu handhaben als die dickeren µPs.
@Michael: mit diesem Code misst man wohl weniger die Optimierung des
Compilers als die Größe der Float-Bibliothek. Ungelinkt braucht das
Programm 1214 Byte.
@Matthias: leider fehlt zum Kompilieren die code.h.
Wo wir gerade so schön am Compiler-Vergleichen sind: im Anhang ist das
nächste Testobjekt. Bitte nur kompilieren, nicht linken (Option -c beim
gcc).
Hi
was zu erwarten war. Sind bei mir auch genau 1304 Byte. (aktuelle
WINAVR) Merkwürdigerweise braucht der 3.3er GCC den ich gestern unter
Linux compiliert hab ein paar Byte mehr.
Matthias
Hi
mit dem aktuellen Snapshot (gcc 3.3 vom 21.7.2003) sind es ganau 4 Byte
mehr als mit dem WINAVR. Kann das evtl. an einer anderen avrlibc
liegen?
avr-libc-20030512cvs.tar.gz
Matthias
So, Matthias zuerst.
Die BIT0_POS +++ habe ich einfach nur nach Gutdünken definiert.
eeprom_read + eeprom_write habe ich nur als external deklariert und
nicht eingefügt und nichts gelinkt. Dafür alles auf max. speed für
einen 2313 eingestellt.
Ohne zu linken erzeugt meine Quelle fm.c bei mir 1022 Byte.
Ich finde es angenehm und würde es weiter begrüßen, die vorliegenden
Beispiele ohne Hickhack und Geschrei zu behandeln. Es ist viel Aufwand,
wenn sich jeder immer alle Demos für eigene Versuche installieren muß.
Daß AVRGCC soviel 'fließenden' Code dazulinkt, ist merkwürdig. Es
werden nur FMUL + FDIV gebraucht. Offensichtlich ist die Bibliothek zu
'grob' angelegt. Bei dickeren ATmegas ist das in der Regel belanglos.
Andreas:
Anbei das Ergebnis zu dbg.c. Die erweiterten Befehle zu ATmega sind
nicht aktiviert; wenn doch, dann werden es zwei Byte weniger (MOVW bei
gcd_3:)
Vielleicht hat Crazy Horse noch etwas compiliert.