14.3.2. Watchdog¶
Hardwarový watchdog je základem, na kterém stojí každá další volba zpevnění. Je to malinký nezávislý časovač, který resetuje procesor, když mu příliš dlouho nebylo řečeno jinak. Skript, který se zasekne na nestabilním senzoru, síťové volání, které se zablokuje za svým časovým limitem, alokátor paměti uvázlý v zákoutí haldy, výjimka, která unikla ze smyčky – žádný z nich watchdog nezastaví. Časovač odpočítává bez ohledu na to a kamera se restartuje.
Pro dodávaný produkt není watchdog volitelný. Bez něj kterýkoli z výše uvedených režimů selhání ponechá kameru mrtvou, dokud si toho někdo nevšimne a nevypne a nezapne napájení. S ním se kamera sama znovu spustí a jediným důkazem selhání je jeden řádek v logu.
Viz také
Stránka watchdog časovač v hardwarové kapitole pokrývá, co je watchdog na hardwarové úrovni, a základy API machine.WDT. Tato stránka pokrývá, co se mění pro produkční nasazení.
14.3.2.1. Spuštění watchdogu¶
machine.WDT je dané API. Je podporováno hardwarem: jakmile je vytvořeno, časovač běží až do dalšího resetu. Neexistuje žádný stop(), žádný deinit(), žádný únik přes Ctrl-C. To je celý smysl.
Typické nastavení na začátku main.py, bezprostředně před smyčkou, kterou chrání:
from machine import WDT
wdt = WDT(timeout=10_000) # milliseconds
main.py je správným domovem pro watchdog, protože právě tam žije smyčka. Reset watchdogu je hardwarový reset, takže cesta studeného startu se znovu spustí a main.py znovu vstoupí do smyčky sám od sebe – obnova funguje bez jakéhokoli zapojení v boot.py. Spuštění watchdogu v boot.py místo toho znamená, že každý měkký reset (například vývojářské Ctrl-D) předá aplikaci hardwarový časovač, který nemá jak zastavit, což je obtěžující na pracovním stole a past v produkčním nastavovacím kódu, který běží předtím, než je smyčka připravena.
Zvolte časový limit 2 až 3krát delší, než je nejhorší pozorovaný čas iterace hlavní smyčky. Kolísání snímkové frekvence, pomalé čtení ze studeného senzoru, krátký zádrhel Wi-Fi – žádný z nich by neměl watchdog vybavit. Skutečné zaseknutí (nekonečná smyčka, zablokované I/O volání) by mělo. Příliš krátké časové limity dělají z watchdogu zdroj falešných resetů; příliš dlouhé časové limity nechávají kameru sedět nereagující po minuty, než se obnova spustí.
14.3.2.2. Krmení watchdogu¶
wdt.feed() resetuje odpočítávání. Volejte jej jednou za každou iteraci hlavní smyčky, na začátku těla smyčky, aby ke krmení došlo bezpodmínečně před jakoukoli prací, která by se mohla zaseknout:
while True:
wdt.feed()
frame = csi0.snapshot()
process(frame)
14.3.2.3. Přežití výjimek¶
Watchdog zvládá zaseknutí. Výjimky jsou jiný režim selhání. Neošetřená výjimka probublá na nejvyšší úroveň skriptu, main.py skončí a kamera spadne do REPL. Watchdog se pak po svém časovém limitu vybaví, protože jej z REPL nic nekrmí, kamera se resetuje a main.py se znovu spustí – takže obnova funguje, ale v terénu se za každý pád platí plný časový limit plus restart, traceback jde na USB stdout, který nikdo nečte, a jakýkoli stav v paměti, který si aplikace udržovala, je pryč.
Zabalení hlavní smyčky do try / except na nejvyšší úrovni mění pád na zalogovanou událost, kterou aplikace pokračuje dál, bez placení za reset:
import logging
log = logging.getLogger(__name__)
while True:
wdt.feed()
try:
frame = csi0.snapshot()
process(frame)
except Exception:
log.exception("frame loop iteration failed")
Zachytávání Exception (nikoli BaseException) zachovává funkčnost KeyboardInterrupt a SystemExit, což je to, co chce vývojář připojený přes USB.
Tento vzor je softwarovou polovinou živosti: watchdog zachytává zaseknutí, wrapper zachytává pády a log zaznamenává, co z toho kterýkoli zachytil.
14.3.2.4. Vědět, proč ke spuštění došlo¶
Každý měkký reset a každý reset watchdogu se nakonec projeví jako čerstvý start. Pomocník pro diagnostiku při startu loguje machine.reset_cause() při každém studeném startu; řádek reset cause je to, co terénu řekne, zda se obnova skutečně spustila, nebo se kamera jen normálně restartuje vypnutím a zapnutím.
Řádek s příčinou resetu je to, co dělá práci watchdogu viditelnou v logu. Log plný resetů watchdog timeout říká, že se aplikace zasekává a watchdog ji obnovuje. Log bez nich říká, že se watchdog nemusel vybavit – což obvykle znamená, že je aplikace zdravá, ale může také znamenat, že je časový limit nastaven příliš dlouhý na to, aby zachytil zaseknutí, ke kterým ve skutečnosti dochází.
14.3.2.5. Kompletní startovací šablona¶
main.py, které spojuje watchdog, nastavení logování, diagnostiku při startu a wrapper dohromady, vypadá takto:
import logging
from machine import WDT
from app.logging_setup import setup_logging, log_boot_diagnostics
setup_logging('/sdcard/logs/app.log')
log_boot_diagnostics()
log = logging.getLogger(__name__)
wdt = WDT(timeout=10_000)
while True:
wdt.feed()
try:
step()
except Exception:
log.exception("loop iteration failed")
step() je práce aplikace na iteraci; zbytek tohoto lešení se mezi produkty nemění. Zpevnění je jeden watchdog, jeden wrapper a zalogovaný start při každém studeném startu – není to mnoho kódu a je v tom rozdíl mezi kamerou, která se obnoví sama, a kamerou, která potřebuje servisní zásah.