Forum: Compiler & IDEs STM32F4 mit gcc-arm-none-eabi


von B. S. (kruwakre)


Lesenswert?

Hallo Zusammen,

ich versuche ein STM32-E407 Development Board von Olimex mit 
STM32F407ZGT6 CPU mit der GCC ARM Embedded toolchain 
(gcc-arm-none-eabi-4_9-2015q4) zu programmieren. Compiler und Linker 
(beides gcc) rufe ich mittels Makefile auf. Debugging mittels GNU gdb 
(GNU Tools for ARM Embedded Processors) 7.8.0.20150604-cvs. Debugserver 
ist Open On-Chip Debugger 0.8.0 (2014-06-07-21:57).

Mein Problem: Was ist die richtige Kombination aus CFLAGS, LDFLAGS 
startupfile.S und Linkerskript?

Mit folgendem kann ich erfolgreich ein Projekt aus CubeMx kompilieren, 
lande aber im HardFault_Handler des STM32F4.

CFLAGS = -Wall -ggdb -mcpu=cortex-m4 -mthumb -O0 -mfloat-abi=softfp 
-mfpu=neon $(HEADER_PATH) 
-Wl,--gc-sections,-Map=$(OUTPUT).map,-T$(LINKER_SCRIPT) 
--specs=nano.specs --specs=nosys.specs

gcc.ld (aus der arm none eabi toolchain)
startup_ARMCM4.S (aus der arm none eabi toolchain)

Ich habe mit STM32CubeMX release 4.14.0 ein Projekt erstellt, dass nur 
USB FS als Device Only als Communication Device Class und den RNG des 
STM32F407 configuriert. Die Clock-Einstellungen sind valide, laut 
CubeMx.

Leider habe ich keine Möglichkeit gefunden, aus CubeMX direkt in ein 
Makefile zu exportieren, und habe deshalb alle Sourcen, Header und 
Includepfade von Hand zusammengesucht und ins Makefile gepackt.

Ich habe bereits erfolgreich ein kleines BLINK LED Projekt mit o.g. 
toolchain zum Laufen gebracht. Nach langem Probieren hatte ich die 
richtige Kombination aus allen CFLAGS und Defines -D_USE_XYZ etc. 
Linkerscripts gefunden.

Ich möchte gerne den Zufall durch Planung in Irrtum verwandeln ;-) und 
endlich das Zusammenspiel aus CFLAGS, Defines, Linkersripts und 
startup-Files verstehen. Könnt Ihr mir helfen?

Wo finde ich dazu informationen, bzw. wer weiß Rat.
Gerne liefere ich noch weitere Details aus der Toolchain von CubeMx bis 
openocd. Ich wollte den ersten Beitrag nicht gleich überladen.

Beste Grüße
kruwakre

von hp-freund (Gast)


Lesenswert?

Moin,

man kann natürlich alles per Hand machen - wenn man möchte.
Allerdings dann auch wieder alles Neu bei Wechsel des Controllers.

Oder STM32SW4 benutzen wenn Du HAL verwendest.
Es lässt sich ein Projekt dafür aus CubeMX erstellen und dann einfach 
dieses in STM32SW4 (AC6) importieren.

Das erstellt dir dann auch die Makefiles, für alle Fälle.

von Ein Anfänger (Gast)


Lesenswert?

Moin,

Du kannst CubeMX auf TrueStudio einstellen, dann generiert es dir 
Linkerfile und Startup-File für die gcc und du kannst die in deinem 
Makefile benutzen.

Ich kann dir sonst noch die Flags heraussuchen, die ich genutzt habe 
(bin inzwischen auf CMake umgestiegen).

von John Doe (Gast)


Lesenswert?

B. S. schrieb:
> CFLAGS = -Wall -ggdb -mcpu=cortex-m4 -mthumb -O0 -mfloat-abi=softfp
> -mfpu=neon $(HEADER_PATH)
> -Wl,--gc-sections,-Map=$(OUTPUT).map,-T$(LINKER_SCRIPT)
> --specs=nano.specs --specs=nosys.specs

Also die NEON-Engine hat der M4 sicherlich nicht.
Dafür die FPv4-SP.

Richtig wäre also:
-mfpu=fpv4-sp-d16 -mfloat-abi=hard

Die FPU muss aber noch per Software aktiviert werden. Steht im Cortex-M4 
Programming Manual unter "Enabling the FPU".

von Dr. Sommer (Gast)


Lesenswert?

B. S. schrieb:
> -mfpu=neon

B. S. schrieb:
> gcc.ld (aus der arm none eabi toolchain)
> startup_ARMCM4.S (aus der arm none eabi toolchain)

Beides falsch. Siehe ARM GCC. Startupcode & Linkerscript musst du 
aus den Beispielen von ST kopieren.

von Steffen R. (steffen_rose)


Lesenswert?

Man findet passende Files auch in der CubeFW:
z.B.:
STM32Cube_FW_F4_V1.9.0\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Template 
s

von Markus W. (dl8mby)


Lesenswert?

Schau Dir mal das Projekt mcHF vom Sulinger Amateurfunk Club an:

https://github.com/df8oe/mchf-github/tree/master/mchf-eclipse

Details sind auch in folgenden Thred zu finden.

Beitrag "mcHF-SDR Selbstbau-Projekt"

Das Projekt im Github läuft auf einem 405/407 und dort sind die
Makefiles und Linkerfiles zum abkupfern vorhanden.

Vielleicht hilft Dir das.

Markus
DL8MBY

