Use a system timer as a watchdog
A high-level application can use a system timer as a watchdog to cause the OS to terminate and restart that application if it becomes unresponsive. When the watchdog expires, it raises a signal that the application doesn't handle, which in turn causes the OS to terminate the application. After termination, the OS automatically restarts the application.
To use a watchdog timer:
- Define the timer
- Create and arm the timer
- Reset the timer regularly before it expires
To define the timer, create an itimerspec structure and set the interval and initial expiration to a fixed value, such as one second.
#include <time.h>
const struct itimerspec watchdogInterval = { { 1, 0 },{ 1, 0 } };
timer_t watchdogTimer;
Set a notification event, signal, and signal value for the watchdog, call timer_create to create it, and call timer_settime to arm it. In this example, watchdogTimer
raises the SIGALRM event. The application doesn't handle the event, so the OS terminates the application.
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);
}
Elsewhere in the application code, reset the watchdog periodically. One technique is to use a second timer, which has a period shorter than the watchdogInterval
, to verify that the application is operating as expected and, if so, reset the watchdog timer.
// Must be called periodically
void ExtendWatchdogExpiry(void)
{
//check that application is operating normally
//if so, reset the watchdog
timer_settime(watchdogTimer, 0, &watchdogInterval, NULL);
}