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"