STM32 startet im HardFault

OP #7464666
Lesenswert?

Guten Tag euch allen,

ich habe hier eine Platine mit einem STM32L562CEU6 (Cortex M33) die immer im HardFault_Handler startet. Platine ist selbst designed und wird über den ST-Link eines Nucleo L152RE programmiert/debugged. Programmiert wird in CUBE-IDE Version: 1.13.0. Flashen/Auslesen mit CUBE-Programmer funktioniert, Optionbytes auslesen etc. alles kein Problem, nur das Programm läuft nicht.

Dinge die ich bereits probiert habe:

  • leeres Projekt erstellt und nur PB11 und PA15 als output Push/Pull definiert (keine weiteren Äderungen)
  • Spannungsregler runter gelötet und direkt 3,3V vom Labornetzteil dran gelötet (Ausschließlich der Core wird versorgt)
  • Geschwindigkeiten (Core und SWD) verringert
  • Chip getauscht
  • GND und VDD Pads gecheckt ob die verbunden sind (außer das GND-Pad unter dem Controller)

gelegentlich komme ich zu einem Breakpoint in der startup_stm32l562ceux.s in Zeile 62 und kann sogar 2 Schritte weiter steppen. In der stm32l5xx_it.c ist aber spätestens schluss in Zeile 217 ("SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */") und ich lande im HardFault_Handler.

Die Debugregister bringen mich nicht wirklich weiter (siehe Anhang). Ich denke es ist irgendeine Kleinigkeit die konfiguriert werden muss, was ich natürlich nicht gemacht habe.

Vielen dank schonmal an alle die sich mit dem Problem befassen

Angehängte Dateien:
Gast #7464837
Lesenswert?

A.P. W. schrieb:

Stackpointer nicht initialisiert, und zeigt dann bei der nächsten Stack-Operation auf einen unerlaubten/ungültigen Bereich =>BusFault?

Ja. Kann sein.

Timo schrieb:

In der stm32l5xx_it.c ist aber spätestens schluss in Zeile 217 ("SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */") und ich lande im HardFault_Handler.

Kannst du den Startup code mal anhängen inklusive der Vektortabelle + Linkerscript? Ohne, dass ich den Code jetzt sehe klingt es so, als würde der Startupcode ja ein Stück weit anlaufen.

@TO: Kannst du im Debugger mal einen Screenshot von den Core registern des Cortex machen?

Tritt das Problem nur beim "selbstständigen" booten also nach Power on reset auf, oder auch, wenn du es über den Debugger lädst und dann direkt loslaufen lässt?

Das wird es vermutlich nicht sein, aber ich hatte mal Probleme mit meinem in C geschrieben Startupcode für den STM32F4. Sobald die Optimierung -O2 oder größer an war, ist der Startupcode gecrasht. Lag im Endeffekt daran, dass der Startupcode in C geschrieben war und mit float abi hard compiliert war. GCC hat dann die Kopierschleife, die die .data Section vom Flash in den RAM kopiert mit FPU mov Befehlen angereichert, weil die höheren Durchsatz erreichen. Das ist dann gewaltig schiefgegangen, weil die FPU zu diesem Zeitpunkt noch nicht aktiviert war. Lösung war dann entweder die FPU frühzeitiger zu aktivieren, oder den Startupcode mit mit softfpu ABI zu kompilieren.

OP #7465096
Lesenswert?

Danke euch beiden für die Hilfe,

hier die Linkerscripte, die Startup, alle Register direkt nachdem der Controller in den Hardfault gelaufen ist und die main.c. Der code ist komplett von CUBE IDE generiert, daher wundert mich der Fehler so sehr.

bzgl. des Vectortables: Ist das die *.map datei?

edit: @M. H. das Problem tritt mit und ohne debugger auf, einmal bin ich jetzt ein paar Schritte weiter gekommen bis sich der Hardfault gemeldet hat. Dies ist passiert nachdem ich von -O0 auf -Og umgestellt habe, lässt sich jetzt aber nicht reproduzieren.

Angehängte Dateien:
OP #7465153
Lesenswert?

Auch Software verhält sich manchmal unvorhersehbar, insbesondere wenn man das gleiche teil mehrfach flasht und Reste zurück bleiben. Reproduzierbarkeit des weiterkommens ist jetzt gegeben.

Weitere info:

  • Chiperase und dann neu programmieren lässt wenigstens etwas an Code laufen: mit O0 wie im ersten Post beschrieben bis "SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */"
  • Neustart mit debugger überspringt den Breakpint, endet aber an der gleichen Stelle. <-- daher habe ich angenommen der Code wird nicht ausgeführt.
  • Og, O1 und O2 läuft immer bis Zeile 96 "bl __libc_init_array" unabhängig vom Chiperase. Beim Neustart wird der Breakpoint in Zeile 62 "ldr sp, =_estack /* set stack pointer */" übersprungen; nach Chiperase oder Änderung der Optimierung hält der Controller hier an. Weitere habe ich nicht getestet, kann das aber gerne noch machen falls es hilft.
#7465171
Lesenswert?

Timo schrieb:

Dinge die ich bereits probiert habe:

  • leeres Projekt erstellt und nur PB11 und PA15 als output Push/Pull definiert (keine weiteren Äderungen) ...
  • Geschwindigkeiten (Core und SWD) verringert

