Guten Abend zusammen,
ich bin in auf der Suche nach Flash-Flashfressern in einem Projekt
(STM32F103). Ich habe mir mal mit nm die Funktionen angeschaut, die nach
der LTO noch übrig bleiben. Hier die größten Brocken:
1
134247197 00000856 T _realloc_r
2
134264961 00000988 T __ieee754_rem_pio2
3
536872084 00001032 D __malloc_av_
4
536871016 00001064 d impure_data
5
134239781 00001116 T _malloc_r
6
134224749 00001188 T main
7
134227809 00001300 T tft_putChar
8
134266733 00001684 T __kernel_rem_pio2
9
134232949 00001792 T RunAllTests
10
134256833 00002836 T _dtoa_r
11
134248293 00003952 T _svfprintf_r
12
134252245 00004016 T _vfprintf_r
Auffällig sind die beiden __ieee754_rem_pio2 und __kernel_rem_pio2. Zum
einen benutze ich meines Wissens innerhalb des gesamten Projekts keine
trigonometrischen Funktionen auf Float. Zum anderen scheint es eine
Dublette für unterschiedliche Float-Varianten zu sein.
Gibt es eine Möglichkeit, herauszufinden, welche Kette von
Funktionsaufrufen die Einbindung dieser Funktionen bewirkt?
Viele Grüße
W.T.
Wenn du auf dem Controller Debuggern kannst, dann wäre ein einfacher
Versuch einen Breakpoint auf die Funktion zu setzen. Vielleicht wird die
Funktion aufgerufen und du hast einen Callstack.
Alternativ könntest du für die Objectfiles die .lst Dateien durchsuchen,
ob dort die entsprechende Funktion aufgerufen wird. Wenn die Funktion
allerdings in einer Bibliothek, die du nur linkst, aufgerufen wird, dann
kommst du damit wahrscheinlich nicht weiter.
Nachdem deine Liste "RunAllTests" enthält vermute ich, dass dort ein
Testframework läuft. Könnte es sein, dass dort für eine Metrik oder zur
Darstellung diese Funktionen benötigt werden?
Walter T. schrieb:> Guten Abend zusammen,>> ich bin in auf der Suche nach Flash-Flashfressern in einem Projekt> (STM32F103). Ich habe mir mal mit nm die Funktionen angeschaut, die nach> der LTO noch übrig bleiben. Hier die größten Brocken:>
1
> 134247197 00000856 T _realloc_r
2
> 134264961 00000988 T __ieee754_rem_pio2
3
> 536872084 00001032 D __malloc_av_
4
> 536871016 00001064 d impure_data
5
> 134239781 00001116 T _malloc_r
6
> 134224749 00001188 T main
7
> 134227809 00001300 T tft_putChar
8
> 134266733 00001684 T __kernel_rem_pio2
9
> 134232949 00001792 T RunAllTests
10
> 134256833 00002836 T _dtoa_r
11
> 134248293 00003952 T _svfprintf_r
12
> 134252245 00004016 T _vfprintf_r
13
>
>> Zum einen benutze ich meines Wissens innerhalb des gesamten Projekts keine> trigonometrischen Funktionen auf Float.
Da:
> 134248293 00003952 T _svfprintf_r> 134252245 00004016 T _vfprintf_r
Dass die zur Laufzeit nicht verwendet werden kann ein Compiler nicht
wissen — uns selbst wenn, welche xprintf-Implementation sollte er dann
verwenden? Manchmal gibt's abgespeckte LibCs mit weniger Features:
Nicht Standard-konfirm aber eben kleiner.
> Zum anderen scheint es eine Dublette für unterschiedliche Float-Varianten zu
sein.
???
> Gibt es eine Möglichkeit, herauszufinden, welche Kette von> Funktionsaufrufen die Einbindung dieser Funktionen bewirkt?
Map-File oder Lib-Quelle.
Zwölf M. schrieb:> printf() ... was soll die bringen ? Auf dem PC etwas Tolles, auf einem> Controller ein striktes No-go.
Im Allgemeinen ist das falsch. Auf 32-Bit-µCs (mit entsprechend mehr
Flash/RAM) geht das durchaus. Auf einem STM32F103 ist das überhaupt kein
Problem.
Guten Morgen,
danke für die Antworten. Vorweg: Mir geht es momentan nicht ums Platz
sparen. Mit dem Platz sieht es noch gut genug aus (ich habe noch 64 kB
Reserve). Mir geht es darum, den Platzverbrauch zu verstehen.
M.K. B. schrieb:> Nachdem deine Liste "RunAllTests" enthält vermute ich, dass dort ein> Testframework läuft.
Richtig. Deswegen überhaupt die Float/Double-Unterstützung (Vergleich
von selbstgeschriebenen Funktionen mit einer Referenzimplementierung)
und Ausgabe per printf.
Eine Metrik gibt es aber nicht aus und wird m.W. auch nicht berechnet.
Johann L. schrieb:> Da:>>> 134248293 00003952 T _svfprintf_r>> 134252245 00004016 T _vfprintf_r
Das ist auch meine Vermutung. Mein Ziel ist der Schritt vom Vermuten zum
Wissen. Ein bischen Abwegig ist es ja schon, daß printf() irgendwelche
Bruchteile von PI benötigt.
Im *.res-File tauchen die Funktionen nicht auf- deswegen gehe ich davon
aus, dass sie von Library-Funktionen aufgerufen werden.
Im Map-File sehe ich.... nichts. Außer dass alle "verdächtigen"
Funktionen aus der libc stammen (libg_s.a). Aber so habe ich die
richtigen Suchbegriffe gefunden (call graph + map file). Da muß ich mich
mal in das passende Werkzeug einlesen. Ich dachte eventuell, so etwas
wär schon in den Bordmitteln enthalten.
M.K. B. schrieb:> Wenn du auf dem Controller Debuggern kannst, dann wäre ein einfacher> Versuch einen Breakpoint auf die Funktion zu setzen.
Das war auch mein erster Gedanke. Aber wie setze ich einen Breakpoint in
eine Library-Funktion, die als Kompilat verlinkt wird? Gibt es
Debugging-Werkzeuge, die für die Arbeit mit einem reinen Binary ohne
Quelltext geeignet sind? Bislang habe ich immer in der IDE debuggt.
Zwölf M. schrieb:> printf() ... was soll die bringen ?
Damit kann ich den Inhalts meines mit malloc() allozierten Arrays aus
zur Laufzeit berechneten double-Werten sehr bequem ausgeben. Was
übrigens selbst auf dem AVR bei 1 MHz schneller geht, als eine
Forendiskussion darüber zu lesen. BTDT.
Frank M. schrieb:> Zwölf M. schrieb:>> printf() ... was soll die bringen ? Auf dem PC etwas Tolles, auf einem>> Controller ein striktes No-go.>> Im Allgemeinen ist das falsch. Auf 32-Bit-µCs (mit entsprechend mehr> Flash/RAM) geht das durchaus. Auf einem STM32F103 ist das überhaupt kein> Problem.
Und selbst auf einem AVR würde ich das nicht einfach a priori
ausschließen. Wenn man den Flash-Speicher nicht für was anderes braucht,
und printf() nützlich sein kann, warum sollte man ihn dann ungenutzt
lassen, nur um irgendeinem Prinzip zu gehorchen? Geld bekommt man dafür
bekanntlich nicht zurück.
Walter T. schrieb:> Im Map-File sehe ich.... nichts. Außer dass alle "verdächtigen"> Funktionen aus der libc stammen (libg_s.a).
Da sollte doch zumindest das Modul autauchen? Hier mal einen Auszug (für
anderes Target, was aber keine Rolle spielt):
1
Archive member included to satisfy reference by file (symbol)
Von Modul crtatmega168.o wurde also Symbol "exit" referenziert, das noch
nicht aufgelöst war. Die Auflösung / Definition des Symbols "exit"
geschah dadurch, dass gegen Modul _exit.o aus libgcc.a gelinkt wurde.
Einzelne Funktionen sieht man auf dieser Ebene nicht mehr, sondern nur
noch Module oder Input-Sections. Da libc/libm üblicherweise so
übersetzt werden, dass jede Funktion in einem eigenen, entsprechend
benannten Modul landet, kann man die Funktion hier einfach raten: Es ist
_exit aus der libgcc.
Oder
Bei der newlib nano muss man floats beim printf explizit erlauben:
>2) Programs that require formatted floating-point input/output must >explicitly> reference the relevant support function during linking. For the scanf()> family of routines the support function is "_scanf_float". For the> printf() family of routines the support function is "_printf_float".> There are two ways to achieve this:> a) Explicitly reference the support function during linking. For example,>by adding "-u _printf_float" to the link command
Also vllt mal die libc wechseln?
Oder guck doch mal welche du nimmst, vllt lässts sich ja abschalten.