STM32F4 mit gcc-arm-none-eabi

#4540793
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
Gast #4540801
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.
Gast #4540854
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).
Gast #4540882
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".
Gast #4542414
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...
#4544190
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
#4544273
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.
Gast #4545097
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren