Forum: Compiler & IDEs AVR-GCC und kleine Controller


von Sebastian Fahrner (Gast)


Lesenswert?

Hallo,

gestern wollte ich ein kleines Programmchen für einen 2313 (2kB Flash, 
128B RAM) mit AVR-GCC schreiben. Obwohl mein Programmchen wirklich klein 
war (nur ein Modul, ~500 Zeilen mit defines und Kommentaren), kam die 
Fehlermeldung, daß sowohl Flash als auch RAM voll sind.

Ist das normal??
Kann man dem Compiler vielleicht irgendwie sagen, er soll auf 
"Speicherplatz" optimieren??

Danke,

Sebastian

von Peter D. (peda)


Lesenswert?

Ich habe ähnliches vor:

Um die Eignung der AVR für meine Anwendungen im industriellen Umfeld zu 
testen, will ich einen AT89C2051 durch einen AT90S2313 ersetzen, d.h. 
ohne eine neue Platine machen zu müssen.

Das 2051-Programm ist in C geschrieben und belegt etwa 1,6kB des Flash. 
Es sind nur wenige Zeilen, aber es benutzt float Variablen.


Meine Frage:

Hat schon mal jemand float auf nem 2313 verwendet oder ist das 
illusorisch ?


Peter

von Joerg Wunsch (Gast)


Lesenswert?

@Sebastian:

Welche Features benutzt Du denn alles so?

Ich habe mal ein kleines meiner Projekte herausgewühlt,
das vom Codeumfang vergleichbar ist.  Das kommt für 2 x
je ca. 400 Zeilen Quellcode auf 1 KB Flash-Nutzung.
Allerdings hängt das von den benutzten Bibliotheksfunktionen
etc. pp. mit ab.  Wenn Du printf() benutzt, genügt schon
eine einzige Zeile Programmcode, daß alles nicht mehr in
einen AT90S2313 hineinpaßt. ;-)

Die RAM-Nutzung hast Du natürlich komplett mit Deinen
Variablen selbst in der Hand.  Denk dran, daß Du auch
RAM für den Stack brauchst.

@Peter:

float auf dem 2313 wird sicher knapp.  Solange Du nur
addieren und subtrahieren willst, geht es vielleicht
gerade noch so, Multiplikation oder gar Division ziehen
aber vermutlich schon so viel mit rein, daß das nicht
mehr praktikabel ist.  Und Ein-/Ausgaben wirst Du ja
vielleicht auch noch machen wollen...

Ich habe Gleitkomma erfolgreich auf einem AT90S8535
benutzt, allerdings wäre für printf() kein Platz mehr
gewesen (hatte ich damals sowieso noch nicht), und zusammen
mit bißchen Debug-Code und sowas habe ich am Ende den
Flash dieses Teils auch vollbekommen (fast jedenfalls).

Vielleicht wäre ja scaled integer eher was für Dich?

von Michael (Gast)


Lesenswert?

@Peter:

Vielleicht hast Du schon mein Frequenzmeßgerät gesehen 
www.mino-elektronik.de/fmeter/fmeterx.htm. Hier wird float auf Basis 
eines IAR-Compilers ICCA90 (V1.x) verwendet. Die Codegröße für fadd, 
fsub, fmul, fdiv, die Konvertierungen float2long, long2float, ... und 
die Rundungen beträgt unter 900Byte. Verglichen mit ImageCraft-AVR, 
GCCAVR und Codevision-AVR ist das sehr kompakt. Printf ist allerdings 
bei keinem der Compiler anzuraten, da auch viele Routinen gelinkt 
werden, die nicht gebraucht werden.
Ohne Geld auszugeben, kann man eine Demo von IAR bekommen, eine c-Quelle 
mit float schreiben und 'debuggen'; so bekommt man den versteckten Code 
der Libs zu sehen und könnte ihn auch abtippen. Zur weiteren Anwendung 
gibt es einen kostenlosen AA90 Assembler (www.atmel.com). Bei mir (s.o.) 
gibt es auch ein Beispielprogramm 'fm.c', welches auch float benötigt 
und trotz reiner C-Quelle in den 2313 paßt.

