Raspberry Pi má interní watchdog, který se dá aktivovat poměrně snadno a to natažením modulu bcm2708_wdog
modprobe bcm2708_wdog
Aby došlo k natažení modulu po rebootu, stačí přidat jeden řádek do /etc/modules
echo "bcm2708_wdog" >> /etc/modules
Watchdog se spustí zasláním nějakého znaku /dev/watchdog.
echo 1 > /dev/watchdog
Toto zasílání je poté třeba opakovat každých 10 sekund - v opačném případě watchdog Raspberry Pi natvrdo resetuje. Níže uvedenou dávku je dobré přídat do /etc/rc.local - tedy do skriptu, který se spustí po bootu.
nohup while true; do echo 1 > /dev/watchdog; sleep 10; done; &
Význam bodů:
Funkci zajišťuje firmware v ATtiny85. Funkce je primitivní - v nekonečné smyčce běží čítač, který po dosažení určité hodnoty (70 sekund a 5 minut) provede reset Raspberry. Aby k resetu nedocházelo, je potřeba, aby Rasperry periodicky tento čítač resetoval. To se děje tak, že vstup označená CCIN (Clear Counter INput) je připojen k nějakému GPIO pinu a tento pin periodicky (1x za minutu) stáhne defaultní log. 1 na 0 (minimálně na 20ms). Log. jednička je na CCIN proto, že Atmel má tento pin nastaven jako vstup se zapnutým pullupem. Aby si mohl Raspberry zjistit, že Atmel žije a že došlo k resetu čítače, je z Atmelu vyveden signál FEEDBACK. Jedná se o výstup, který kopíruje vstup CCIN. Pokud je CCIN na log.0, tak je i FEEDBACK log.0 a naopak. Výstup FEEDBACK je nakofigurován jako otevřený kolektor - opovídající vstup na Raspberry musí mít u příslušného vstupu nastaven pullup.
Po zapnutí napájení je nastaven timeout na 5 minut. Během této doby musí Raspbbery nabootovat a spustit se dávka, která bude každých 60 sekund odesílat impuls na CCIN. Po obdržení prvního impulzu se timeout přepne na 70 sekund - tedy došlo ke spuštění zmíněné dávky, která bude čítač periodicky mazat. Pokud Raspberry zatuhne, do 70-ti sekund se provede tvrdý reset. Po provedení resetu se nastaví opět dlouhý timeout 5 minut a to proto, aby měl Raspberry dost času nabootovat i s případnou kontrolou filesystému.
V případě, že je nutné provést reboot OS ručně a je pravděpodobnost, že se to nestihne do 70-ti sekund, je možné přepnout na dlouhý interval následujícím způsobem: stačí poslat 5 po sobě jdoucích impulzů na CCIN s tím, že čas mezi jednotlivými impulzy bude menší jak 2 sekundy.
#!/usr/bin/python # -*- coding: utf-8 -*- import RPi.GPIO as GPIO import time import sys # -- board pin's numbers -- CCIN=7 FEEDBACK=21 # -- main gpio settings -- GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(CCIN, GPIO.IN) time.sleep(0.03) GPIO.setup(FEEDBACK, GPIO.IN, pull_up_down=GPIO.PUD_UP) # -- get count of repeats -- try: rpt = int(sys.argv[1]) except Exception: rpt = 1 # -- send impulses to CCIN -- for i in range(rpt): # -- feedback before -- confirmed = True if GPIO.input(FEEDBACK)!=1: confirmed = False # -- falling edge -- GPIO.setup(CCIN, GPIO.OUT) GPIO.output(CCIN, 0) time.sleep(0.03) # -- feedback during -- if GPIO.input(FEEDBACK)!=0: confirmed = False # -- rising edge -- GPIO.setup(CCIN, GPIO.IN) time.sleep(0.03) # -- feedback after -- if GPIO.input(FEEDBACK)!=1: confirmed = False print "RPiwdt:", if confirmed: print "Feedback confirmed" else: print "Feedback failed"