Forum: Compiler & IDEs AVR-GCC warum Code so groß?


von AtmelFreak (Gast)


Lesenswert?

Hallo Gemeinde,

Mittlerweile habe ich eine Menge Projekte unter FAST-AVR geschrieben und
sie haben immer beeindruckend gut funktioniert. Zuletzt jetzt das
Projekt mit 2 RFM 12ern. Es funktionierte natürlich nicht sie mit
Hard-SPI zum laufen zu zwingen. Also drangemacht an AVR-GCC und zum
testen Benedikts Code (danke Benedikt für deine Pionierleistung ;-) )
geladen, geändert und auf meinem Tiny2313 getoastet und......... siehe
da es funzt.
Jetzt aber mal meine Frage: Mein Code in FAST-AVR entspricht vom Umfang
der Funktionen derer in Benidikts Code in C. Nach dem Compilieren habe
ich aber bei FAST-AVR nur ca 56% RAM beschrieben während mir AVR-GCC
161% sagt.
Trotz allem habe ich ihn in meinen Chip bekommen. Senden-Empfangen funzt
aber die anschließende bearbeitung der Daten funzt nur ab und an.
Ausserdem habe ich auch festgestellt das manchmal nach dem Einschalten
der Chip langsamer läuft, Da ich am Anfang 2 LEDs blinken
lasse.(interner 4 MHz-Takt ist eingefused)

Wäre prima wenn mir jemand sagen könnte warum mir AVR-GCC eine
Speicherauslastung von rd160% angibt. Achja -os ist eingestellt. Bei
anderen einstellungen verändert sich allerdings nicht viel.
Vielen Dank schonmal vorab

von Simon K. (simon) Benutzerseite


Lesenswert?

richtigen Chip eingestellt?

von Peter D. (peda)


Lesenswert?

AtmelFreak wrote:
> Jetzt aber mal meine Frage: Mein Code in FAST-AVR entspricht vom Umfang
> der Funktionen derer in Benidikts Code in C. Nach dem Compilieren habe
> ich aber bei FAST-AVR nur ca 56% RAM beschrieben während mir AVR-GCC
> 161% sagt.

Der GCC legt Konstanten als default in den SRAM. Man muß ihm erst 
speziell sagen, daß er sie in den Flash legen soll (Attribut progmem).


Peter

von AtmelFreak (Gast)


Lesenswert?

Danke Peter,
@Simon
ja der Chip ist in meinem Makefile korrekt angegeben.

@Peter
das kuriose ist das ich jetzt mal ein ganz kleinen Code geschrieben 
habe, welcher mir zum testen nur mal den gesamten PortB meines Tiny2313 
im Zeitrhytmus setzt und löscht. Da zeigt mir der Compiler schon 
2340Byte an und eine Speicherauslastung von 114% mit delay.h. Ohne 
delay.h sind es dann immerhin noch 112%. Ich frage mich ernsthaft woran 
das liegt. An Konstanten kann es nicht liegen. Meiner Ansicht nach liegt 
es eher an meinem Makefile. Kann das sein?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Optimierung aktiviert?
Zeit in delay ist keine Compilezeit-Konstante?
Kristallkugel, um den Code zu sehen?

von AtmelFreak (Gast)


Lesenswert?

Es kommt mir auch so vor als wenn diese Angabe um fast genau 100% zu 
hoch ist. ;-)

Leider habe ich nur Windoofs-Apps in C geproggt und musste mich da mit 
Speicherauslastungen nicht so auseinandersetzen. Das proggen von AVR in 
C ist ja nun doch massiv anders.#
Ich glaube ich habe den GCC noch nicht so richtig verstanden.

Danke euch für eure Hilfe

von Markus (Gast)


Lesenswert?

>Achja -os ist eingestellt.

-Os sollte es sein.

von AtmelFreak (Gast)


Lesenswert?

