3.27. Watchdog-timer¶
En watchdog-timer är en hårdvarukomponent som återställer mikrokontrollern om det körande skriptet någonsin slutar peta på den med jämna mellanrum. Skriptet ”matar” watchdogen från någonstans där det vet att frisk kod körs; om en bugg, en hängning eller ett oväntat undantag någonsin hindrar kameran från att mata watchdogen inom en konfigurerad timeout, återställer chipet sig självt och skriptet startar på nytt.
På en utplacerad enhet utan någon människa i närheten som kan strömcykla den är detta skillnaden mellan en övergående bugg som återhämtar sig på sekunder och en tegelsten som kräver ett servicebesök.
Watchdog-räknaren tickar ned från sin timeout. Varje feed() laddar om den; om den når noll återställs chipet.¶
3.27.1. machine.WDT-klassen¶
machine.WDT aktiverar watchdogen och exponerar en enda metod, feed(). När den väl är startad kan watchdogen inte stoppas – de enda vägarna ut är att mata den enligt schema eller att låta den återställa chipet:
from machine import WDT
wdt = WDT(timeout=2000) # reset if not fed within 2 seconds
while True:
do_work()
wdt.feed()
timeout anges i millisekunder. Rätt värde beror på hur lång tid den längsta legitima iterationen av huvudloopen tar, med bekväm marginal – en 100 ms-loop med en 2 s-timeout har gott om marginal för en långsam iteration utan onödiga återställningar.
3.27.2. Var feed() ska anropas¶
Var feed() placeras är det avgörande designbeslutet; watchdogen fångar bara buggar i de delar av koden som inte körs mellan matningarna.
Anropa från huvudloopen, högst upp eller längst ned. Det vanligaste mönstret. Watchdogen fångar allt som hänger huvudloopen – ett dödläge, en oändlig
while, en kringutrustning som aldrig returnerar – och återställer chipet tillbaka in i loopen.Anropa inte från en avbrottshanterare. Poängen med watchdogen är att fånga hängningar i den normala kodvägen. En ISR som utlöses oavsett om huvudloopen sitter fast skulle fortsätta mata en watchdog som borde utlösas.
Anropa inte inifrån en lång blockerande operation. En nätverksförfrågan eller sensoravläsning som tar tio sekunder är precis den typ av hängning som watchdogen ska fånga. Att lägga
feed()inuti den omintetgör skyddet.
En riktlinje som fungerar för de flesta program: mata en gång per iteration av huvudloopen, med timeouten satt till flera gånger den förväntade loop-varaktigheten. Om en enskild iteration legitimt behöver längre tid än timeouten – en avsiktlig kalibreringsfas, exempelvis – strukturera den fasen som en serie mindre delar med feed() mellan dem, eller ändra timeouten med timeout_ms() (där det stöds) innan du går in i den.
3.27.3. Tillgänglighet¶
Watchdogen exponeras på de flesta OpenMV-kameror men inte alla – hårdvaran finns på varje del, men Python-API:et är ännu inte inkopplat överallt. Kontrollera OpenMV-kort eller försök konstruera en WDT och fånga AttributeError om den inte stöds.
Även på kameror där WDT inte exponeras kan en fältutplacerad enhet använda en mjuk motsvarighet – en separat uppgift eller ett huvudloop-steg som övervakar framsteg och utlöser machine.reset() om något ser fastkört ut. Det är mindre robust än en hårdvaru-watchdog (en fastkörd avbrottshanterare kan ta ned den mjuka övervakaren också) men den täcker samma fall på tillämpningsnivå.