Ich hatte seinerzeit meine ersten Versuche mit dem 2313 gemacht, der 
genau wie bei Dir den 2051 ersetzen sollte. Der Code für einen 
Tastatudekoder + LCD-Treiber + ser.Multiprozessorschnittstelle auf dem 
2051 war mit 2k gerade passend, für den 2313 wollte der C-Compiler 
zunächst 3k erzeugen. Durch Optimierung und teilweise Codierung in 
Assembler (wie auch schon beim 2051) passte der Code dann auch in den 
2313. So macht man seine Erfahrungen. Die Vorteile waren für mich das 
interne EEPROM und die Programmierung verschiedener Versionen auf der 
Leiterplatte. Die serielle Ausgabe (über 4094) aufs LC-Display wurde so 
schnell, daß bei 62,5kBd keine Warteschleifen mehr eingefügt werden 
mussten.

Ich will hier keine Werbung machen, aber der aktuelle IAR ICCAVR erzeugt 
sehr guten Code und nutzt bei den ATmega auch die neuen Befehle; das 
Teil kostet aber auch richtig Knete! Ich rufe die Compiler aus der 
Kommandozeile auf, was für mich sehr wichtig ist.

Ich kann Dir anbieten, Deine Quelle 'mal durch den Compiler zu nudeln 
und Dir den Output schicken.

Michael

von Sebastian Fahrner (Gast)


Lesenswert?

Mein Programmchen benutzt gar keine C-Library. Auch keine floats oder 
solche Sachen. Allerdings eine größere Schachtelungstiefe von 
if/switch/for etc.
Die Variablen, die ich benutze, machen zusammen 20 bis 30 Bytes.

Ich habe den GCC in Verdacht, ziemlich resourcenhungrigen Code zu 
erzeugen?!

Grüße,

Sebastian

von Peter D. (peda)


Lesenswert?

@Michael,

900 Byte klingt gut, beim 2051 sinds 979 Byte.

Vielleicht hat doch noch jemand dazu Vergleichszahlen für den AVRGCC ?

printf() nehme ich nicht, da ich ja 7-Segment-Kode brauche und kein 
ASCII.


Dein Frequenzmesser sieht interessant aus, ähnelt vom Meßprinzip her 
meinem mit dem 2051 aufgebautem.

Eine Frage, ist das Programm dazu nun in C (wegen float) oder in 
Assembler ?

Das mit den 0,0025 Hz ist aber ein Druckfehler, das wären ja 7 Minuten 
Meßzeit.

Meiner geht von 0,5Hz ... 125MHz, die Auflösung ist 4 Digits bzw. 
0,001Hz, die Meßzeit beträgt 0,5s ab >2Hz und erhöht sich bis auf 2s bei 
0,5Hz.

Als Vorverstärker bzw. Trigger nehme ich den AD8009 und den LT1720.

Bei Interesse kann ich mehr dazu auf meine Webseite stellen.


Peter

von Michael (Gast)


Lesenswert?

@Peter:

'fm.c' ist reine C-Quelle; Du kannst Dir den .hex-Code ja 'mal auf einen 
2313 programmieren.

Bei fmeter.htm sind 0,0025Hz kein Druckfehler. Bei 1Hz Eingangsfrequenz 
bekommt man 7-stellige Ergebnisse: jede Sekunde ein neues! Ich gleiche 
damit z.B. PCF8583 Uhren ab. Der Vorteiler für 50MHz wird automatisch 
selektiert.
Hier habe ich die Steuerung und Auswertung in C, die Interruptroutinen 
und Optimierungen (interne Registerverwendung) in Assembler gemacht. 
Ebenso ist der startup abgemagert - einige Konstanten liegen im EEPROM.

Michael

von Notker (Gast)


Lesenswert?

> Ich will hier keine Werbung machen, aber der aktuelle IAR ICCAVR erzeugt sehr 
guten Code ...

Ich will ja hier keine Werbung machen, aber da schmeisst mal wieder 
jemand Äpfel und Tomaten durcheinander! Was hat denn die Firma IAR 
Systems mit der Firma Imagecraft zu tun?? ICCAVR stammt von der Firma 
Imagecraft und nicht von IAR, wie man am Namen schon unschwer erkennen 
kann (Imagecraft C-Compiler). Und zwischen den Produkten von Imagecraft 
und denen von IAR Systems liegen Welten.

Vielleicht entscheidest du dich erst mal, wofür du hier 
(Schleich-)werbung machen willst.


> Ich habe den GCC in Verdacht, ziemlich resourcenhungrigen Code zu erzeugen?!

