Czy mogę wysłać bicie serca sprzętowemu stróżowi z własnego programu?

14

W odpowiedzi na pytanie i doskonałą odpowiedź udzieloną przez Steve'a Robillarda tutaj:

Jak mogę zresetować Raspberry Pi?

Jak mogę wysłać sygnał pulsu z mojego programu do sprzętowego watchdoga BCM2708 zamiast z demona watchdoga Linux? Innymi słowy, chcę zresetować RPi, jeśli MÓJ program nie działa (który uruchamia się przy starcie), nie tylko gdy cały system jest zamrożony.

Dzięki.

Chłopak
źródło

Odpowiedzi:

7

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/watchdogi 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, watchdoguruchomi się restart. Możesz znaleźć przykładowy program (bardzo prosty) tutaj .

Należy zauważyć, że w normalnej sytuacji, po zamknięciu /dev/watchdog, watchdogmoż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/watchdogchyba ż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.

Krzysztof Adamski
źródło
Aha, i zapomniałem - możesz do tego użyć watchdogd. Obsługuje wywoływanie zewnętrznego programu, który sprawdzi i zgłosi stan systemu. Przeczytaj „Check Binary” na tej stronie
podręcznika
Dzięki. Mam to działa! Po dodaniu bcm2708_wdog do / etc / modułów stworzyłem prostą aplikację testową VB.NET, aby sprawdzić moje zrozumienie: Dim fs As New System.IO.FileStream (fn, IO.FileMode.Open), aby uruchomić uruchomiony licznik i fs.WriteByte ( H), a następnie fs.Flush (), aby wysłać puls. Działa świetnie!
Guy
Jaka jest reprezentacja numeryczna WDIOC_KEEPALIVE? nie mogę go nigdzie znaleźć.
Flash Thunder,
@FlashThunder: Tutaj jest zdefiniowane: lxr.free-electrons.com/source/include/uapi/linux/watchdog.h#L29, ale musiałbyś rozwiązać kilka poziomów makr, aby znaleźć dokładną wartość. Lepszym sposobem jest napisanie prostego programu w języku C w celu wydrukowania wartości. Wystarczy dołączyć <linux / watchdog.h>. W moim systemie to0x80045705
Krzysztof Adamski