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
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.
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.
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.
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.
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.
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:
Da ich so ein Verhalten bei einem frischen, unveränderten Cube-Projekt noch nie beobachtet hab, kann man mit an Sicherheit grenzender Wahrscheinlichkeit davon ausgehen, daß es sich in diesem Fall um ein Hardware-Problem handelt.
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.
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.
Mit einem Hardfaulthandler kann man doch zumindestens rausfinden, welche konkrete Instruktion den Hardfault auslöst. Die eigentliche Ursache kann natürlich an anderer Stelle sein. Ich vermute subtil falsche Auswahl der Hardware in Cube.
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.
Heute wollte bei mir ein STM32L031 nicht loslaufen. Ursache war ein nicht richtig gelöteter SMD-Uhrenquarz bei in STM32CubeMX eingeschaltetem LSE-Oszillator. Der CPU-Takt kommt vom HSI-Oszillator.
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.