Wie schaffe ich es die Größe des kompilierten Codes kleiner zu bekommen?
Während ich mit dem ICC für eine einfache Routine einen kompilierten
Code von ein paar Bytes bekomme, erhalte ich für denselben Sourcecode
mit avr-gcc kompiliert, mehrere KBytes. Trotz der eingeschalteten
Optimierung im makefile mittels der s Option.
Ich habe einige Hindeutungen auf ein Tool namens avr-size im /bin
Verzeichnis gelesen welches den code kleiner machen soll, aber die
Erklärungen waren mir bisher zu kryptisch.
Ich nutze (mittlerweile) übrigens WinAvr in der aktuellsten Version
Danke für eure Antworten.
Wie optimierst du? Die Option für möglichst kleinen Code heißt -Os.
Wie stellst du fest wie groß das Ergebnis ist? Ich hoffe du vergleichst
nicht die Größe der Hex- oder Elf-Dateien. Probier's mal mit avr-size
irgendwas.elf/irgendwas.hex ("text"). Kleiner machen kann man damit aber
nichts.
Und warum schreibst du nicht ins AVR-GCC-Forum?
????
Aber s ist als option doch schon im Makefile gesetzt.
Und verglichen habe ich den generierten *.hex Code vom icc Compiler und
den generierten .hex Code vom avr-gcc compiler. Und der Unterschied
waren !!13KB!!
Also wo soll ich da noch optimieren ?
Ich habe mal die beiden Hex Dateien auf Codegröße mit avr-size gecheckt
und muss feststellen dass Tasteneingabe1 wesentlich kleiner ist als
tasteneingabe. Lässt sich im Ausgabefensterbild hoffentlich
nachvollziehen.
Also kann ich doch anhand des Vergleichs der hex Dateien sehen dass
eines größer ist als das andere.
Aber mein Problem ist damit noch immer nicht gelöst.
Nicht sehr gross oder ???
Also ein Compiler der daraus 14K macht ist kein Compiler !
/************************************************************/
#include <avr/io.h>
#include <avr/io8515.h>
int main (void)
{
unsigned char taster;
DDRB = 0xff; // PORTB Ausgang komplett
DDRD = 0x00; // alle Eingänge an PORTD
for(;;)
{
taster = PIND;
PORTB = taster;
}
return 0;
}
/**********************************************************/
Hi Axel!
>> Also kann ich doch anhand des Vergleichs der hex Dateien sehen dass eines
größer ist als das andere.
Ne, nicht wirklich. Da mußt Du Dir die Dateien im Hex-Editor anschauen
und vergleichen, wieviel Bytes wirklich Befehle enthalten.
Es kann zum Beispiel sein, dass ein Compiler im Hex-File nur die Befehle
ausgibt und dann Schluß macht. Der Rest im AVR wird dann nicht
geschrieben. Ein anderer Compiler schreibt nach den Befehlen lauter FFs
in das File, die dann auch im AVR stehen. Die Dateien sind ungleich, der
Code kann der gleiche sein. Oder ein Compiler legt eine .db-Anweisung
direkt hinter die Befehle und läßt den Rest frei, ein anderer schreibt
die .db-Anweisung ans Ende des Flash und füllt den Zwischenraum mit FFs.
Also, zum Vergleichen schauen, wieviele Bytes im File wirklich Befehle
repräsentieren und was nur Füllung ist. Von vornherein festlegen kann
man das wohl nur, wenn man direkt ASM programmiert.
Würde ich so sehen. Einwände?
Sven
Ich habe mal das ganze compilierte Teil inklusive makefile und
dosausgabe als Bild gezippt und angehängt vielleicht findet jemand ja
das Problem. Ich untersuche gerade das makefile auf eventuelle
"Problemzonen".
Aber vielleicht ist ja jemand schneller als ich.
tschö
http://www.mikrocontroller.net/attachment.php/27328/ausgabedos.jpg:
Sieht so aus als würden da haufenweise unnötige Bibliotheken dazugelinkt
(-lprintf_flt, -lm, ...). Keine Ahnung warum das im Standard-Makefile so
drin ist. Wenn du "von Hand" kompilierst, funktioniert alles wie
erwartet:
avr-gcc test.c -mmcu=at90s8515 -Os -g -o test.elf
avr-objcopy -O ihex test.elf test.hex
Hab ja fast das gleiche problem hier geschildert
http://www.mikrocontroller.net/forum/read-2-27323.html
habe jetzt diese 2 zeilen im makefile auskommentiert und siehe da, laut
avr-size:
744 statt zuvor 5536. Ist zwar immer noch leicht grösser als die 674 mit
dem speziell angepassten makefile, aber ich will ja nicht meckern... :o)
Warum steht sowas in nem standard makefile? So oft wird floatingpoint
printf ja wohl auch nicht benötigt.
Wer kennt eine leicht verständliche Doku der Makefiles?
Gruß Axel
Sorry to post in English.
The sample makefile in the latest WinAVR release, 20030424, has a "bug".
Comment out the line:
LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
to
# LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
and that will dramatically reduce your code size. This line links in the
floating point printf library, which is huge.
You can leave in:
LDFLAGS += -lm
as this will not increase the code size. This will link in the math
library, but it will only include functions if you use them.
Sorry for the inconvenience. This will be corrected in the next release.
Gruß
Eric Weddington
>> Wer kennt eine leicht verständliche Doku der Makefiles?
schau mal ins doc verzeichnis von winavr dort ist einen dokumentation.
die ersten fünf kapitel in ruhe durchlesen.
Ciao,
BAB
Das war übrigens mein Versehen, 'tschuldigung Jungs. Ich hatte
Eric einen Review seines Beispielmakefiles geliefert (den ich
ihm schon lange versprochen hatte) und dort die Zeile mit dem
floating point printf() dringelassen. Die war natürlich
eigentlich als Kommentar gedacht... Eric war ein bißchen knapp
mit der Zeit bei der Fertigstellung der letzten WinAVR-Version
(die er vor allem aufgrund reparierter Compiler-Bugs angefertigt
hat), da hat er das dann auch übersehen.
Zur Frage, wer denn floating point printf() braucht: naja, sowie
man nicht mit den Bytes knausern muß, nimmt man doch gerade
fürs Debuggen gern mal printf(). Ideal ist es ja eigentlich,
wenn man für die Entwicklung einen ATmega128 benutzen kann und
dann, wenn man weiß, daß der Algorithmus und die gewünschten
Funktionen gehen, erstmal festlegt, wie groß der Controller für
den richtigen Zweck denn sinnvoll sein sollte. Andersrum kommt
man schnell in die Verlegenheit, am Ende eine Hardware designt
zu haben, bei der man nützliche Features weglassen muß, nur
weil man in der Pi-mal-Daumen Schätzung am Anfang den Controller
zu klein gewählt hat (oder man muß endlos Stunden dransetzen,
den Code mit der Hand kleiner zu feilen). Aber es ist
natürlich auch ziemlich klar, daß floating point printf()
unter einem ATmega16* keinen Sinn hat.