Verwenden eines Systemtimers als Watchdog

Eine allgemeine Anwendung kann einen Systemtimer als Watchdog verwenden, damit das Betriebssystem diese Anwendung beendet und neu startet, wenn sie nicht mehr reagiert. Wenn der Watchdog abläuft, wird ein Signal ausgelöst, das die Anwendung nicht verarbeitet, was wiederum dazu führt, dass das Betriebssystem die Anwendung beendet. Nach der Beendigung startet das Betriebssystem die Anwendung automatisch neu.

So verwenden Sie einen Watchdog-Timer:

  • Definieren des Timers
  • Erstellen und Arm des Timers
  • Setzen Sie den Timer regelmäßig zurück, bevor er abläuft.

Um den Timer zu definieren, erstellen Sie eine itimerspec-Struktur , und legen Sie das Intervall und den anfänglichen Ablauf auf einen festen Wert fest, z. B. eine Sekunde.

#include <time.h>

const struct itimerspec watchdogInterval = { { 1, 0 },{ 1, 0 } };
timer_t watchdogTimer;

Legen Sie ein Benachrichtigungsereignis, ein Signal und einen Signalwert für den Watchdog fest, rufen Sie timer_create auf, um es zu erstellen, und rufen Sie timer_settime auf, um ihn zu bewaffnen. In diesem Beispiel watchdogTimer löst das SIGALRM-Ereignis aus. Die Anwendung behandelt das -Ereignis nicht, sodass das Betriebssystem die Anwendung beendet.

void SetupWatchdog(void)
{
    struct sigevent alarmEvent;
    alarmEvent.sigev_notify = SIGEV_SIGNAL;
    alarmEvent.sigev_signo = SIGALRM;
    alarmEvent.sigev_value.sival_ptr = &watchdogTimer;

    int result = timer_create(CLOCK_MONOTONIC, &alarmEvent, &watchdogTimer);
    result = timer_settime(watchdogTimer, 0, &watchdogInterval, NULL);
}

Setzen Sie den Watchdog an einer anderen Stelle im Anwendungscode in regelmäßigen Abständen zurück. Eine Methode besteht darin, einen zweiten Timer zu verwenden, der einen kürzeren Zeitraum als hat watchdogInterval, um zu überprüfen, ob die Anwendung wie erwartet funktioniert, und wenn ja, setzen Sie den Watchdog-Timer zurück.

// Must be called periodically
void ExtendWatchdogExpiry(void)
{
    //check that application is operating normally
    //if so, reset the watchdog
    timer_settime(watchdogTimer, 0, &watchdogInterval, NULL);
}