2013-02-07 5 views
14

Nachdem ich Embedded Code nach FreeRTOS verschoben habe, bleibt mir ein interessantes Dilemma über den Watchdog. Der Watchdog-Timer ist ein Muss für unsere Anwendung. Die Verwendung von FreeRTOS war auch für uns ein großer Gewinn. Wenn die Anwendung mehr Einzeltasking war, fütterte sie den Watchdog zu bestimmten Zeitpunkten in seinem logischen Ablauf, so dass wir sicherstellen konnten, dass die Aufgabe rechtzeitig einen logischen Fortschritt machte.Strategie für das Füttern eines Watchdogs in einer Multitask-Umgebung

Mit mehreren Aufgaben, das ist jedoch nicht einfach. Eine Aufgabe könnte aus irgendeinem Grund gebunden sein, ohne Fortschritte zu machen, aber eine andere ist in Ordnung und macht genug Fortschritte, um den Wachhund glücklich zu ernähren.

Ein Gedanke war, eine separate Aufgabe zu starten, nur um den Watchdog zu füttern, und dann einige Zähler verwenden, die anderen Aufgaben regelmäßig erhöhen, wenn die Watchdog-Aufgabe ankreuzen würde, würde sicherstellen, dass alle Zähler wie Fortschritt angezeigt wurde bei allen anderen Aufgaben, und wenn ja, dann füttere den Watchdog.

Ich bin gespannt, was andere in solchen Situationen getan haben?

+4

Wir ziemlich viel getan haben, was Sie gesagt haben. Es gibt einen Kicker und Aufgaben mit bekannten Zeiträumen checken mit dem Kicker ein. Wenn diese Aufgaben nicht rechtzeitig ausgeführt werden, wird der Kicker nicht ausgeführt. Der Kicker sollte der Thread mit der niedrigsten Priorität im System sein. Wenn das System keine Zeit hat, um zum Kicker zu gelangen, wird das Gerät zurückgesetzt. (Das gibt dir auch Schutz auf dem Kicker selbst.) Ich bin jetzt beschäftigt, werde aber später versuchen, eine längere Antwort zusammenzustellen. – Ross

+0

Ich erinnere mich an eine ähnliche Frage innerhalb des letzten Monats, sicherlich mit dem eingebetteten Tag. – Dan

Antwort

7

Eine Überwachungsaufgabe, die den Status aller anderen Aufgaben überwacht, ist eine gute Lösung. Verwenden Sie anstelle eines Zählers jedoch eine Statusanzeige für jede Aufgabe. Das Statusflag sollte drei mögliche Werte haben: UNKNOWN, ALIVE und ASLEEP. Wenn eine periodische Task ausgeführt wird, setzt sie das Flag auf ALIVE. Tasks, die bei einem asynchronen Ereignis blockieren, sollten ihr Flag auf ASLEEP setzen, bevor sie während des Laufs blockieren und LEBEN. Wenn der Watchdog-Monitor-Task ausgeführt wird, sollte er den Watchdog auslösen, wenn jede Task entweder ALIVE oder ASLEEP ist. Dann sollte die Watchdog-Überwachungsaufgabe alle ALIVE-Flags auf UNKNOWN setzen. (ASLEEP-Flags sollten ASLEEP bleiben.) Die Tasks mit dem UNKNOWN-Flag müssen ausgeführt werden und ihre Flags erneut auf ALIVE oder ASLEEP setzen, bevor der Monitor-Task den Watchdog erneut kickt.

Siehe „Multitasking“ Abschnitt dieses Artikels für weitere Informationen: http://www.embedded.com/design/debug-and-optimization/4402288/Watchdog-Timers

2

Dies ist in der Tat ein großer Schmerz mit Watchdog-Timern.

Meine Boards haben eine LED auf einer GPIO-Leitung, so dass ich in einer While-/Sleep-Schleife (750ms an, 250ms aus) in einem Thread mit der zweitniedrigsten Priorität blitze (der niedrigste ist der Leerlauf-Thread, der nur geht in einer Schleife auf Low-Power-Modus). Ich habe einen wdog-Feed in den LED-Flash-Thread gesteckt.

Dies hilft bei kompletten Abstürzen und Threads mit höherer Priorität, die CPU-Schleife, hilft aber nicht, wenn das System Deadlocks. Zum Glück, meine Message-Passing-Designs nicht festgefahren, (na ja, nicht oft, jedenfalls :).

2

nicht möglich Situation zu umgehen Vergessen, wo Aufgaben gelöscht werden, oder ruhend für längere Zeiträume. Wenn diese Aufgaben zuvor mit einer Watchdog-Aufgabe eingecheckt wurden, müssen sie auch einen "Check-out" -Mechanismus haben.

Mit anderen Worten, die Liste der Aufgaben, für die eine Watchdog-Aufgabe zuständig ist, sollte dynamisch sein, und sie sollte so organisiert sein, dass einige wilde Codes die Aufgabe nicht einfach aus der Liste löschen können.

Ich weiß, leichter gesagt dann ... done

0

Ich habe die Lösung entwerfen, um die FreeRTOS Timer mit:

  1. SystemSupervisor SW-Timer, die füttern die HW WD. FreeRTOS Fehler verursacht Reset.
  2. Jede Aufgabe erstellt "eigenen" SW-Timer mit SystemReset-Funktion.
  3. Jeder Task ist dafür verantwortlich, seinen Timer vor dem Ablauf "manuell" neu zu laden.
  4. SystemReset Funktion Daten speichert vor einem suiside

Hier commiting ist einige Pseudo-Code-Eintrag:

//--------------------------------- 
// 
// System WD 
// 
void WD_init(void) 
{ 
HW_WD_Init(); 
    // Read Saved Failure data, Send to Monitor 
    // Create Monitor timer 
    xTimerCreate( "System WD",  // Name 
        HW_WD_INTERVAL/2, // Reload value 
        TRUE,    // Auto Reload 
        0,     // Timed ID (Data per timer) 
        SYS_WD_Feed); 
} 
void SYS_WD_Feed(void) 
{ 
    HW_WD_Feed(); 
} 

//------------------------- 
// Tasks WD 
// 
WD_Handler WD_Create() 
{ 
    return xTimerCreate( "",     // Name 
          100,    // Dummy Reload value 
          FALSE,    // Auto Reload 
          pxCurrentTCB,  // Timed ID (Data per timer) 
          Task_WD_Reset); 
} 

Task_WD_Reset(pxTimer) 
{ 
    TaskHandler_t th = pvTimerGetTimerID(pxTimer) 
    // Save Task Name and Status 
    // Reset 
} 

Task_WD_Feed(WD_Handler, ms) 
{ 
    xTimerChangePeriod(WD_Handler, ms/portTICK_PERIOD_MS, 100); 
}