Możesz i to całkiem proste. RPi ma moduł Linux, który implementuje standardowy interfejs API watchdoga Linux. Dokumentację tego można znaleźć tutaj .
Teraz, jeśli to przeczytasz, będziesz wiedział, że istnieje specjalny plik urządzenia o nazwie /dev/watchdog
i aby go użyć watchdog
, musisz otworzyć ten plik i zapisać dane (jeden bajt, najlepiej napisać coś innego niż „V”, które ja ” wyjaśniam później) od czasu do czasu. Jeśli nic nie napiszesz w tym pliku wystarczająco długo, watchdog
uruchomi się restart. Możesz znaleźć przykładowy program (bardzo prosty) tutaj .
Należy zauważyć, że w normalnej sytuacji, po zamknięciu /dev/watchdog
, watchdog
może być wyłączona. Istnieje specjalny tryb o nazwie „Funkcja Magic Close”, który wydaje się być implementowany przez sterownik RPi, ale AFAIK nie jest włączony w domyślnej konfiguracji jądra (opcja CONFIG_WATCHDOG_NOWAYOUT). W takim przypadku ponowne uruchomienie zostanie uruchomione, nawet jeśli zamkniesz, /dev/watchdog
chyba że napiszesz „V” tuż przed zamknięciem aplikacji.
Powinieneś sprawdzić się, czy rzeczywiście jest wyłączony (nie mam teraz RPi do przetestowania), ale jeśli nie jest, nie jest to dla ciebie dobre. Jeśli aplikacja ulegnie awarii, plik urządzenia nadzorującego zostanie zamknięty, a ponowne uruchomienie nie zostanie uruchomione, dlatego właśnie tego chcesz. W tej sytuacji możesz albo zmienić konfigurację jądra i przebudować ją, albo napisać spersonalizowaną aplikację, która będzie monitorować, czy Twoja główna aplikacja działa (na przykład przy użyciu metody IPC).
Istnieje również interfejs API ioctl, który pozwala zrobić więcej watchdog
. Możesz na przykład ustawić inny limit czasu - IOCTL z WDIOC_SETTIMEOUT (wydaje się być obsługiwany przez sterownik RPI) lub uzyskać limit czasu - IOCTL z WDIOC_GETTIMEOUT (który również wydaje się obsługiwany). Możesz użyć go do zmodyfikowania domyślnego limitu czasu (10 sekund). Istnieje jednak sztywny limit do 16 sekund. Oto przykład:
int timeout = 15;
int fd = open("/dev/watchdog", O_WRONLY);
ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
Możesz także użyć IOCTL z WDIOC_KEEPALIVE zamiast pisać znak, jeśli chcesz. Obie metody są poprawne.