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?
Was meinst du mit "Unübersichtlichkeit der Bibliotheken", und von welchen Fehlern sprichst du?
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.
was willst du damit eigentlich sagen, soll der Compiler so arbeiten, dass man das Listfile noch versteht (wegen Lerneffekt und so) oder soll effektiver Code erzeugt werden? Habe dein obiges Schleifenbeispiel mal mit CodeVision compiliert: ; 84 for(i=0;i<70000;i++); 000056 27ee CLR R30 000057 93e0 0084 STS _i,R30 000059 93e0 0085 STS _i+1,R30 00005b 93e0 0086 STS _i+2,R30 00005d 93e0 0087 STS _i+3,R30 _0x2D: 00005f 91a0 0084 LDS R26,_i 000061 91b0 0085 LDS R27,_i+1 000063 9180 0086 LDS R24,_i+2 000065 9190 0087 LDS R25,_i+3 000067 + __CPD2N 0x11170 000067 37a0 CPI R26,LOW(0x11170) 000068 e1e1 LDI R30,HIGH(0x11170) 000069 07be CPC R27,R30 00006a e0e1 LDI R30,BYTE3(0x11170) 00006b 078e CPC R24,R30 00006c e0e0 LDI R30,BYTE4(0x11170) 00006d 079e CPC R25,R30 .ENDM 00006e f4ac BRGE _0x2E 00006f 91e0 0084 LDS R30,_i 000071 91f0 0085 LDS R31,_i+1 000073 9160 0086 LDS R22,_i+2 000075 9170 0087 LDS R23,_i+3 000077 + __SUBD1N -1 000077 5fef SUBI R30,LOW(-0x1) 000078 4fff SBCI R31,HIGH(-0x1) 000079 4f6f SBCI R22,BYTE3(-0x1) 00007a 4f7f SBCI R23,BYTE4(-0x1) .ENDM 00007b 93e0 0084 STS _i,R30 00007d 93f0 0085 STS _i+1,R31 00007f 9360 0086 STS _i+2,R22 000081 9370 0087 STS _i+3,R23 000083 cfdb RJMP _0x2D sehe da nicht viel weitere Optimierungsmöglichkeit, allenfalls die Schleifenvariable direkt in Registern statt im SRAM abzulegen, dass macht CodeVision mit long-Variablen prinzipiell nicht, selbst wenn noch freie Register da wären. Wie löst IAR das Beispiel?
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.
Hi könntest du mal das angehängte Programm (auch eine Art Frequenzzähler) durch den IAR jagen? Matthias
@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).
Natürlich (wie komm ich nur auf "code")? Hier ergibt das Programm 1304 Byte.
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
Hast du den aktuellen Snapshop runtergeladen oder den 3.3 Release? Meinen habe ich heute aus der aktuellsten Version kompiliert.
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.
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.