Auch mal wieder so eine Fehlannahme! Ich würde erst mal schauen welches 
Flieskommaformat bzw. welche Präzision die Routinen haben, bevor ich 
anfange die erzeugte Codegrösse zu vergleichen. Wenn ich die Präzision 
und den Zahlenbereich einer Fliesskommavariablen entsprechend reduziere, 
bekomme ich naturgemäss auch kompaktere Routinen und damit kompakteren 
Code (siehe z.B. CodeVision & Konsorten). Wenn man allerdings volle IEEE 
754-Präzision haben möchte (float = 4 Byte, double = 8 Byte und long 
double = 10 Byte), so kostet das natürlich entsprechenden Platz. Leider 
schreibt der ANSI-Standard hier nichts vor, so dass Hersteller 
kommerzielle Compiler mit verkrüppelten Fliesskommaroutinen trotzdem 
noch dieses Schildchen auf den Karton pappen dürfen, was mir persönlich 
sehr missfällt.


Notker

von Joerg Wunsch (Gast)


Lesenswert?

Der avr-gcc unterstützt ohnehin nur 4-Byte floats, double
ist identisch zu diesem.  Viel mehr erscheint mir persönlich
auch kaum sinnvoll; zwei 4-Byte floats als Argumente einer
Funktion belegen bereits den kompletten Satz an scratch
registers, die definiert sind, also ab 3 Parametern müßte
man schon auf den Stack.

Anyway, wichtig beim avr-gcc ist, welche Optimierungsoptionen
benutzt werden.  Wer gedankenlos -O3 schreibt (oder gar
sinnloserweise noch größere Zahlen, weil er das Manual nicht
gelesen hat und nicht weiß, daß es gar nichts höheres gibt ;-),
der wird bestraft.  -O3 wird ja vielleicht noch ein bissel
schneller als die kleineren Zahlen, aber kleiner wird es
absolut nicht, sondern vielmehr recht aufgebläht.  Am kleinsten
fallen -Os (wie der Name sagt ;-) und -O1 aus, und sie sind
bestenfalls nur geringfügig langsamer als die Optimierungsstufen
mit der größeren Zahl (d. h. weniger als 10 % selbst bei
rechenkritischen Operationen).

von Reiner Patommel (Gast)


Lesenswert?

Vielleicht ist meine Frage ja ganz dumm ...:
Sind im Makefile die linker flags richtig ?
#linker flags
  LDFLAGS = -Wl,-Map=$(TRG).map,--cref -lm

Das Fehlen des -lm switches erzeugt Fehlermeldungen über volles flash.

von Michael (Gast)


Lesenswert?

@notker:

'iccavr.exe' ist auch von IAR. Wie man am Namen unschwer erkennen kann 
kommt ICC von Iar-C-Compiler. Die Version davor hieß 'icca90.exe'. 
Vielleicht liest Du die Sätze 'mal komplett, ohne gleich loszuwettern.

Ich habe noch einmal nachgesehen: float-basisroutinen bei IAR brauchen 
638 Byte (gleicher Wert bei zwei verschiedenen Projekten). Internes 
Format 4 Byte, wie nicht anders zu erwarten.

von Notker (Gast)


Lesenswert?

ftp://ftp.imagecraft.com/pub/pub/iccavrdem.exe

Also der ist doch wohl zweifelsohne von Imagecraft, oder? (das "dem" 
steht übrigens dafür, dass es die Demoversion ist, die Vollversion 
heisst iccavr.exe.

Ich habe den Satz schon richtig gelesen, danke für den Hinweis!

Notker

von Notker (Gast)


Lesenswert?

> Der avr-gcc unterstützt ohnehin nur 4-Byte floats, double
ist identisch zu diesem.

Das halte ich aber für ein Gerücht! Aber ein kurzes Debugging mit dem 
AVR-Studio an einem Beispielprogramm wird dies schnell klären.

> Wer gedankenlos -O3 schreibt (oder gar
sinnloserweise noch größere Zahlen, weil er das Manual nicht
gelesen hat und nicht weiß, daß es gar nichts höheres gibt ;-),
der wird bestraft.

Womit denn? Mit Freiheitsstrafe nicht unter 2 Jahren? ;-)

Naja, beim "normalen!" gcc gibt es hier schon höhere Zahlen.


Notker

von Joerg Wunsch (Gast)


Lesenswert?

> Das halte ich aber für ein Gerücht!

