Forum: Mikrocontroller und Digitale Elektronik HardFault Handler STM32F207


von Leo (Gast)


Lesenswert?

Guten Morgen,

in sämtlichen Beispielapplikationen wird ein HardFault Handler 
eingesetzt. Was ist eigentlich die Aufgabe eines solchen Handlers ? Wenn 
zum Beipiel ein Pointer auf eine falsche Adresse zeigt, wird dann der 
HardFault Handler angesprochen ? Gibt es eine Möglichkeit bei Eintreten 
eines solchen HardFault Handler die Ursache zu bestimmen ? Gibt es 
womöglich irgendwelche Fehlerzustände die man auslesen könnte ?

von ttl (Gast)


Lesenswert?

ja, man kann die Fehlerursache abfragen. Such mal im Netz, es gibt 
fertigen Code der die Feehlerquelle per printf rausgibt.

von Leo (Gast)


Lesenswert?

Danke für deinen Beitrag. Ich konnte im Netz bisher nichts finden.

von Leo (Gast)


Lesenswert?

Im Netz habe ich dazu nichts finden können. Verwendet hier jemand den 
HardFault Handler ?

von LTC1043 (Gast)


Lesenswert?

Leo schrieb:
> Im Netz habe ich dazu nichts finden können. Verwendet hier jemand den
> HardFault Handler ?

Dann ist wohl dein Google defekt.....

http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/

Gibt sicher auch noch andere Quellen für Infos.

Cheers

von Michael B. (michael_b93)


Lesenswert?

An dieser Stelle sei angemerkt, dass mit "Fehlerursache per printf 
ausgeben" hier nicht gemeint ist, dass dann dort steht: "Sie haben einen 
falschen Speicherbereich beschrieben", sondern du bekommst die aktuellen 
Registerwerte ausgegeben und vielleicht kannst du dir auch noch die 
aufrufende Codezeile ausgeben lassen (wenn dein Debugger das nicht 
sowieso tut).

Falls dir das sowieso klar war, dann bitte ich diesen Kommentar zu 
ignorieren.

von Leo (Gast)


Lesenswert?

Herzlichen Dank für eure Unterstützung.

von Roland H. (batchman)


Lesenswert?

Michael B. schrieb:
> An dieser Stelle sei angemerkt, dass mit "Fehlerursache per printf
> ausgeben" hier nicht gemeint ist, dass dann dort steht: "Sie haben einen
> falschen Speicherbereich beschrieben", sondern du bekommst die aktuellen
> Registerwerte ausgegeben und vielleicht kannst du dir auch noch die
> aufrufende Codezeile ausgeben lassen (wenn dein Debugger das nicht
> sowieso tut).

Es ist wesentlich mehr als die aktuellen Registerwerte. Je nach Fault 
wird in den Fault Status Registern ziemlich genau die Stelle 
beschrieben. Es kommt der Sache, die Du vermisst, ziemlich nahe.

Beispielsweise erzeugt einen "read from invalid memory adddress" einen 
synchronen Fault, so dass die Instruktion und die Zugriffsadresse exakt 
in den Statusregistern steht ("precise").

Beim Schreiben erzeugt er einen asynchronen Fault (wg. eines Puffers), 
der Fault schlägt ein paar Instruktionen später auf ("imprecise").