Hallo Markus
ja es ist auch -Os eingestellt
ich nutze das Makefile Tool welches in der aktuellen Toolchain vorhanden 
ist.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Und was hat das jetzt mit der Code-Groesse zu tun? Offenbar garnichts.

von Peter D. (peda)


Lesenswert?

AtmelFreak wrote:
> das kuriose ist das ich jetzt mal ein ganz kleinen Code geschrieben
> habe, welcher mir zum testen nur mal den gesamten PortB meines Tiny2313
> im Zeitrhytmus setzt und löscht. Da zeigt mir der Compiler schon
> 2340Byte an und eine Speicherauslastung von 114% mit delay.h.

Dann zeig doch mal den kleinen Code (als Anhang!).

Wo es klemmt, sieht man am einfachsten an nem Beispiel.


Peter

von AtmelFreak (Gast)


Angehängte Dateien:

Lesenswert?

Hier mein kurzer Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
#define outport_b   DDRB
5
6
7
8
int main (void)
9
{
10
outport_b = 0xFF;
11
12
  while (1)
13
  {
14
    PORTB |= (1<<PB0) | (1<<PB1) |(1<<PB2) |(1<<PB3) |(1<<PB4) |(1<<PB5) |(1<<PB6) |(1<<PB7);
15
      for (unsigned char i=0; i<50; i++)
16
        for (unsigned char o=0; o< 256; o++);
17
    PORTB &= ~((1<<PB0) | (1<<PB1) |(1<<PB2) |(1<<PB3) |(1<<PB4) |(1<<PB5) |(1<<PB6) |(1<<PB7));
18
      for (unsigned char i=0; i<50; i++)
19
        for (unsigned char o=0; o< 256; o++);
20
      }
21
}

und im Anhang das Log vom Makefile

Ich weiß wirklich nicht was es sein kann aber über 2K für das bissl???

von Εrnst B. (ernst)


Lesenswert?

Also, bei mir optimiert der GCC da so gut wie alles weg, übrig bleibt 
eigentlich nur:

DDRB=0xFF;
PORTB;
PORTB = 0xFF;
1
  for (unsigned char o=0; o< 256; o++);
  ist eine Endlosschleife, alles danach schmeißt der Compiler weg.
Die Schleifen aussenrum sind egal, haben keinen Effekt, werden also auch 
rausoptimiert.

von Peter D. (peda)


Lesenswert?

Ernst Bachmann wrote:
> Also, bei mir optimiert der GCC da so gut wie alles weg, übrig bleibt
> eigentlich nur:
>
> PORTB = 0xFF;


Bei mir auch:
1
4.3.0
2
   text    data     bss     dec     hex
3
    104       0       0     104      68


Peter

von AtmelFreak (Gast)


Lesenswert?

*lach na super
Ich danke euch
aber das löst leider nicht mein Problem

Anscheinend mache ich was falsch nur weiss ich leider nicht was. 
Vieleicht nützt es etwas zur Rätzels Lösung wenn ich sage das ich 
Prog...Notepad nutze und von dort Makeall.
Wie compiliert Ihr das C-Prog?
Weshalb habe ich dann 2K Hex?
Ich verstehe das nicht.

von holger (Gast)


Lesenswert?

>Anscheinend mache ich was falsch nur weiss ich leider nicht was.
>Vieleicht nützt es etwas zur Rätzels Lösung wenn ich sage das ich
>Prog...Notepad nutze und von dort Makeall.

Poste dein komplettes Projekt?