Ich verwende nicht die CUBE-IDE - vielleicht eine blöde Frage: Wurde dieser Test auch wirklich mit der HSI-Clock gemacht? Ein unsauberer externer Oszillator führt ja irgendwann auch zum Hardfault.

OP #7465176
Lesenswert?

Jopp, habe mit MSI RC und HSI RC getestet. Dabei habe ich 4, 16, 48 und 110 MHz Coretakt eingestellt (nachdem ich das leere Projekt ohne weitere Änderungen getestet hatte)

p.s.: alle o.g. Tests sind mit dem leeren Projekt gemacht. Das Projekt für die Platine mit der ganzen Perepherie habe ich nicht weiter verwendet.

#7465223
Lesenswert?

Danke, hätte ich mir eigentlich selber beantworten können. Die CPU schafft nicht mal immer die allererste Instruktion:

Timo schrieb:

gelegentlich komme ich zu einem Breakpoint in der startup_stm32l562ceux.s in Zeile 62 und kann sogar 2 Schritte weiter steppen

Es muss an der Hardware liegen. Kann man das nicht weiter eingrenzen bis nur der nackte Controller bleibt? Beispielsweise nur eine blinkende LED und ohne angeschlossenem Debugger bzw. sonstiger Hardware. Tritt der Fehler trotzdem auf, dann bleibt nicht viel als Ursache übrig:

  • n x VSS
  • n x VDD
  • VSSA
  • VDDA
  • BOOT0
  • NRST
#7465329
Lesenswert?

Harry L. schrieb:

kann man mit an Sicherheit grenzender Wahrscheinlichkeit davon ausgehen, daß es sich in diesem Fall um ein Hardware-Problem handelt.

Es gibt immer genügend Gründe warum man seine Hardware nicht zeigen möchte, z.B.:

  • "meine Hardware ist fehlerfrei"
  • die Hardware ist so schlecht dass man sie nicht herzeigen kann
  • die Community könnte ja eine Fehler finden und man steht dann blöd da.
  • die Hardware enthält solch geniale Schaltungsteile dass man sie vor Nachbau schützen muss.
OP #7465849
Lesenswert?

Sry, dass ich bisher nicht geantwortet habe, private Verpflichtungen und so.

Ich habe bisher sämtliche Pegel+Dreck auf allen Pins gemessen, außerdem werde ich nochmal eine Platine mit AUSSCHLIEßLICH Prozessor und Blockkondensatoren bestücken.

Ergebnisse und die viel gewünschte Ansicht der Hardware kommt morgen.

Moderator (Firma: Titel) Persönliche Seite #7466000
Lesenswert?

Wastl schrieb:

Nicht reproduzierbare Software-Fehler können häufig auf unzuverlässige Hardware zurückzuführen sein.

Ich kenne das eher andersrum.

Timo schrieb:

Dreck auf allen Pins gemessen

Miss auch mal "Masse gegen Masse" quer über die Platine. Da müsste eine Linie auf 0V herauskommen. Manchmal sieht man da überraschenderweise wesentlich mehr.

#7473694
Lesenswert?

Timo schrieb:

Ergebnisse und die viel gewünschte Ansicht der Hardware kommt morgen.

Wir warten ..... jetzt schon mehr als eine Woche, so lang kann es dauern bis "morgen" gekommen ist. Das ist wohl ein sehr dehnbarer Begriff.

Was mögen wir daraus für Schlussfolgerungen ziehen? Vielleicht die bereits vermuteten?

Wastl schrieb:

Es gibt immer genügend Gründe warum man seine Hardware nicht zeigen möchte, z.B.: ............

#7473977
Lesenswert?

Es gibt für Cortex im xPSR aus historischen Gründen ein T Bit wo den Thumb only Befehlssatz freischalten muß. Wenn das vom Debugger her nicht gesetzt wird, fliegt die Kiste gleich beim allerersten Befehl auf die Fresse weil sie den Code als 32 bit ARM ausführen will was aber bei Cortex freilich gar nicht implementiert ist. Den Debugger von Cube kenne ich leider nicht, ich weis nur daß dies einige andere nicht von alleine machen. Mit Segger Ozone aber kein Problem.

Gast #7474904
Lesenswert?

J. V. schrieb:

Es gibt für Cortex im xPSR aus historischen Gründen ein T Bit wo den Thumb only Befehlssatz freischalten muß. Wenn das vom Debugger her nicht gesetzt wird, fliegt die Kiste gleich beim allerersten Befehl auf die Fresse weil sie den Code als 32 bit ARM ausführen will was aber bei Cortex freilich gar nicht implementiert ist. Den Debugger von Cube kenne ich leider nicht, ich weis nur daß dies einige andere nicht von alleine machen. Mit Segger Ozone aber kein Problem.

Das sollte sich bei korrekter Vektortabelle automatisch erledigen. Bei jedem indirekten Sprung, wird, da die Befehlsadressen nur Wort-aligned sein können, in das LSB der Adresse eine 1 für Thumb-Mode geschrieben. Das LSB wir vom Cortex beim Laden der Instruktion ignoriert, aber dieses signalisiert ihm, dass das Ziel im Thumb-Mode zu interpretieren ist. Sonst würde ohne Debugger ja kein Code anlaufen...

Angehängt meine Vektortabelle eines STM32F407 (Cortex M4): Der Resetvector (Adresse 0x08000004) enthält: 0x0800b62d (little endian). Wie man aber am zweiten Screenshot erkennen kann, liegt der reset-Vector an Adresse 0x0800b62c.

Angehängte Dateien:

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