Kannst Du gern.  Um wieviel möchtest Du wetten?

RTFDoc hilft hier übrigens auch, es ist sehr eindeutig
beschrieben, daß er nur 32-bit floats kennt.  Aber ich
gebe zu, wetten wäre unfair, ich habe Heimvorteil.

> Naja, beim "normalen!" gcc gibt es hier schon höhere
> Zahlen.

Woher hast Du denn diese Weisheit?  Aus dem Manual oder
dem Sourcecode des gcc bestimmt nicht.  Vielleicht aus
abergläubischen Linux-Makefiles, die von Unwissenden
geschrieben worden sind, die sich einbilden, das bloße
Aufschreiben von -O99 würde die gcc-Geister beschwören,
besseren Code zu produzieren...  gcc selbst ignoriert es
geflissentlich und nimmt einfach stattdessen mal -O3 an,
bis die Leute ja dann vielleicht doch noch RTFM'ed haben...

von Notker (Gast)


Lesenswert?

>Woher hast Du denn diese Weisheit? Aus dem Manual oder
>dem Sourcecode des gcc bestimmt nicht. Vielleicht aus
>abergläubischen Linux-Makefiles, die von Unwissenden
>geschrieben worden sind, die sich einbilden, das bloße
>Aufschreiben von -O99 würde die gcc-Geister beschwören,
>besseren Code zu produzieren...

Sag mal, du trägst hier aber ganz schön dick auf!

Also das, was hier drin steht ist also falsch?

http://www.fokus.gmd.de/linux/HOWTO/pdf/Assembly-HOWTO.pdf

Ich könnte ja jetzt noch in den Sourcen des gcc solange rumsuchen, bis 
ich etwas gefunden habe, aber ehrlich gesagt, ich finde es langsam etwas 
müssig, jede fragwürdige Behauptung, die hier gemacht wird, genauer zu 
untersuchen. Wer es also genau wissen will, soll selbst nachsehen.

Notker

von Sebastian Fahrner (Gast)


Lesenswert?

Wasichnochsagenwollte:

Mit WinAVR hab ich jetzt mein Programmchen problemlos in den A2313 
bekommen. Scheint wirklich ein Fortschritt gegenüber V3.0.2 zu sein!!

Grüße,

Sebastian

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

man gcc, da steht's weiß auf Schwarz: -O, -O0, -O1, -O2 und -O3. Das 
Assembler-HOWTO ist also offensichtlich falsch.

von Joerg Wunsch (Gast)


Lesenswert?

@Notker:

> Sag mal, du trägst hier aber ganz schön dick auf!

Zumindest habe ich die Doku gelesen. ;-)  Diese nennt
eindeutig nur -O0 (ist identisch zum Weglassen von -O),
-O alias -O1, -O2 und -O3.

> Also das, was hier drin steht ist also falsch?

Ja, zumindest für einen unverpfuschten gcc.  Allerdings
ist innerhalb des gcc die Variable "optimize" global,
und diese bekommt in der Tat die Zahl nach -O zugewiesen,
so daß ein einzelner Codegenerator von anderen Levels
Gebrauch machen könnte.  Der ungepatchte gcc benutzt
aber als höchsten Vergleich "optimize >= 2", und genau
so ist es auch dokumentiert.  UTSL.

von Joerg Wunsch (Gast)


Lesenswert?

> Zumindest habe ich die Doku gelesen. ;-) Diese nennt
> eindeutig nur -O0 (ist identisch zum Weglassen von -O),
> -O alias -O1, -O2 und -O3.

Sorry, -Os habe ich unterschlagen.

von Notker (Gast)


Lesenswert?

Also hier mal ein Codeauszug aus der Source des gcc 3.2:

