Hallo Leute! Ich frage mich gerade, was man (ganz Allgemein) bei einem Hard Fault eines Cortex-M4 (oder -M3) noch machen kann. Klar, man kann sich im Hard Fault Handler den Stack Frame und damit den Program Counter etc. sowie verschiedene Statusregister zu dein einzelnen Faults anschauen. Aber was bleiben dann noch für Möglichkeiten zu einer vernünftigen "Lösung" des Problems übrig? * Fehlermeldung bspw. an den PC per USB ausgeben: Funktioniert nicht, da USB auf Interrupts angewiesen ist (zumindest das von mir verwendete Modul vom Atmel Software Framework) und diese Interrupts nicht ausgeführt werden, da sie eine niedrigere Priorität als der Exception Handler haben. * Softwarereset des Controllers: Funktioniert nicht, falls Reset-Pin extern beschalten ist und auf High gezogen wird. Was sagen die Profis zu dem Thema? Gibt es Ideen, was an Maßnahmen überhaupt möglich ist? Ich habe leider kein konkretes Anwendungsszenario, deswegen musste ich meine Fragestellung so allgemein halten ;) Vielen Dank schon mal :)
Andi K. schrieb: > Aber was bleiben dann noch für Möglichkeiten zu einer > vernünftigen "Lösung" des Problems übrig? Normerweise kriegst du den Hard Fault, wenn es keine vernünftige Lösung mehr gibt. Aber drauf achten, dass in Standardeinstellung ein paar andere Faults nicht selbst auftreten, sondern effektiv auf dem Hard Fault gemappt werden. Das kann man ändern.
Andi K. schrieb: > * Softwarereset des Controllers: Funktioniert nicht, falls Reset-Pin > extern beschalten ist und auf High gezogen wird. Gegen Konstruktionsfehler ist kein Kraut gewachsen. Der Reset Pin sollte OC/OD beschaltet werden.
>* Fehlermeldung bspw. an den PC per USB ausgeben: Funktioniert nicht, da >USB auf Interrupts angewiesen ist Man kann Fehlermeldungen per UART ausgeben da man den auch ohne Interrupt benutzen kann.
Andi K. schrieb: > * Softwarereset des Controllers: Funktioniert nicht, falls Reset-Pin > extern beschalten ist und auf High gezogen wird. Bei welchem Controller? NVIC_SystemReset() sollte überall funktionieren, das ist ein internes Signal. Es gibt auch noch ein VECTRESET Bit, das nur den Core selbst resettet - aber das will man praktisch nie.
Andi K. schrieb: > Fehlermeldung bspw. an den PC per USB ausgeben: Funktioniert nicht, da > USB auf Interrupts angewiesen ist Doch das funktioniert: 1. Zwei Stacks verwenden: PSP für den Task und MSP für die Handler (also auch Interrupts) 2. Aus dem Hard Fault Handler (MSP) zu einer Speicherstelle mit SVC zur Fehlerbehandlung "zurückkehren" 3. Im SVC Handler (MSP) die USB Ausgabe machen. Abgesehen davon sollte vor dem Hard Fault noch der MemManage Fault implementiert werden, meistens läuft nämlich "nur" der Stack über.
Der Hardfault tritt auch sehr schnell bei zu hoher Frequenz auf, wenn man sich mal mit der PLL vertut ;)
Andi K. schrieb: > Aber was bleiben dann noch für Möglichkeiten zu einer > vernünftigen "Lösung" des Problems übrig? Das hängt von deiner Anwendung ab. In den meisten Fällen benutzen die Anfänger im Programmieren eben den Startup-Code, den sie als Default bei der IDE ihrer Wahl eben so vorfinden. Und so führt jeder blöde Fehler (NMI, Hardfault, Spurious, Data Abort und so weiter je nach konkreter CPU) zu einem "B ." was m.M.n. die dümmste aller Varianten ist. Ich mache das zumeist so, daß jeder dieser unabgedeckten Interrupts das ganze System neu startet, also einen Warmstart auslöst. Obendrein setze ich noch ein Fehlerflag, so daß später in main bei Bedarf nachgeschaut werden kann, was denn passiert war. Auf diese Weise kommt der µC wenigstens wieder so gut es geht auf die Beine und spielt nicht toter Mann. Also: alle [weak] Interrupts bei dem fertigen Projekt abfangen und ggf. nen Neustart auslösen. Für evtl. Debugging zuvor kann man es hingegen halten wie man will. W.S.
W.S. schrieb: > In den meisten Fällen benutzen die Anfänger im Programmieren eben den > Startup-Code, den sie als Default bei der IDE ihrer Wahl eben so > vorfinden. Und genau das kann man auch behalten, wenn man die Faults behandeln will. Das muss man nämlich nicht in Assembler und auch nicht im Startupcode tun. Außerdem ist ein Fault ein Programm-Fehler und nicht eine temporäre Befindlichkeit des Prozessors. Daher sollte man die in vielen Anwendungen nicht einfach ignorieren und neu starten, sondern die Hardware in einen sicheren Zustand bringen und dann doch in Endlosschleife stehen bleiben. Wenn es für das Funktionieren deiner Geräte unerlässlich ist, bei einem Fehler neuzustarten, solltest du vielleicht mal überlegen die tatsächlichen Fehler im Code zu korrigieren ...
W.S. schrieb: > Ich mache das zumeist so, daß jeder dieser unabgedeckten Interrupts > das ganze System neu startet, also einen Warmstart auslöst. und zwar nicht sofort, sondern nach einigen Sekunden bis zu etlichen Minuten. In der Zwischenzeit wird eine mehr oder weniger ausführliche Fehlermeldung ausgegeben, wenigstens mit LED-Blinkcode. Falls der Fehler wiederholt auftritt, müsste man das eigentlich beim Startup abfangen. Ansonsten kann so eine Pause das Gerät vor allzu großem Dauerstress bewahren.
Schaulus Tiger schrieb: > und zwar nicht sofort Das hängt - wie bereits geschrieben - von der konkreten Anwendung ab. Es gibt ne Menge Anwendungen, wo es verdammt wichtig ist, zu allererst mal einen möglichst sicheren Zustand herbeizuführen - und das sollte in solchen Fällen möglichst direkt im Startupcode und möglichst ohne UP-Call's passieren, denn es könnte ja z.B. sein, daß der RAM ne Macke hat. Naja - und das mit der Fehlerlampe ist auch so eine Sache. Viele µC stecken an Stellen, wo niemals irgend einer hinschaut bzw. hinschauen kann. Da hilft ne LED oder ne V24-Ausgabe auch bloß nicht. W.S.
Vielen Dank für eure Anregungen! Ich merk schon, dass ich doch noch nicht so fortgeschritten bin wie gedacht, sondern eher ein blutiger Anfänger ;) Sehr interessant ist natürlich, dass einige einen Neustart für sinnvoll halten, nachdem die Hardware in einen sicheren Zustand gebracht wurde, während anderen genau davon abraten und das Gegenteil, d.h. eine Endlosscheleife präferieren. Jim Meba schrieb: > Bei welchem Controller? NVIC_SystemReset() sollte überall funktionieren, > das ist ein internes Signal. Es gibt auch noch ein VECTRESET Bit, das > nur den Core selbst resettet - aber das will man praktisch nie Ich habs nochmal genauer überprüft und NVIC_SystemReset() funktioniert wie es soll ;)
Andi K. schrieb: > Sehr interessant ist natürlich, dass einige einen Neustart für sinnvoll > halten, nachdem die Hardware in einen sicheren Zustand gebracht wurde, > während anderen genau davon abraten und das Gegenteil, d.h. eine > Endlosscheleife präferieren. Wobei "einige" für "einige Geräte", nicht für "einige Leute" steht ;) Und was ein sicherer Zustand ist, kann auch noch vom aktuellen Betriebszustand abhängen. Schon eine normale Heizungspumpe soll man nicht abschalten, wenn der Brenner läuft. Aber wenn das Oel alle ist, möchte man nicht sinnlos die Wärme aus dem Speichertank pumpen. Aber eine Endlosschleife ohne jede Meldung geht garnicht. Na gut, meinetwegen wenn ein Debugger angeschlossen ist. Das gesagt habend, fällt mir ein Überwachungsgerät ein. Da lasse ich als "endgültigen" Reset die eigene Sicherung durchbrennen... Aber dann geht immer noch die 24V-LED aus!
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.