von AtmelFreak (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Holger
Das ist mein komplettes Projekt. Nachdem, wie ich oben beschrieben habe, 
versucht habe die RFM zum laufen zu bewegen und das Programm in C so 
dermaßen groß war, habe ich mir gedacht ein kleines blödsinniges Prog zu 
schreiben um zu schauen was die Speicherauslastung sagt.
Und siehe da...bei den paar zeilen, die von anderen Compilern sogar noch 
getrashed werden, habe ich 2304Byte.

Vieleicht hilft es und habe mal das Makefile angehangen.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Du willst mir erzaehlen dass obiges Programm >1k SRAM belegt? Mit 
Sicherheit nicht.

von AtmelFreak (Gast)


Lesenswert?

ääääääääääähm ich habe den output von ProgrammersNotepad doch als 
Textfile mal angehangen. Was steht dort?
Size after:
AVR Memory Usage
----------------
Device: attiny2313

Program:    2304 bytes (112.5% Full)

und genau das ist es was ich nicht verstehe. Bei Ernst und Peter sind es 
grad mal 68h. Mehr dürfte es auch nicht sein. Ich habe es auf meinem PC 
und meinem Laptop compiliert und bei beiden das gleiche Ergebnis.
Ich bin wirklich ratlos.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was macht das hier im Linkeraufruf?
1
(...) -lprintf_min -Wl,-u,vfscanf -lscanf_min -lm

Ich kenne die verwendete Toolchain nicht, da ich sie nicht nutze, aber 
das da sagt mir, daß in irgendeiner Weise sowohl 
printf/scanf-Unterstützung als auch 
Floatingpoint-Arithmethikunterstützung in Form von libm.a gelinkt 
werden.

Könnte es sein, daß sich das auf die Codegröße auswirken könnte?

von 900ss (900ss)


Lesenswert?

Michael G. wrote:
> Du willst mir erzaehlen dass obiges Programm >1k SRAM belegt? Mit
> Sicherheit nicht.

Hör doch einfach mal auf rumzupalabern. Oben hast du auch schon einen 
sehr hilfreichen Kommentar abgelassen. Entweder Klappe halten oder mach 
dich daran, das zu untersuchen.
Du erinnerst mich immer daran:
Beitrag "Ausblenden von Trollen bzw. unangemeldeten Benutzern."

Also ich habe mir den lss File mal angesehen nachdem ich Compiler und 
Linker u.s.w. laufen lassen habe so wie im Make output von AtmelFreak 
oben angegeben.
Da wird das ganze printf-Geraffel aus der Lib dazugelinkt. Deshalb ist 
das Zeugs so groß denke ich. Ich verstehe allerdings nicht ganz genau 
warum. Die Linkeroptionen sind mir noch etwas suspekt. Ich dachte, das 
Zeugs wird nur gelinkt, wenn es auch aufgerufen wird.

Aber da muß irgendwo des Rätsels Lösung liegen. Warum er das Zeugs 
dazulinkt das möge wer anders erklären :-)

von AtmelFreak (Gast)


Lesenswert?

Vielen Dank!!
Ich habe mal die betreffenden Zeilen auskommentiert und siehe da
ich habe nur noch 104Byte 5,1%full
Das sieht mir eher nach einer realistischen Speicherauslastung aus.
Allerdings heisst das wohl das wenn ich printf, scanf etc. nutzen will
das ich das wieder hinzunehmen muss?
Oh man wie gut das ich mich mit dem Compiler so gut auskenne

Aber erstmal herzlichen Dank für eure Hilfe

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

AtmelFreak wrote:

> Allerdings heisst das wohl das wenn ich printf, scanf etc. nutzen will
> das ich das wieder hinzunehmen muss?

Nur, wenn du die Gleitkommaversion davon benötigst.  Die wirst du
auf einem ATtiny2313 wohl eher vermeiden wollen. ;-)

von 900ss (900ss)


Lesenswert?

1
.....  -Wl,-u,vfprintf -lprintf_min -Wl,-u,vfscanf -lscanf_min -lm

Jörg, damit ich nicht dumm sterbe... Weshalb wird hier das printf-Zeugs 
dazugelinkt, obwohl es keinen call gibt? Ich dachte dann wird es nicht 
gelinkt.

von holger (Gast)


Lesenswert?

>>Tiny2313

>Allerdings heisst das wohl das wenn ich printf, scanf etc. nutzen will
>das ich das wieder hinzunehmen muss?

