Forum: Mikrocontroller und Digitale Elektronik STM32 HardFault_Handler


von noob (Gast)


Lesenswert?

Hi Leute,
ich habe ein source code fabriziert der nach einer weile in die 
HardFault_Handler() funktion springt. jedoch weiss ich nicht was das 
verursacht könnt ihr mir einige tipps geben wie ich das debuggen kann?
ich benutze IAR 5.30 und die standard lib 3.3.0 ,der controller ist der 
stm32f103cb.
ich habe einiges dazu im internet gefunden leider war nix dabei was mir 
wirklich weiter geholfen hat.

danke!

von Michael A. (schopf16)


Lesenswert?

Arbeitest du mit einem RTOS?
Kommt der Hard-Fault immer zur gleichen Zeit oder variiert die Zeit?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Der Spring da rein wenn man aus irgend einem Grund auf einer Adresse was 
lese/schrieben möchte, auf der weder Flash noch Ram und auch keine 
Pheriperie ist.

Vermutlich hast Du ein Zeiger, der irgend wo was lesen/schreiben soll 
(z.B. Index-Variable eines Arrays, das einen falschen viel zu großen 
Wert hat und somit ins nirvana Zeigt.

PS: Ich mag diese Fehlermeldung auch nicht, da man nicht weiß an welcher 
Programmposition das auftrat. Zumindest habe ich das noch nicht 
herausgefunden.

von noob (Gast)


Lesenswert?

HI Leute,
WOW das ging ja schnell. Also es ist kein RTOS. und Ja der Code bleibt 
jedesmal an der selben Stelle stehen.
Aber es muss doch eine Möglichkkeit geben das problem irgendwie zu 
finden oder?

von noob (Gast)


Lesenswert?

im moment habe ich ein "workaround" geschaffen in dem ich die Funktion 
NVIC_SystemReset() jedesmal aufrufe, wenn ich in den Handler gerate, 
jedoch würde ich gern herausfinden was die Ursache für den Handler ist

von (prx) A. K. (prx)


Lesenswert?

Es gibt ein paar System Exceptions, die je nach Einstellung von 
Prioritäten nicht im dafür vorgesehenen Handler sondern automatisch im 
Hardfault-Handler landen. Stellt man die anders ein, dann weiss man 
schon mehr, nämlich welche Exception es wirklich war.

Ausserdem ist es nicht so, dass man im Handler komplett ahnungslos ist. 
Die Returnadresse ist bekannt, so dass man rauskriegt an welcher 
Programmposition man rausflog. Bei MemFaults kriegt an zudem raus, um 
welchen Zugriff es sich handelte.

Das kann man beispielsweise über einen Debugger ermittelt. Manche 
schreiben sich aber auch einen komplexen Fault-Handler, der alle 
relevante Information einsammelt und irgendwohin dumpt.

von Hannes S. (Gast)


Lesenswert?

Ein Hardfault ist eigentlich auch "nur" ein Interrupt. Das bedeutet, 
dass sich auf dem Stack auch die Rücksprungadresse befindet. Und das ist 
auch in etwa die Adresse, an der die Anweisung zu finden ist, welche den 
Hardfault ausgelöst hat. Ganz genau passt das manchmal nicht, da die CPU 
(sofern sie noch in der Lage dazu ist) ganz gern mal schon noch die 
nächsten paar Befehlt ausführt, bis sie merkt, dass da ein Hardfault 
war.

Aber trotzdem hilft es schonmal sehr viel im Hardfault Handler die CPU 
anzuhalten und an SP+24 nachzuschauen: In der Nähe der dort zu findenden 
Adresse wurde der Hardfault ausgelöst.

von (prx) A. K. (prx)


Lesenswert?


von noob (Gast)


Lesenswert?

an  Hannes S.: also ich stoppe den Debugger und kann jetzt wo 
nachschauen
               was in SP+24 steht?
               ich habe unter IAR die Möglichkeit mir den CSTACK 
anzuschauen.
               wenn du das damit meinst, steht da jetzt eine Tabelle:

              Location    |    Data
              0x20000390  |    0x08
                  +1      |    0x00
                  .       .      .
                  .       .      .
                  .       .      .
                +24       |    0x54
   und was sagt mir das jetzt? sorry aber da fehlt mir einfach das know 
how.

an   A. K.:
also diesen thread habe ich mir jetzt angesehen und da steht was von 
"void hard_fault_handler_c(unsigned int * hardfault_args)" aber ich habe 
unter stm32f10x_it.c eine funktion die keine übergabe parameter hat 
sondern nur void: void HardFault_Handler(void)

jetzt könnte ich das mit dem C code einfach kopieren aber wie sieht es 
mit dem assembler bereich aus wie kann man dem jetzt die parameter 
übergabe beibringen. wenn ich mich jetzt nicht irre müsste doch im 
startup_stm32f10x_md.s die folgenden Zeilen irgendwie abgeändert werden:
        PUBWEAK UsageFault_Handler
        SECTION .text:CODE:REORDER(1)
UsageFault_Handler
        B UsageFault_Handler

von Hannes S. (Gast)


Lesenswert?

Yep, das CSTACK Fenster ist schonmal richtig. Jetzt musst Du nur noch 
den Wert aus +27 bis +24 auslesen, beginnend bei +27 und Dir dann eine 
Adresse draus bauen. Wahrscheinlich dürfte in +27=0x08 und
26=0x00 drinstehen. Das würde dann 0x0800xx54 bedeuten. Diese Adresse 
suchst Du nun im Disassambly Window. Und schon bist Du an der Stelle, an 
der das Unglück seinen Lauf nahm...

Ach ja: Im Hardfault Handler sollte kein Code drinstehen, der ein 
sichern eines weiteren Registers auf dem Stack bedingt, denn dadurch 
würde sich die Adresse verschieben. Sicherheitshalber also nur ein 
__no_operation() in den Handler und dann den Brakpoint drauf.

von noob (Gast)


Lesenswert?

danke das werd ich mal ausprobieren

von noob (Gast)


Lesenswert?

also ich habe mal nachgeschaut und habe da jetzt folgende adresse

   Location       |     Data
    0x20000390    |     0x08
       .          .      .
       .          .      .
       .          .      .
      +24         |     0x54
      +25         |     0xF6
      +26         |     0x0B
      +27         |     0xAC

also müsste ich auf 0xAC0BF654 ist das so richtig? Wie kommst du 
eigentlich auf +24 bis +27?
und ist es normal das der inhalt (spalte Data) sich jedesmal ändert?

von (prx) A. K. (prx)


Lesenswert?

Mit etwas Glück und IARs Hilfe übernimmt diese Suche nach den Registern 
und deren Decodierung dein Debugger bereits selbst. Jedenfalls tut das 
der von Keil:
http://www.keil.com/appnotes/files/apnt209.pdf

von noob (Gast)


Lesenswert?

ja soetwas wie auf seite 14 deiner pdf Datei hat es auch aber wenn ich 
nach 0xAC0BF654 suche dann findet er nix bzw stürtzt ab

von Hannes S. (Gast)


Lesenswert?

An 0xAC0BF654 existiert kein Flash/RAM. Der Sprung an diese Adresse 
dürfte dann auch der Grund für den Hardfault sein. Wieso das passiert? 
Mir fällt da eigentlich nur ein Nicht/falsch initialisierter 
Funktionspointer ein. Allerdings kann man in diesem Fall nicht so 
einfach sagen, wo das passiert ist.

Wie ich auf +24 komme? Das ergibt sich aus der Sicherung der Register 
bei jedem Aufruf eines Interrupts:
SP+0: R0
  +4: R1
  +8: R2
 +12: R3
 +16: R12
 +20: LR
 +24: PC
 +28: xPSR

Wie schon gesagt: Sofern nötig, veranlasst der Compiler noch die 
Sicherung weitere Register. Dies hängt vom Code im Handler ab.

Wenn der komplette Code im Flash liegt, sollten PC und LR immer Adressen 
beginnend mit 0x080xxxxx enthalten.

von noob (Gast)


Lesenswert?

Hi,
ich bins nocheinmal.
ich wollte mich für die infos bedanken.
hab den fehler jetzt gefunden.

von Arne (Gast)


Lesenswert?

Hallo noob,

mir scheint es, als ob ich ein ähnliches Problem habe.
Magst zu posten, wo Dein Problem lag?

von D. R. (misterdimi1992)


Lesenswert?

Hallo zusammen,

wollte nochmal an den Thread anknüpfen, da ich gerade ein ähnliches 
Problem habe.

Kommt man nur mit IAR in den SP+24? Oder ist das auch mit Eclipse 
möglich?

: Bearbeitet durch User
Beitrag #7198426 wurde von einem Moderator gelöscht.
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.