2009-03-19 7 views
9

Ich habe einen Watchdog in meinem Mikrocontroller, der, wenn er nicht gekickt wird, den Prozessor zurücksetzt. Meine Anwendungen laufen für eine Weile gut, werden aber irgendwann zurückgesetzt, weil der Watchdog nicht gekickt wurde. Wenn ich durch das Programm gehe, funktioniert es gut.Debugging eines Watchdog-Timeouts

Was sind einige Möglichkeiten, dies zu debuggen?

EDIT: Fazit: Die Art, wie ich meinen Fehler fand, war die Watchdog Paniermehl.

Ich verwende eine PIC, die einen hohen und niedrigen ISR-Vektor hat. Der High-Vektor sollte mit der LED-Matrix umgehen und der Low-Vektor sollte mit dem Timer-Tick umgehen. Aber ich habe beide ISR-Handler in den hohen Vektor gesetzt. Wenn ich also die LED-Matrix-ISR deaktivierte und der Zeitzähler-ISR einen Dienst benötigte, würde der Prozessor in dem niedrigen ISR stecken bleiben, um den Zeitgeber-Tick zu handhaben, aber der Zeitgeber-Handler war nicht da.

Die Brotkrumen begrenzten meine Suche auf die Funktion, die die LED-Matrix behandelt und speziell die LED-Matrix-Unterbrechung deaktiviert.

Antwort

9

Fügen Sie eine nicht initialisierte globale Variable hinzu, die im gesamten Code auf verschiedene Werte festgelegt ist. Stellen Sie es vor und nach wichtigen Funktionsaufrufen ein.

Setzen Sie einen Breakpoint am Anfang von main.

Wenn der Prozessor zurückgesetzt wird, hat die globale Variable immer noch den letzten Wert, auf den sie gesetzt wurde. Fügen Sie diese "Brotkrümel" hinzu, um auf die Problemfunktion einzugrenzen.

+0

Nur für jeden, der hierher kommt, hinzufügen: Eine "nicht initialisierte globale Variable" wird einige spezielle Semantik mit C-Compilern benötigen. Der Standard besagt, dass auch globale Variablen, denen kein Wert zugewiesen ist, auf Null initialisiert werden müssen. Daher benötigt man typischerweise Attribute für diese Variablen, wie z.B. ".noinit" für avr-gcc. – FourtyTwo

0

Frage jede Annahme Sie, zweimal machen:

  • Stellen Sie sicher, den Watchdog ist getreten (ich weiß nicht, die Protokollierungsmöglichkeiten auf dem Prozessor).
  • Stellen Sie sicher, dass der Watchdog, wenn er getreten wird, den Prozessor nicht zurücksetzt.

Und fragen Sie sich, welche Unterschiede es gibt zwischen "Durchschreiten" und Laufen alleine; Timing-Einschränkungen werden sicherlich eine Rolle spielen.

3

Viele Software-Watchdogs werden automatisch deaktiviert, wenn Sie einen Debugger anhängen (um einen Neustart zu verhindern, während der Debugger die Anwendung angehalten hat).

Das hieß, hier sind einige Grundlagen:

sind dies eine Multithreading-Anwendungen? Verwenden Sie einen RT-Scheduler? Wenn ja, ist Ihre Watchdog-Aufgabe verhungert?

Stellen Sie sicher, dass Ihre Watchdog-Task nicht an irgendwas hängen kann (ausstehende Semaphore, Warten auf eine Nachricht usw.). Manchmal können Funktionen blockieren, die Sie möglicherweise nicht erwarten. Zum Beispiel habe ich eine Linux-Plattform, an der ich gerade arbeite, wo ich printf ziemlich leicht blockieren kann.

Wenn es sich um einen Single-Thread handelt, kann ein Profiler Ihnen helfen, Timing-Probleme zu identifizieren.

Wenn es sich um ein neues System handelt, stellen Sie sicher, dass der Watchdog korrekt funktioniert. teste einfachen Code, der nur den WD trifft und dann in einer Endlosschleife schläft.

+1

+1 für den ersten Absatz im Besonderen. –

+0

Sekunde zu dir! :) Immer wenn ein neues Emulationsboard zum Debuggen kommt, stelle ich zuerst sicher, dass die WD-Einheit abgeschnitten ist! –

2

Ich verwende statusbasierte Programmierung und einen Trick, den ich immer verwenden wollte, war, einen Ausgangsport für den aktuellen Zustand in binärer Form zu reservieren.Schließen Sie dann einen Logikanalysator an und sehen Sie, wie sich der Status ändert. Sie könnten etwas Ähnliches hier tun: Tun Sie, was Robert gesagt hat, und erstellen Sie eine globale Variable und ändern Sie ihren Wert an Schlüsselpunkten - vorzugsweise mit einer Funktion, die den Wert des Ports sofort auf den aktuellen Zustand setzt (zB changeState (nextState);) Geben Sie den Status ein, wenn Sie die Funktion eingeben, mit der der Hund getreten wird, und ändern Sie dann den vorherigen Zustand, bevor Sie die Funktion verlassen. Sie sollten in der Lage sein zu sehen, von welchen Funktionen es nicht gekickt wird und dann können Sie daran arbeiten.

Viel Glück, es klingt wie ein Timing-Problem und diese sind schwer zu lösen.

1

Normalerweise wird die Watchdog-Task/der Thread mit niedriger Priorität ausgeführt. Wenn also der Watchdog nicht gekickt wird, sollte das daran liegen, dass der Prozessor etwas anderes macht - wahrscheinlich etwas, was er nicht tun sollte.

Es wäre wirklich nützlich, den Ausführungskontext (lokaler Stapel, Zeitplanungsstatus usw.) für jede Aufgabe/jeden Thread kurz vor dem Zurücksetzen des Prozessors auszugeben. Mit etwas Glück und Arbeit können Sie feststellen, was die Watchdog-Aufgabe daran hindert, den Timer zu treten.

1

Ich würde einen zusätzlichen Ausgangspin verwenden, der an geeigneten Stellen im Code hoch und niedrig gesetzt wird, um den Bereich zu begrenzen, in dem ich suche. Dann würde ich es auf einem digitalen Oszilloskop oder Logikanalysator verfolgen. Dies entspricht der Breadcrumbs-Methode, die von einem anderen Poster erwähnt wird, aber Sie können viel schneller mit dem Reset-Puls korrelieren.

0

Sie können eine While-Schleife in Ihren Code einfügen und eine LED innerhalb der While-Schleife umschalten. Dies ist der effektivste Weg, um zu überprüfen, ob das Board zurückgesetzt wird.