Beispiel für "read from invalid memory access"
1
ERR   Hard fault
2
ERR     R0   : 0x2000002a
3
ERR     R1   : 0x80035e1
4
ERR     R2   : 0x30000000
5
ERR     R3   : 0x30000000
6
ERR     R12  : 0x1000000
7
ERR     LR   : 0x8001e35
8
ERR     PC   : 0x8001e3a
9
ERR     xPSR : 0x61000200
10
ERR     CCR : 0x218 0b1000011000
11
ERR       Bit 3: Trap unalign    : 1
12
ERR       Bit 4: Trap div by zero: 1
13
ERR       Bit 9: Stack align     : 1
14
ERR     SHCSR: 0x0 0b0
15
ERR       Bit 0: Mem fault  : 0
16
ERR       Bit 1: Bus fault  : 0
17
ERR       Bit 3: Usage fault: 0
18
ERR     CFSR : 0x8200 0b1000001000000000
19
ERR      UFSR: 0b0
20
ERR       Bit 16: Undef instr: 0
21
ERR       Bit 17: Inv state  : 0
22
ERR       Bit 24: Unaligned  : 0
23
ERR       Bit 25: Div by zero: 0
24
ERR      BFSR: 0b10
25
ERR       Bit  8: Instr bus error   : 0
26
ERR       Bit  9: Precise           : 1
27
ERR       Bit 10: Imprecise         : 0
28
ERR       Bit 15: BFAR contains addr: 1
29
ERR      MFSR: 0x0
30
ERR       Bit 0: Instr access violation: 0
31
ERR       Bit 1: Data access violation : 0
32
ERR       Bit 7: MFAR contains addr    : 0
33
ERR     HFSR : 0x40000000 0b1000000000000000000000000000000
34
ERR       Bit 30: Escalation to hard fault: 1
35
ERR     DFSR : 0x9 0b1001
36
ERR       Bit 0: Halted: 1
37
ERR       Bit 1: BKPT  : 0
38
ERR       Bit 3: VCATCH: 1
39
ERR     AFSR: 0x0 0b0
40
ERR     Mem fault addr MMFAR: 0x30000000
41
ERR     Bus fault addr BFAR : 0x30000000

"PC" zeigt die Adresse des Befehls,
"Precise" sagt aus, dass diese Adresse exakt stimmt.
"BFAR contains addr" sagt aus, das im BFAR exakt die Zieladresse des 
Zugriffes steht.

Diese Fehlerrückmeldung sind m. E. einer der wichtigsten Dinge bei einer 
µC-Architektur (beim PIC32 sind das m. W. die "Exceptions").
Wichtig ist, dass diese Fehler einen Fault auslösen, und dass dieser 
angezeigt werden kann. Es ist ziemlich gefährlich, wenn der µC einfach 
weitermacht, und (viel) später auf die Nase fällt.

Das Thema hat eine gewisse Komplexität. Der initiale Aufwand lohnt sich, 
da man mittelfristig ein Werkzeug zur Hand hat, das m. A. nach wichtiger 
als ein Debugger ist - denn dieser hängt im Zweifel nicht am µC, wenn es 
knallt.

Beim CM0 ist das sehr viel reduzierter (Statusregister), so dass es sich 
lohnt, während der Entwicklung einen CM3/CM4 einzusetzen. Beim letzteren 
kommen noch weitere Statusregister für die FPU dazu.

LTC1043 schrieb im Beitrag #2989639:
> Gibt sicher auch noch andere Quellen für Infos.

Die (und ich) haben vermutlich alle von Joseph Yiu abgeschrieben, 
welcher "The Definitive Guide to the ARM Cortex-M3" geschrieben hat.

Das sieht man daran, dass in der Deklaration "unsigned int" verwendet 
wird, aber beim cast "unsigned long". Das ist beim 32-Bitter das 
gleiche, es wäre aber ziemlich zufällig, dass dies nicht durch "Copy & 
Paste" enstanden ist :-)
1
  unsigned int stacked_r0;
2
  unsigned int stacked_r1;
3
  unsigned int stacked_r2;
4
  unsigned int stacked_r3;
5
  unsigned int stacked_r12;
6
  unsigned int stacked_lr;
7
  unsigned int stacked_pc;
8
  unsigned int stacked_psr;
9
 
10
  stacked_r0 = ((unsigned long) hardfault_args[0]);
11
  stacked_r1 = ((unsigned long) hardfault_args[1]);
12
  stacked_r2 = ((unsigned long) hardfault_args[2]);
13
  stacked_r3 = ((unsigned long) hardfault_args[3]);

von Leo (Gast)


Lesenswert?

Um einen HardFault auszulösen, habe ich den Empfangspuffer für die 
ankommenden seriellen Daten verkleuinert. Nun wird der HardFault 
ausgelöst. Wie sind nun die hardfault_args zu interpretieren ?

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.