Gestione del watchdog su schede WAFER 582x
Un circuito di watchdog è un dispositivo hardware che permette di effettuare un controllo
sullo stato del sistema e riavviare la macchina nel caso risulti non operativa
a causa di un crash irreparabile del software. Il funzionamento solitamente è basato su un
timer non pilotato dalla CPU principale che viene impostato dall'utente ad un valore stabilito e
diminuisce nel tempo; quando questo valore raggiunge lo zero allora viene alzato il segnale di
reset del sistema e la macchina viene riavviata.
La scheda WAFER 5822 prodotta dalla taiwanese ICP include tra i suoi componenti un circuito di
watchdog programmabile che si interfaccia col sistema grazie a due registri:
Registro
|
Modalità
|
Azione
|
0x443
|
Scrittura
|
Imposta il timer del circuito
|
0x443
|
Lettura
|
Attiva il decremento del timer
|
0x843
|
Lettura
|
Disattiva il decremento del timer
|
Il manuale della scheda spiega molto chiaramente come utilizzare tali registri,
e fornisce anche codice di esempio in assembler: a questo punto occorre solo decidere come interfacciare
l'hardware con l'utente. Il sistema più comodo e intuitivo a mio avviso è quello di
utilizzare la directory virtuale /proc sia per attivare e disattivare il timer, sia per
avvisare il sistema che l'applicazione è ancora viva. Sebbene il registro hardware sia uno
solo, nulla mi vieta però di creare più file a cui associare dei timer software che poi
il programma verifica periodicamente: nel momento in cui uno di tali timer non riceve risposta
dall'applicazione corrispondente, il programma sospende l'aggiornamento del registro hardware
riavviando di fatto la scheda. Per una gestione più accurata poi ho
supportato anche un dispositivo /dev/watchdog che deve essere regolarmente aperto come un
file normale e nel quale occorre spedire il carattere V prima dello scadere del tempo.
Se il dispositivo viene chiuso prima della spedizione di tale carattere, oppure se il carattere non
viene spedito in tempo, il sistema si riavvia immediatamente.
Proviamo quindi a compilare il sorgente come modulo con il supporto della directory
/proc attivato, carichiamolo in memoria e controlliamo nella directory
/proc se compare la nuova directory:
[/root]# gcc -DMODULE -D__KERNEL__ -O6 -c wafer582xwdt.c
[/root]# insmod wafer582xwdt.o
[/root]# lsmod
Module Size Used by
wafer582xwdt 5696 0 (unused)
[/root]# ls -la /proc/watchdog/
totale 0
drw-r--r-- 1 root root 0 gen 6 09:03 .
dr-xr-xr-x 47 root root 0 gen 6 09:51 ..
-rw-r--r-- 1 root root 0 gen 6 09:03 0
-rw-r--r-- 1 root root 0 gen 6 09:03 1
-rw-r--r-- 1 root root 0 gen 6 09:03 2
-rw-r--r-- 1 root root 0 gen 6 09:03 3
-rw-r--r-- 1 root root 0 gen 6 09:03 4
-rw-r--r-- 1 root root 0 gen 6 09:03 5
-rw-r--r-- 1 root root 0 gen 6 09:03 6
-rw-r--r-- 1 root root 0 gen 6 09:03 7
-rw-r--r-- 1 root root 0 gen 6 09:03 8
-rw-r--r-- 1 root root 0 gen 6 09:03 9
-r--r--r-- 1 root root 0 gen 6 09:03 status
[/root]#
Come possiamo vedere abbiamo a disposizione 10 differenti timer
a livello logico per poter gestire il sistema di watchdog. Proviamo ora a vedere
cosa dice il file di stato:
[/root]# cat /proc/watchdog/status
The watchdog is now disabled.
WDT timeout: 7
Module ping: 5
/dev/watchdog timeout: 10 - disabled
/proc/watchdog/0 timeout: 0
/proc/watchdog/1 timeout: 0
/proc/watchdog/2 timeout: 0
/proc/watchdog/3 timeout: 0
/proc/watchdog/4 timeout: 0
/proc/watchdog/5 timeout: 0
/proc/watchdog/6 timeout: 0
/proc/watchdog/7 timeout: 0
/proc/watchdog/8 timeout: 0
/proc/watchdog/9 timeout: 0
[/root]#
Esattamente quello che ci aspettavamo di trovare, ovvero l'indicazione che
il dispositivo è disattivo in quanto non abbiamo ancora
provveduto ad attivarlo. Proviamo allora ad eseguire il programma di esempio
watch (sorgente C, 725 byte), che gestisce il file
/dev/watchdog secondo le specifiche richieste:
[/root]# ./watch >/dev/null &
[1] 726
[/root]# cat /proc/watchdog/status
The watchdog is now enabled.
WDT timeout: 7
Module ping: 5
/dev/watchdog timeout: 10 - enabled
/proc/watchdog/0 timeout: 0
/proc/watchdog/1 timeout: 0
/proc/watchdog/2 timeout: 0
/proc/watchdog/3 timeout: 0
/proc/watchdog/4 timeout: 0
/proc/watchdog/5 timeout: 0
/proc/watchdog/6 timeout: 0
/proc/watchdog/7 timeout: 0
/proc/watchdog/8 timeout: 0
/proc/watchdog/9 timeout: 0
[/root]#
Il dispositivo ora viene indicato come attivo; se volete
provare il suo effettivo funzionamento provate a lanciare direttamente il
comando watch nella shell e ad interromperlo con un CTRL-C, il sistema
dovrebbe brutalmente riavviarsi dopo poco. Possiamo ora provare ad attivare
invece i timer presenti nella directory /proc/watchdog utilizzando
il programma di esempio mwatch (tipo sconosciuto, 396 byte):
[/root]# ./mwatch >/dev/null &
[2] 728
[/root]# cat /proc/watchdog/status
The watchdog is now enabled.
WDT timeout: 7
Module ping: 5
/dev/watchdog timeout: 10 - enabled
/proc/watchdog/0 timeout: 50
/proc/watchdog/1 timeout: 45
/proc/watchdog/2 timeout: 64
/proc/watchdog/3 timeout: 34
/proc/watchdog/4 timeout: 65
/proc/watchdog/5 timeout: 59
/proc/watchdog/6 timeout: 72
/proc/watchdog/7 timeout: 36
/proc/watchdog/8 timeout: 41
/proc/watchdog/9 timeout: 54
[/root]#
Il file di stato ci riporta i differenti tempi di controllo
impostati per ogni singolo timer. Tale risultato è ovviamente ottenibile
anche se andiamo a leggere ogni singolo file presente nella directory. Per
disattivare un timer così impostato è necessario scrivere il
valore 0 all'interno del file corrispondente.
Ultima cosa: se vi interessa utilizzare il driver direttamente nel kernel dovete
applicare la patch che ho fornito, ed attivare il driver dalla sezione dei dispositivi a
carattere: verrà offerta una opzione aggiuntiva per decidere se includere il supporto
del filesystem /proc oppure no. Compilato come modulo invece è possibile
caricarlo specificando una serie di parametri che modificano i valori preimpostati:
timeout indica il valore che viene scritto all'interno del registro di watchdog,
ping è l'intervallo tra ogni lettura di tale registro per avvisare che tutto
funziona regolarmente mentre devtimeout indica il tempo massimo entro il quale un
programma che usa il dispositivo /dev/timeout deve spedire il carattere di controllo.
RIFERIMENTI
In allegato vi lascio il sorgente del modulo appena discusso e il sito del produttore della
scheda. Quanto discusso vale anche per la scheda WAFER 5820, sorella più piccola di quella
descritta nell'articolo. Gli altri modelli della famiglia WAFER invece utilizzano dispositivi
differenti per la gestione del watchdog e non sono quindi compatibili.
-
Il sorgente del driver (sorgente C, 17 KB) per il circuito di watchdog.
-
Il sorgente del programma di esempio watch (sorgente C, 725 byte).
-
Il sorgente del programma di esempio mwatch (tipo sconosciuto, 396 byte).
-
Il sito del produttore della scheda.