Forum: Compiler & IDEs STM32F303: Empfehlenswerte Compilerargumente


von Alex -. (alex796)


Lesenswert?

Hi,
bis dato habe ich immer blind STM32CubeIDE verwendet, sowohl zum 
Programmieren als auch zum kompilieren und flashen. All das geschah 
hinter den Kulissen.

Nun habe ich angefangen, mich mit GNU GCC für ARM Architekturen zu 
beschäftigen und frage mich, welche Compilerargumente empfehlenswert 
sind.

Anbei mein makefile [Kritik und Verbesserungsvorschläge erwünscht]:
1
# CC and MACH are variables
2
CC=arm-none-eabi-gcc
3
MACH=cortex-m4
4
# CFLAGS will be options passed to the compiler
5
CFLAGS= -c -mcpu=$(MACH) -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -I ./Driver -std=gnu11 -Wall -O0 -DSTM32F303xC
6
LDFLAGS= -mcpu=$(MACH) -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard --specs=nano.specs -TSTM32F303CCTX_FLASH.ld -Wl,-Map=final.map
7
8
# Target: Dependencies
9
all: main.o startup_stm32f303cctx.o syscalls.o sysmem.o system_stm32f3xx.o final.elf
10
main.o: main.c
11
  $(CC) $(CFLAGS) -o $@ $^
12
13
syscalls.o: Driver/syscalls.c
14
  $(CC) $(CFLAGS) -o $@ $^
15
16
sysmem.o: Driver/sysmem.c
17
  $(CC) $(CFLAGS) -o $@ $^
18
19
system_stm32f3xx.o: Driver/system_stm32f3xx.c
20
  $(CC) $(CFLAGS) -o $@ $^
21
22
startup_stm32f303cctx.o: startup/startup_stm32f303cctx.s
23
  $(CC) $(CFLAGS) -o $@ $^
24
25
final.elf: main.o startup_stm32f303cctx.o syscalls.o sysmem.o system_stm32f3xx.o
26
  $(CC) $(LDFLAGS) -o $@ $^
27
28
clean:
29
  @echo "Clean project"
30
#  -del -rf *.o *.elf
31
  -rm -rf *.o *.map *.elf
32
  @echo "Clean completed"

Schaue ich mir das makefile an, das ST bei den Projekten erstellt, sind 
da etwas mehr Argumente vorhanden:
1
-g3 -O0 -ffunction-sections -fdata-sections -fstack-usage -MMD -MP -MF"Src/main.d" -MT"Src/main.o"
-g3: Debugging information
-O0: Debugging produces expected results
ffunction sections / fdata sections: Garbage collection optimization
MMD: ???
MP: ???
MF: ???
MT: ???

Die ersten 3 Kompilerargumente (g3, o0, ffunction/fdata) ergeben Sinn 
für mich.
Ich habe allerdings schwer, die ganzen M Argumente zu deuten, wenn ich 
sie im GNU GCC Handbuches nachschlage.

Frage 1: Was genau bewirken die?

Frage 2: Ergeben die Sinn?

Frage 3: Würdet Ihr zusätzliche Kompilerargumente empfehlen?

Vielen Dank,

von Klaus W. (mfgkw)


Lesenswert?

Die -M erzeugen eine Textausgabe, die in ein makefile kopiert werden 
kann ("die a.cpp inkludiert x.h" etc. in Makefile-Format).
Brauchst du nur, wenn du die makefile-Regeln nicht ganz von HAnd 
schreiben willst.

von Klaus W. (mfgkw)


Lesenswert?

PS: man kann die auch dazu nutzen, sie mit einem eigenen Target (z.B. 
dep) im makefile zu erzeugen und immer im makefile mit include 
einzufügen.
Ändert man was an den includes in C, wird mit mit einem make dep alles 
wieder korrigiert.

von Cartman (Gast)


Lesenswert?

> welche Compilerargumente empfehlenswert sind

Welche Zwiebeln soll ich kaufen?
Normale, Weisse oder Rote? Oder doch besser Knoblauch?

Dein Ansinnen entspringt wohl eher deiner Faulheit.
Aber, sowas wie "empfehlenswert" gibt es nicht.