------------------schnipp--------------------------------
      else if (argv[i][0] == '-' && argv[i][1] == 'O')
        {
          /* Handle -Os, -O2, -O3, -O69, ...  */ 
<--------!!!!
          char *p = &argv[i][2];

          if ((p[0] == 's') && (p[1] == 0))
            {
              optimize_size = 1;

              /* Optimizing for size forces optimize to be 2.  */
              optimize = 2;
            }
------------------schnapp-----------------------------------

Also irgendwie scheinen dort ja doch Levels höher als 3 erkannt und 
ausgewertet zu werden, oder habe ich heute abend etwas an den Augen??? 
Level -O6 habe ich im Unix-Bereich schon des öfteren in Sourcen 
namhafter und renommierter GPL-Software gesehen.

Notker

von Joerg Wunsch (Gast)


Lesenswert?

Wenn Du bis dorthin vorgedrungen bist, dann untersuche
einfach noch, an welchen Stellen die Variable
"optimzize" auch wirklich benutzt wird.  Du wirst
zu Deinem Erstaunen feststellen, dass der hoechste
Vergleich, der irgendwo auftritt, optimize >= 2
ist -- was exakt der Manpage entspricht.

Was anderes habe ich auch nicht geschrieben: die
Zahl nach -O wird zwar noch geparst, aber alles
ab -O3 wird identisch behandelt.

Ob mehr oder weniger namhafte ,,Experten'' im Glauben
an den Gott der Optimierung dann -O6 schreiben, ist
mir egal.  Sie werden jedenfalls damit nicht mehr
als mit -O3 erreichen, und um auf den Anfang
zurueckzukommen, fuer die meisten AVR-Applikationen
kann -O3 zu einer massiven Platzverschwendung bei
bestenfalls marginaler Verbesserung der Laufzeit
fuehren.  Siehe Doku, meine Mini-Benchmark-Ergebnisse
habe ich dokumentiert.

von Notker (Gast)


Lesenswert?

> Du wirst zu Deinem Erstaunen feststellen, dass der hoechste
> Vergleich, der irgendwo auftritt, optimize >= 2
> ist -- was exakt der Manpage entspricht.

Nun, dann schauen wir doch mal etwas weiter unten (toplev.c) ...

------------------------schnipp-------------------------------
        flag_delete_null_pointer_checks = 1;
      flag_reorder_blocks = 1;
    }

  if (optimize >= 3)           <---------------!!!
    {
      flag_inline_functions = 1;
      flag_rename_registers = 1;
-----------------------schnapp-------------------------------
Nun, ich denke, dass DU besser mal einen Blick vorher hier 
hineingeworfen hättest. Mein lieber Jörg Wunsch, so langsam wird die 
Sache langweilig. Ich glaube, du suchst dir besser ein anderes Forum mit 
leichtgläubigerem Publikum aus, wo du dein "Expertenwissen" zum Besten 
geben kannst. Die Behauptung hier ist wohl auch mal wieder heisse Luft.

Notker

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Na gut, dann halt >=3, was Jörg wahrscheinlich auch gemeint hat ("...was 
exakt der Manpage entspricht"), aber größere Werte als 3 machen beim GCC 
definitiv keinen Unterschied.

BTW: Er ist auf dem Gebiet wohl der letzte, in dessen Zusammenhang es 
angebracht ist "Expertenwissen" in Anführungszeichen zu schreiben...

von Notker (Gast)


Lesenswert?

> BTW: Er ist auf dem Gebiet wohl der letzte, in dessen Zusammenhang es 
angebracht ist "Expertenwissen" in Anführungszeichen zu schreiben...

Mag ja alles sein, allerdings finde ich seine Art wenig souverän. Als 
tatsächlicher Experte sollte man schon seine Hausaufgaben gemacht haben 
und ein etwas diplomatischerer Umgang mit anderen Menschen wäre kein 
Luxus.


Notker

von Joerg Wunsch (Gast)


Lesenswert?

Nun, die Hausaufgaben habe ich gemacht.  Siehe Andreas'
Hinweis, das war ein simpler Schreibfehler -- der Effekt
ist exakt der, den ich beschrieben habe: -O3 ist der
höchste ,,aus der Dose raus'' unterstützte Level.  Daß
man dafür natürlich entweder >= 3 oder > 2 schreiben muß,
ja klar.  Ich hatte meine Hausaufgabe schon vor einer
Woche gemacht und daher aus dem Gedächtnis zitiert.

Ich wehre mich vor allem gegen diese ,,weil es im HOWTO xyz
steht, muß es richtig sein'' Mentalität.  Alles spricht
dagegen, daß es -O levels > 3 wirklich gibt (die Manpages,
der Sourcecode), aber der Glaube an den Gott der Optimierung
wirkt stärker...  Dabei ist in der Doku zum gcc wirklich
recht detailliert beschrieben, welche Stufe welche Optimierungen
einschließt.  Im Gegensatz zu irgendeinem Howto stammt diese
aber von den Autoren/Maintainern.

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.