Можно и это довольно просто. RPi имеет модуль Linux, который реализует стандартный Linux watchdog API. Вы можете найти документацию об этом здесь .
Теперь, если вы прочитаете это, вы узнаете, что существует специальный файл устройства, /dev/watchdog
и для его использования watchdog
вам нужно открыть этот файл и записать некоторые данные (один байт, лучше написать что-то отличное от 'V', которое я ' объясню позже) к этому время от времени. Если вы долго ничего не будете записывать в этот файл, watchdog
произойдет перезагрузка. Вы можете найти пример программы (очень простой) здесь .
Обратите внимание, что в обычной ситуации, если вы закроете /dev/watchdog
, watchdog
можно отключить. Существует специальный режим, называемый «Волшебное закрытие», который, похоже, реализован драйвером RPi, но AFAIK он не включен в конфигурации ядра по умолчанию (опция CONFIG_WATCHDOG_NOWAYOUT). В этом случае перезагрузка будет запущена, даже если вы закроете ее, /dev/watchdog
если только вы не напишите «V» перед выходом из приложения.
Вы должны проверить себя, действительно ли он отключен (у меня сейчас нет RPi для тестирования), но если это не так, это не хорошо для вас. Если ваше приложение падает, файл сторожевого устройства будет закрыт и перезагрузка не будет запущена, и именно поэтому вы этого хотите. В этой ситуации вы можете либо изменить конфигурацию ядра и пересобрать ее, либо написать настраиваемое приложение, которое будет отслеживать, работает ли ваше основное приложение (например, с использованием какого-либо метода IPC).
Существует также API ioctl, который позволяет вам делать больше с watchdog
. Например, вы можете установить другой тайм-аут - IOCTL с WDIOC_SETTIMEOUT (кажется, поддерживается драйвером RPI) или получить тайм-аут - IOCTL с WDIOC_GETTIMEOUT (который также, кажется, поддерживается). Вы можете использовать его для изменения времени ожидания по умолчанию (10 секунд). Однако существует жесткое ограничение до 16 секунд. Вот пример:
int timeout = 15;
int fd = open("/dev/watchdog", O_WRONLY);
ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
Вы также можете использовать IOCTL с WDIOC_KEEPALIVE вместо написания символа, если хотите. Оба метода действительны.