3.27. Watchdog timer¶
Un watchdog timer è un componente hardware che resetta il microcontrollore se lo script in esecuzione smette mai di sollecitarlo periodicamente. Lo script «alimenta» (feed) il watchdog da un punto in cui sa che sta girando codice sano; se un bug, un blocco o un’eccezione imprevista impediscono mai alla camera di alimentare il watchdog entro un timeout configurato, il chip si resetta da solo e lo script riparte da capo.
Su un dispositivo installato sul campo senza nessun essere umano vicino per ciclarne l’alimentazione, questa è la differenza tra un bug transitorio che si risolve in pochi secondi e un brick che richiede un intervento di assistenza.
Il contatore del watchdog scende a partire dal suo timeout. Ogni feed() lo ricarica; se raggiunge lo zero, il chip si resetta.¶
3.27.1. La classe machine.WDT¶
machine.WDT abilita il watchdog ed espone un unico metodo, feed(). Una volta avviato, il watchdog non può essere fermato – le uniche vie d’uscita sono alimentarlo secondo la pianificazione o lasciare che resetti il chip:
from machine import WDT
wdt = WDT(timeout=2000) # reset if not fed within 2 seconds
while True:
do_work()
wdt.feed()
Il timeout è in millisecondi. Il valore giusto dipende da quanto tempo richiede la più lunga iterazione legittima del ciclo principale, con un margine confortevole – un ciclo da 100 ms con un timeout di 2 s ha ampio margine per un’iterazione lenta senza reset indesiderati.
3.27.2. Dove chiamare feed()¶
Dove risiede feed() è la decisione di progettazione critica; il watchdog cattura solo i bug nelle parti del codice che non vengono eseguite tra una feed e l’altra.
Chiamala dal ciclo principale, all’inizio o alla fine. Lo schema più comune. Il watchdog cattura qualunque cosa blocchi il ciclo principale – un deadlock, un
whileinfinito, una periferica che non ritorna mai – e resetta il chip riportandolo nel ciclo.Non chiamarla da un gestore di interrupt. Lo scopo del watchdog è catturare i blocchi nel percorso di codice normale. Un ISR che scatta indipendentemente dal fatto che il ciclo principale sia bloccato continuerebbe ad alimentare un watchdog che dovrebbe invece scattare.
Non chiamarla all’interno di un’operazione bloccante lunga. Una richiesta di rete o una lettura di un sensore che richiede dieci secondi è esattamente il tipo di blocco che il watchdog dovrebbe catturare. Mettere
feed()al suo interno vanifica la protezione.
Una linea guida che funziona per la maggior parte dei programmi: alimenta una volta per iterazione del ciclo principale, con il timeout impostato a diverse volte la durata attesa del ciclo. Se una singola iterazione necessita legittimamente di un tempo superiore al timeout – una fase di calibrazione deliberata, ad esempio – struttura quella fase come una serie di blocchi più piccoli con feed() tra di essi, oppure cambia il timeout con timeout_ms() (dove supportato) prima di entrarvi.
3.27.3. Disponibilità¶
Il watchdog è esposto sulla maggior parte delle cam OpenMV ma non su tutte – l’hardware è presente su ogni componente, ma l’API Python non è ancora collegata ovunque. Controlla la Schede OpenMV oppure prova a costruire un WDT e cattura l”AttributeError se non è supportato.
Anche sulle cam dove WDT non è esposto, un dispositivo installato sul campo può usare un equivalente software – un task separato o un passo del ciclo principale che monitora i progressi e innesca machine.reset() se qualcosa sembra bloccato. È meno robusto di un watchdog hardware (un gestore di interrupt bloccato può mettere fuori uso anche il monitor software) ma copre gli stessi casi a livello applicativo.