Ja, sicher. Aber solche mächtigen/großen Funktionen haben
auf einem so kleinen Controller nichts zu suchen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

900ss D. wrote:

> Jörg, damit ich nicht dumm sterbe... Weshalb wird hier das printf-Zeugs
> dazugelinkt, obwohl es keinen call gibt?

Weil das mit dem -uvfprintf erzwungen wird.

Der Haken ist, dass die vfprintf-Funktion die einzige Funktion in
der Bibliothek libprintf_flt.a ist.  Damit diese Funktion auch wirklich
aus dieser Bibliothek genommen wird, muss sie zum Zeitpunkt, da die
Bibliothek durchsucht wird, `externally undefined' in der Symboltabelle
sein.  Da die meisten Nutzer aber wohl eher printf oder fprintf rufen
werden und nicht vfprintf selbst, würde die Bibliothek in diesem Falle
erstmal ignoriert, bis das printf später in der Standardbibliothek
gefunden worden ist.  Dieses wiederum erzeugt dann eine undefinierte
Referenz auf vfprintf, die dann aber auch aus der Standardbibliothek
befriedigt werden würde.

Nicht wirklich schön, aber das erschien mir damals der einzig
praktikable Weg.  Heute würde ich die libprintf_flt.a wohl eher so
aufbauen, dass dort die komplette printf-Familie drin ist, dann geht
es auch ohne den -u-Trick.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:

> sein.  Da die meisten Nutzer aber wohl eher printf oder fprintf rufen
> werden und nicht vfprintf selbst, würde die Bibliothek in diesem Falle
> erstmal ignoriert, bis das printf später in der Standardbibliothek
> gefunden worden ist.  Dieses wiederum erzeugt dann eine undefinierte
> Referenz auf vfprintf, die dann aber auch aus der Standardbibliothek
> befriedigt werden würde.

Ich bin nicht so fit, was ld angeht...
Könnte man das nicht über --start-group et al. lösen?

von 900ss (900ss)


Lesenswert?

Jörg Wunsch wrote:
> Weil das mit dem -uvfprintf erzwungen wird.
OK, das habe ich begriffen.

> .....  Damit diese Funktion auch wirklich
> aus dieser Bibliothek genommen wird, muss sie zum Zeitpunkt, da die
> Bibliothek durchsucht wird, `externally undefined' in der Symboltabelle
> sein.

Also nur das (externally undefined) ist der Grund, weswegen man den -u 
Trick anwenden muß? Damit vfprintf "externally undefined" in der 
Symboltabelle steht und damit dann statt der Standard-Lib die richtige 
Lib. dazugelinkt wird? Hab ich es richtig begriffen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:

> Könnte man das nicht über --start-group et al. lösen?

So, wie ich die Beschreibung lese, nicht.  Man müsste ja libprintf_flt.a
und libc.a zu einer Gruppe zusammen fassen.  Dennoch würde ja das printf
dann aus libc.a gefunden, und in diesem Moment entsteht ein neues
`globally undefined' namens vfprintf.  Das wiederum kann aber sofort
ebenfalls aus der libc.a befriedigt werden, und es gäbe für den Linker
keinen Grund, zurück zu libprintf_flt.a zu gehen (die eine alternative
Implementierung für vfprintf enthält).

Nein, ich denke schon, dass die Lösung wäre, die komplette printf-
Famile in die libprintf_flt.a (und dann noch in die libprintf_min.a)
aufzunehmen, analog dann für scanf.  In diesem Falle würde es dann
genügen, wenn -lprintf_flt vor -lc steht (die ja ohnehin nur implizit
am Ende eingebaut wird).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

900ss D. wrote:

> Also nur das (externally undefined) ist der Grund, weswegen man den -u
> Trick anwenden muß? Damit vfprintf "externally undefined" in der
> Symboltabelle steht und damit dann statt der Standard-Lib die richtige
> Lib. dazugelinkt wird? Hab ich es richtig begriffen?

Ja.

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.