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 ?
ja, man kann die Fehlerursache abfragen. Such mal im Netz, es gibt fertigen Code der die Feehlerquelle per printf rausgibt.
Im Netz habe ich dazu nichts finden können. Verwendet hier jemand den HardFault Handler ?
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
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.
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]); |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.