Forum: Mikrocontroller und Digitale Elektronik STM32 HardFault_Handler


von Florian D. (dunst11)


Lesenswert?

Hallo ich arbeite derzeit mit einem STM32L476 Nucleo und habe schon seit 
einiger Zeit nicht mehr mit STM gearbeitet. Deshalb gleich mal ein 
Tutorial gestartet 
(http://www.carminenoviello.com/2015/01/07/setting-gcceclipse-toolchain-stm32nucleo-part-2/). 
Als Beispiel wurde ein LED-Blinker Beispiel aus der CubeHAL library 
verwendet. Also extra für dieses Nucleo Board.

Nun mein Problem: Beim Debugging mit OpenOCD und GDB komme ich nicht ins 
main sondern direkt in in den HardFault_Handler.

Die Consolenausgabe:

Info : dropped 'gdb' connection
Info : accepting 'gdb' connection on tcp/3333
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
adapter speed: 480 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800029c msp: 0x20020000
adapter speed: 4000 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
adapter speed: 480 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800029c msp: 0x20020000
adapter speed: 4000 kHz
Info : Padding image section 0 with 8 bytes
Info : Padding image section 1 with 1 bytes
Warn : Padding 4 bytes to keep 8-byte write size
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000050 msp: 0x20020000
Warn : block write succeeded
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
adapter speed: 480 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800029c msp: 0x20020000

Laut Disassembly ist 0x0800029c der Reset_Handler. Es waren bereits 
ähnliche Probleme auf µC.net aber dort stand der pc meist irgendwo im 
Nirvana und nicht in den Flashbereich. Weiters bekomme ich auch noch den 
Fehler: No source available for "<signal handler called>() at 
0xfffffff9" wenn ich den GDB pausiere. Ich weiß leider nicht wo hier der 
Fehler liegt. Vielleicht kann mir jemand weiterhelfen

von Florian D. (dunst11)


Lesenswert?

Achja, so wie die Toolchain nach dem Tutorial aufgebaut war, gab es kein 
direktes Template für die L4 Familie. Deshalb das Testprojekt nach 
dieser Anleitung 
(http://www.carminenoviello.com/2015/06/04/stm32-applications-eclipse-gcc-stcube/) 
eingerichtet.

Vielen Dank schon mal...

: Bearbeitet durch User
von Bernardo F. (bernardo)


Lesenswert?

Hallo Florian,
in section 0 werden 8 Bytes geladen, vermutlich der Stackpointer und der 
Resetvektor. Genaueres kann man durch einen Blick ins Linkerfile 
herausbekommen, wo die Reise für section 0 hingeht. Alternativ genügt 
ein Blick mit dem gdb auf die beiden 32-Bit-Worte des Prozessors ab 
Adresse 0x0 oder 0x08000000 (beim 2. Wort muss das LSB gesetzt sein 
wegen Thumb-Code).
Merkwürdig ist dann section 1: geladen wird nur 1 Byte, das war's. Was 
aber nicht verständlich ist, da Thumb-Code 16- oder 32-Bit codierter 
Code ist. Es müssten also mindestens 2 Bytes geladen werden, im 
Normalfall sogar viel mehr. Das Programm wird also m.E. einfach nicht 
(richtig) übertragen. Stimmt das Linkerfile und die Zuteilung der 
Programmteile zu den sections?
Viele Grüße
Bernardo

von Florian D. (dunst11)


Lesenswert?

Hallo Bernado,

danke für die Antwort. Ich werde mir die erwähnten Punkte Heute 
Nachmittag anschauen und werde meine Erkenntnisse dann hier posten.

Grüße Florian

von Florian D. (dunst11)


Lesenswert?

Habe mir das Ganze mal angesehen. Ich kenn mich leider nicht wirklich 
aus mit den linker-scripts. Insgesamt habe ich in der Projektstruktur 3 
Scripts. Wobei libs.ld nicht wirklich Code enthält. Dann gibt es noch 
mem.ld und sections.ld. Im Tutorial wurde bei mem.ld die Flashgröße und 
RAM-Größe sowie die Startadressen auf die MCU meines Nucleo's verändert. 
Ansonsten sind die Files so verblieben wie sie bei einem leeren ARM 
Cortex template erstellt werden.

Ich hätte die Linker files sowie den startup hier gepostet:
https://pastebin.com/WFhHbS1t (mem.ld)
https://pastebin.com/zxnUs2Hh (sections.ld)
https://pastebin.com/C66HqzuZ (startup_stm32l476xx.s)

Vielen Dank für die Hilfe soweit.

: Bearbeitet durch User
von dFa (Gast)


Lesenswert?

Mapfile wäre noch sinnvoll
($ gcc foo.o bar.o -Wl,-eENTRY -Wl,-Map=a.map)

von Bernardo F. (bernardo)


Lesenswert?

Die Linkerfiles sehen "normal" aus: der Speicher wird nach Definition in 
sections.ld in die sections .isr_vector, .inits ... unterteilt und nach 
FLASH (in mem.ld definiert) gelegt. Ein zusätzliches Map-File wäre 
sicherlich nicht verkehrt.

Vermutlich wird also das Programmierfile nicht richtig erzeugt, dieses 
sollte man sich mal ansehen. Dazu kann man die elf-Datei in eine Intel 
HEX-Datei umwandeln (z.B. mit dem Befehl "arm-none-eabi-objcopy -O ihex 
foo.elf foo.hex") und sich den ASCII-Inhalt von foo.hex einmal ansehen. 
Da stehen auch die zu programmierenden Speicheradressen drin und sollten 
dann wesentlich mehr als nur ein paar Zeilen sein. Falls nicht, wird das 
Programmierfile schon nicht richtig erzeugt.

von Florian D. (dunst11)


Angehängte Dateien:

Lesenswert?

Guten Morgen,

hab nun nach dem Wochenende nochmal die genannten Punkte angesehen. Ein 
Map-File hätte ich erstellt. Ebenso habe ich mir das elf file und das 
hex file angesehen. Bei mir wurde sowieso ein hex file erzeugt also habe 
ich den von Bernardo genannten Befehl nicht verwendet. Ich hoffe das hex 
file stimmt so. Ja es sieht nach mehr Zeilen aus, allerdings bin ich für 
die Fehlersuche eigentlich noch nie so "tief" gegangen und kann es 
schlecht beurteilen. Ich hätte die Files wieder angehängt. Ich würde 
mich sehr freuen wenn mir auch jemand erklärt welche wichtigen 
Information ich aus den Files an welchen Stellen rausholen kann, damit 
ich es für das nächste mal weiß.

Vielen Dank soweit :)

von Florian D. (dunst11)


Angehängte Dateien:

Lesenswert?

Ich habe zur Sicherheit auch noch ein Intel-hex erstellt, da ich nach 
einer kurzen Googlesuche denke, dass das file vl. etwas anders ist als 
das erstellte hex file.

von Bernardo F. (bernardo)


Lesenswert?

Hallo Florian,

jetzt hab ich es mir mal angesehen: zunächst sind beide hex-Files 
identisch, der Befehl diff bringt keinen Unterschied. Nach dem manuellen 
Programmieren der elf-Datei und dem Auslesen der ersten zwei Worte bei 
0x0 kommt bei mir Folgendes:

(gdb) load
Loading section .isr_vector, size 0x3a0 lma 0x8000000
Loading section .inits, size 0x28 lma 0x80003a0
Loading section .text, size 0x185b lma 0x80003d0
Loading section .data, size 0x78 lma 0x8001c2c
Start address 0x8000188, load size 7323
Transfer rate: 17 KB/sec, 1830 bytes/write.

(gdb) x/2 0x0
0x0:  0x20020000  0x0800029d  <Reset_Handler>

Nach Ausführen der ersten Assemblerinstruktion
   0x0800029c <+0>:  push  {r3, lr}
wird der HardFault_Handler aufgerufen und im Configurable Fault Status 
Register unter 0xE000ED28 ein Imprecise Data Bus-/BusFault on Stacking 
Error (0x00001400) angezeigt. Letzteres ist auch nicht verwunderlich, da 
der main stack pointer auf 0x20020000 gesetzt wird, dieser 
Speicherbereich aber nicht mehr im 96k-SRAM1 (0x20000000-0x20017FFF), 
sondern in einem reservierten Bereich liegt.

Im Linkerfile mem.ld wird aber eigentlich der richtige Bereich 
adressiert, in LED_Blinker.map steht aber dann der falsche Wert drin, 
siehe __stack und _estack. Daher meine Frage: ist es sicher, dass das 
(modifizierte) mem.ld zum Linken überhaupt verwendet wird?

Viele Grüße
Bernardo

: Bearbeitet durch User
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.