P.S.
Das was an den Linker gereicht wird, ist noch viel niedlicher.

von Alex -. (alex796)


Lesenswert?

Vielen Dank, Klaus!

von Nop (Gast)


Lesenswert?

Alex -. schrieb:

> Die ersten 3 Kompilerargumente (g3, o0, ffunction/fdata) ergeben Sinn
> für mich.

O0 ergibt allenfalls zum Debuggen einen Sinn, sonst ist O2 die bessere 
Wahl. O3 bläht eher den Code auf, bringt aber kaum Performance. Ich 
würde außerdem noch vorschlagen:

-Wall -Wextra -Wpedantic -fno-strict-overflow -mslow-flash-data 
-mcpu=cortex-m4 -mtune=cortex-m4

Die ersten drei sollten klar sein - schalte Compiler-Warnungen an und 
behebe die angemeckerten Stellen, dann brauchst Du nicht soviel zu 
debuggen.

No strict overflow: in C ist signed integer overflow nicht definiert, 
weil die Negativdarstellung nicht standardisiert ist. Der Compiler darf 
solche Stellen einfach wegoptimieren. Das ist heute eher lästig, weil 
das Zweierkomplement sich durchgesetzt hat.

Die m-Optionen sind ja selbsterklärend - die erstere berücksichtigt bei 
den Optimierungen, daß verteilte Datenzugriffe aufs Flash langsamer sein 
können.

von mh (Gast)


Lesenswert?

Nop schrieb:
> No strict overflow: in C ist signed integer overflow nicht definiert,
> weil die Negativdarstellung nicht standardisiert ist. Der Compiler darf
> solche Stellen einfach wegoptimieren. Das ist heute eher lästig, weil
> das Zweierkomplement sich durchgesetzt hat.

Dir ist klar, dass die Option nur die Warnung deaktiviert, nicht das 
worüber gewarnt wird?

von mh (Gast)


Lesenswert?

mh schrieb:
> Nop schrieb:
>> No strict overflow: in C ist signed integer overflow nicht definiert,
>> weil die Negativdarstellung nicht standardisiert ist. Der Compiler darf
>> solche Stellen einfach wegoptimieren. Das ist heute eher lästig, weil
>> das Zweierkomplement sich durchgesetzt hat.
>
> Dir ist klar, dass die Option nur die Warnung deaktiviert, nicht das
> worüber gewarnt wird?

nehme ich zurück, hab ein W mehr in die Option gepackt. Ist trotzdem 
meiner Meinung nach keine gute Idee.

von Bauform B. (bauformb)


Lesenswert?

Nop schrieb:
> O0 ergibt allenfalls zum Debuggen einen Sinn, sonst ist O2 die bessere
> Wahl. O3 bläht eher den Code auf, bringt aber kaum Performance.

... wenn man die Performance braucht. Ich habe das Gefühl, dass für 
viele Leute O0 bei 8MHz durchaus schnell genug wäre. Allerdings würde 
ich O0 freiwillig nie benutzen. Mit Os wird auch viel effektiverer Code 
als mit O0 erzeugt, der Unterschied ist größer als von Os zu O2, aber Os 
spart viel Platz. Dadurch wird der Code lesbarer als mit O0, auch wenn 
die Zuordnung zum Quelltext nicht mehr ganz so gut ist. Die Verschiebung 
beschränkt sich doch auf wenige Zeilen.

Man liest gelegentlich von Fehlern, die je nach Optimierungsstufe 
auftauchen oder nicht. Von daher dürfte man keinen Unterschied zwischen 
Debug- und Release-Version haben. Auch deswegen ist Os ein guter 
Kompromiss, wenn man nicht gerade an Übertakten denkt.

Cartman schrieb:
> Aber, sowas wie "empfehlenswert" gibt es nicht.

Nun, -Wall -Wextra sind immer empfehlenswert. Eigentlich sind fast alle 
-W Optionen empfehlenswert. Warum sollte man auf die Hilfestellung 
verzichten? Es gibt so witzige und trotzdem nützliche wie 
-Wmisleading-indentation oder -Wstack-usage=42. Falls man zu einer 
Warnung etwas nachlesen möchte hilft -fdiagnostics-show-option.

-std=c2x ist wohl noch zu früh, aber zusammen mit -pedantic würde ich 
den Standard festlegen wollen.

-nostdlib würde zum Verzicht auf CubeMX passen;)

-fstrict-volatile-bitfields sollte Default sein, aber sicher ist sicher.

-fno-lto wenn Interrupt-Routinen nicht funktionieren. LTO funktioniert 
wohl meistens, aber es ist sehr komplex, also für viele Überraschungen 
gut.

-ffunction-sections -fdata-sections -Wl,--gc-sections hab' ich 
rausgeworfen, das Manual sagt dazu:
1
Only use these options when there are significant benefits from doing so. ...and you may have problems with debugging if you specify both this option and -g.
schlaue Leute sagen dazu:
https://stackoverflow.com/questions/4274804/query-on-ffunction-section-fdata-sections-options-of-gcc

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Bauform B. schrieb:
> Man liest gelegentlich von Fehlern, die je nach Optimierungsstufe
> auftauchen oder nicht.

Der Optimierer versteht halt nur C/C++. Wenn man dem was anderes 
vorsetzt, braucht man sich nicht zu wundern, daß es nicht funktioniert.

Es spricht überhaupt nichts gegen O2 oder O3, wenn das Profiling ergibt, 
daß das Vorteile bringt.

Oliver

von Bauform B. (bauformb)


Lesenswert?

Oliver S. schrieb:
> Es spricht überhaupt nichts gegen O2 oder O3, wenn das Profiling ergibt,
> daß das Vorteile bringt.

Ich hab' nichts gegen O2, wenn das Vorteile bringt. Ich wollte sagen, 
dass Feiglinge (Chaoten?) dann auch mit O2 debuggen sollten.

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

Ich werfe für eine MCU mit single precission FPU noch
-fsingle-precision-constant -Wdouble-promotion
ein. Also Nur Float benutzen und wo double angezogen wird durch Libs 
warnen.

von Rolf M. (rmagnus)


Lesenswert?

Bauform B. schrieb:
> Oliver S. schrieb:
>> Es spricht überhaupt nichts gegen O2 oder O3, wenn das Profiling ergibt,
>> daß das Vorteile bringt.
>
> Ich hab' nichts gegen O2, wenn das Vorteile bringt. Ich wollte sagen,
> dass Feiglinge (Chaoten?) dann auch mit O2 debuggen sollten.

Das sehe ich auch so. Gerade bei eingeschalteten Optimierungen machen 
sich viele Programmfehler erst bemerkbar. Wenn man das zum Debuggen 
bewusst ausschaltet, muss man nachher noch ein zweites mal debuggen. Und 
mit etwas Übung bekommt man ein Programm auch bei -O2 gedebugt.

Nop schrieb:
> O0 ergibt allenfalls zum Debuggen einen Sinn, sonst ist O2 die bessere
> Wahl.

Auch für das Debugging ist -O0 wenig sinnvoll. Das hat für das Debugging 
(und naütrlich die Performance) Nachteile gegenüber -Og. Mir würde kein 
Grund einfallen, warum man je -O0 verwenden sollte.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Rolf M. schrieb:
> Und
> mit etwas Übung bekommt man ein Programm auch bei -O2 gedebugt.

Auch mit -O3. So groß sind die Unterschiede bzgl. Sourcecode-Debugging 
da dann auch nicht mehr.

Oliver

von Moby (Gast)


Lesenswert?

Ach Du meine Güte.
Nehmt simplen Assembler und das Thema ist gegessen. Aber warum einfach 
wenns auch kompliziert geht? Warum nur Programm programmieren wenn man 
nebenbei auch noch die Werkzeuge dazu programmieren kann?

von ohne Scheiß keinen Preiß (Gast)


Lesenswert?

Meine Empfehlung: mindestens die man-page zu cc oder gcc durchlesen, das 
ist ein guter Einstieg in grundlegende Zaubereien mit dem Compiler. Am 
besten mal ein Wochenende Zeit nehmen und an einem überschaubaren 
Projekt alle Optionen durchprobieren:

http://www.nsc.ru/cgi-bin/www/unix_help/unix-man?cc+1

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.