von Dr. Pinguin (Gast)


Lesenswert?

Markus W. schrieb:
> Das Projekt im Github läuft auf einem 405/407 und dort sind die
> Makefiles und Linkerfiles zum abkupfern vorhanden.
>
> Vielleicht hilft Dir das.


Ganz sicher nicht!
Da er schon nicht weiss, dass der M4 keine NEON Engine hat, sollte er 
erstmal mit den Grundlagen anfangen und nicht irgendetwas, das er nicht 
versteht, einfach "abkupfern". So wird er nur von Problem zu Problem 
stolpern.

Ganz schlechter Tipp...

von B. S. (kruwakre)


Lesenswert?

Hallo Zusammen,

besten Dank für die Antworten. Ich kann jetzt erfolgreicht compilieren, 
und Debuggen!
Das der Cortex M4F kein keine NEON SIMD Engine hat, ist absolut richtig. 
Diese ist nur in den Cortex A Typen vorhanden. Das hätte ich dann 
spätestens beim Debuggen der ersten NEON instruction am SIGILL gemerkt. 
Dann wäre der AHA Effekt sicher noch größer gewesen.

Folgendes hat zum Erfolg geführt:
Ich habe in CubeMx in den "Project Settings" unter Toolchain / IDE auf 
"SW4STM32" gestellt. Ich vermute, es geht auch mit anderen 
Einstellungen.
Das daraus entstehende Linkerscript "STM32F407ZGTx_FLASH.ld" im 
Rootverzeichnis der von CubeMx erstellten Verzeichnisstruktur passt 
offensichtlich zum "startup_stm32f407xx.s" welches sich ebenfalls in 
dieser Struktur unter 
/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/ befindet (Danke 
an Steffen Rose).
Die CFLAGS habe ich aus dem Artikel ARM GCC hier im Forum 
(https://www.mikrocontroller.net/articles/ARM_GCC) aus dem Kapitel 
Compiler & Linker Flags --> "Ohne Optimierungen, mit 
Debug-Informationen:" Zeile "C-Compiler (gcc) " Spalte Cortex-M4F 
entnommen:
-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb 
-ffunction-sections -fdata-sections -g
(Danke an Dr. Sommer)
Ich habe allerdings noch ergänzt: --specs=nosys.specs
Ohne das erhalte ich folgende Fehlermeldung:
/opt/gcc-arm-none-eabi-4_9-2015q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../ 
../../../arm-none-eabi/lib/armv7e-m/fpu/libc.a(lib_a-exit.o):  In 
function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
/opt/gcc-arm-none-eabi-4_9-2015q4/bin/../lib/gcc/arm-none-eabi/4.9.3/../ 
../../../arm-none-eabi/lib/armv7e-m/fpu/libc.a(lib_a-sbrkr.o):  In 
function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
Was bewirkt diese Option, und die auch häufig angegebene 
--specs=nano.specs?

So, der Anfang wäre also gemacht. :-) Besten Dank an alle, die 
geantwortet haben. Aus jedem der Beiträge habe ich etwas entnommen, was 
mich weiter gebracht hat. Kann jemand etwas dazu sagen, was im 
startup-file und im Linkerscript geschieht?

Viele Grüße
Kruwakre

: Bearbeitet durch User
von Sebastian V. (sebi_s)


Lesenswert?

B. S. schrieb:
> Ich habe allerdings noch ergänzt: --specs=nosys.specs
> Was bewirkt diese Option, und die auch häufig angegebene
> --specs=nano.specs?

Die Option --specs=nosys.specs liefert wohl Definitionen für die 
Funktionen wie _exit und _sbrk. Das kann man aber auch selbst machen. 
_exit wird einfach eine Endlosschleife. _sbrk ist etwas schwieriger, da 
dies die Funkion ist wo malloc seinen Speicher her kriegt. Je nach 
Wunsch kann man hier Speicher vom internen RAM oder eventuell 
vorhandenem externen RAM liefern.

Die Option --specs=nano.specs wählt eine größenoptimierte Version der 
Standardlibrary aus. Dort fehlt dann z.B. Unterstützung für einige 
printf Formate, speziell für floating Point Werte.

von W.S. (Gast)


Lesenswert?

B. S. schrieb:
> Kann jemand etwas dazu sagen, was im
> startup-file und im Linkerscript geschieht?

Zumindest das Startupfile kannst du ja lesen. Dort stehen (meist) zu 
allererst die Vektortafel (siehe RefMan, dort: NVIC oder so) und dann 
die diversen Handler. Zuvörderst der Resethandler, der als 
Minimalfunktion deine main aufruft. Dazu gibt es für jeden Eintrag in 
der Vektortafel einen default-Handler, der als [WEAK] gekennzeichnet 
ist, damit er vom Linker ignoriert werden kann, sobald dieser einen 
gleichnamigen Handler in einem deiner Objektfiles entdeckt.

Meine Startupcodes schreibe ich mir immer selbst, sie sind etwas 
umfänglicher und letztlich komfortabler und sicherer. Siehe "B ." in 
Default-Handlern.

Die Linkerscripte beim GCC sind knöseliger als die beim Keil, den ich 
benutze. Du kannst aber mal den Vergleich zuehen, wenn du dir die 
Lernbetty herunterlädtst. Die ist sowohl per Keil als auch per Gcc 
übersetzbar und die entsprechenden Files (*.xcl) befinden sich auch 
dort. OK, die CPU's sind verschieden, aber das Prinzip beim Übersetzen 
ist gleich.

W.S.

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.