Forum: Mikrocontroller und Digitale Elektronik Warum sind nicht verwendete Funktionen im Build enthalten?


von Ben (Gast)


Lesenswert?

Hallo,

ich habe das Problem, dass auch nicht verwendete Funktionen im Build 
enthalten sind und somit das HEX-File aufblächen.
Beispiel:
Ich lege eine Testfunktion an, welche ich niemals aufrufe:
1
#if 1 //0
2
void test_fkt(void);
3
void test_fkt(void)
4
{
5
}
6
#endif

Anschließend compile ich mein Projekt einmal mit aktiver Testfunktion 
(#if 1) und einmal mit abgeschalteter Testfunktion (#if 0).
Die Consolenausgabe gibt unterschiedliche Programmgrößen für mit und 
ohne Testfunktion an:
1
Mit Testfunktion: ... Program: 1056 bytes (3.2% Full) (.text + .data + .bootloader) ...
2
Ohne Testfunktion: ... Program: 1054 bytes (3.2% Full) (.text + .data + .bootloader) ...

Es sind zwar nur 2 Byte, aber es handelt sich ja auch um eine leere 
Testfunktion.
Dabei ist es egal welche Optimierungsstufe ich wähle (-o0, -o1, -o2, 
-o3, -os), es gibt immer einen Programmgrößenunterschied zwischen mit 
und ohne Testfunktion.
Die Dateigröße vom hex-File ändert sich auch.

Des Weiteren taucht die Testfunktion auch im map-File auf:
1
...
2
0x00000094  testfkt1
3
0x0000009a  test_fkt_damit_mehr_speicher
4
0x0000009c  test_fkt2
5
...

Somit spricht meines erachtens alles dafür, dass die Funktion wirklich 
im hex-File enthalten ist.

Meinem Verständnis nach sollte der Linker nicht benötigte Funktionen 
jedoch entfernen. Ich habe nämlich das Problem, dass mein Projekt nicht 
mehr in den µC passt, weil nicht benötigte Funktionen Platz "wegnehmen". 
(Ich möchte nicht alle möglichen Funktionen in meinen Dateien und 
Bibliotheken auskommen.)

Ich hoffe, ihr könnt mir weiterhelfen.

Ich verwende ATmega32, winAVR, Eclipse, Win7 64Bit.

Gruß
Ben

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ben schrieb:
> Meinem Verständnis nach sollte der Linker nicht benötigte Funktionen
> jedoch entfernen.

Das tut er nur, wenn er "function-level linking" beherrscht. Das kann 
nicht jeder Linker.

von holger (Gast)


Lesenswert?

Gib dem Compiler folgendes mit:

-ffunction-sections -fdata-sections


Und dem Linker:

--gc-sections

Das könnte helfen.

von Ben (Gast)


Lesenswert?

Vielen Dank für eure Info. Mit euren Schlagworten habe ich nun auch die 
passende Seite 
http://www.mikrocontroller.net/articles/GCC:_unbenutzte_Funktionen_entfernen 
gefunden.

Gruß
Ben

von Ben (Gast)


Lesenswert?

Ich verwende die entsprechenden Parameter (Einstellungen in Eclipse), 
siehe Aufruf in Console von Eclipse:
1
avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=3686400UL -MMD -MP -MF"trunk/PROJECTS/TEST2/TEST2.d" -MT"trunk/PROJECTS/TEST2/TEST2.d" -c -o "trunk/PROJECTS/TEST2/TEST2.o" "E:/trunk/PROJECTS/TEST2/TEST2.c"
2
avr-gcc -Wl,-Map,test2.map --gc-sections -mmcu=atmega32 -o "test2.elf" ...
Nun werden die Funktionen aus gleichen Dateien in unterschiedliche 
Sections aufgeteilt. Aber es werden keine Sections weggelassen.

Map-File:
1
...
2
 .text.testfkt1
3
                0x00000098        0x2 ./trunk/PROJECTS/TEST2/TEST2.o
4
                0x00000098                testfkt1
5
 .text.test_fkt_damit_mehr_speicher
6
                0x0000009a        0x2 ./trunk/PROJECTS/TEST2/TEST2.o
7
                0x0000009a                test_fkt_damit_mehr_speicher
8
 .text.test_fkt2
9
                0x0000009c       0x4a ./trunk/PROJECTS/TEST2/TEST2.o
10
                0x0000009c                test_fkt2
11
...

Hat jemand eine Idee, woran das liegen kann?
Gruß
Ben

von (prx) A. K. (prx)


Lesenswert?

Ben schrieb:
> Nun werden die Funktionen aus gleichen Dateien in unterschiedliche
> Sections aufgeteilt. Aber es werden keine Sections weggelassen.

--gc-sections
   !=
-Wl,--gc-sections

von Ben (Gast)


Lesenswert?

A. K. schrieb:
> --gc-sections
>    !=
> -Wl,--gc-sections

Ich bin mir sehr sicher, dass ich das schon einmal so probiert hatte - 
ohne Erfolg.

Jetzt habe ich es noch einmal so getestet und jetzt funktioniert es. 
(Muss ich wohl noch etwas falsch gemacht haben.) SUPER!
Vielen Dank an euch! Gute Nacht
Ben

von Ben (Gast)


Lesenswert?

Hallo,

ich bin es noch einmal...
Nun habe ich das Problem, dass zu viele Funktionen weggelassen werden. 
Wenn die Funktionen recht kurz sind, werden sie auch weggelassen, obwohl 
sie aufgerufen werden. Durch ein wenig "herumprobieren" konnte ich ein 
kleines Beispiel finden, bei dem mein Problem auch auftritt. (Das 
Beispiel soll nur den Fehler beschreiben und stellt kein sinnvolles 
Programm dar.) Ich habe vier Testfunktionen test1 bis test4, welche ich 
alle in der main-Funktion aufrufe. Dabei werden die ersten zwei 
Funktionen weggelassen.
1
int main(void)
2
{
3
   test1();
4
   test2();
5
   test3();
6
   test4();
7
   while(1);
8
}
9
10
void test1(void)
11
{
12
   PORTB = 0U;
13
   PORTB += 1U;
14
}
15
16
void test2(void)
17
{
18
   PORTB = 0U;
19
   PORTB += 1U;
20
   PORTB += 1U;
21
}
22
23
void test3(void)
24
{
25
   PORTB = 0U;
26
   PORTB += 1U;
27
   PORTB += 1U;
28
   PORTB += 1U;
29
}
30
31
void test4(void)
32
{
33
   PORTB = 0U;
34
   PORTB += 1U;
35
   PORTB += 1U;
36
   PORTB += 1U;
37
   PORTB += 1U;
38
}

(Wenn ich den Inhalt der Funktionen austausche, so werden immer die 
Funktionen weggelassen, welche drei oder weniger Zeilen Operationen 
beinhalten.)

Über den Parameter "-Wl,--print-gc-sections" lass ich mir ausgeben, 
welche Sections weggelassen werden und erhalte folgende Ausgabe:
1
...
2
c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: Removing unused section '.text.test1' in file './trunk/FR_CONTROL.o'
3
c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: Removing unused section '.text.test2' in file './trunk/FR_CONTROL.o'
4
...

Im Map-File ist für diese beiden Funktionen auch kein Speicherbereich 
zugewiesen.

Den Hinweis zu Startup-Codes und Interrupt-Vektoren hatte ich gelesen. 
Aber dies ist ja etwas anders.

Hat jemand eine Idee, was ich falsch mache?
Gruß
Ben

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Schau die ds Disassemble von main an: Vermutlich wurden die Funktionen 
geinlinet, werden daher nicht mehr referenziert und die entsprechenden 
Sections entsorgt werden.

von holger (Gast)


Lesenswert?

>Nun habe ich das Problem, dass zu viele Funktionen weggelassen werden.

Dann nimm halt -O0 statt -Os oder -O1, -O2, -O3.
Oder besser: Wenn du debuggen willst schalte die Optimierung komplett 
ab.

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

die Eigenschaft, nicht benötigte Funktionen nicht zu linken, war zu 
Urzeiten mal völlig selbstverständlich, ich erinnere mich an 
verschiedene Z80-Linker, die das überhaupt oder mit dem Parameter /s 
(scan) beherrscht haben. Wenn ich das Modul für Fliesskommaarithemtik /s 
aufgerufen habe und keine Division im Programm vorkam, wurde der Code 
für die Division auch nicht gelinkt. Das ist irgendwann dem heutigen 
Paradigma zum Opfer gefallen, dass das Einsparen von Speicherplatz dumm 
und rückständig ist, man wird ja in vielen Foren massiv angefeindet wenn 
man den Speicherbedarf überhaupt erwähnt.

Ich habe allerdings nie begriffen, was denn der Vorteil sein soll, nie 
benutzte Codestücke mit einzubauen. Nur der Linker wird dadurch 
zugegebenermassen einfacher.

Nicht jede Entwicklung ist ein Fortschritt.

Gruss Reinhard

von Till (Gast)


Lesenswert?

Bascom kann das!

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.