3.27. Vahtikoira-ajastin

Vahtikoira-ajastin on laitteisto, joka nollaa mikrokontrollerin, jos käynnissä oleva skripti lakkaa säännöllisesti tökkimästä sitä. Skripti ”ruokkii” vahtikoiraa jostain, missä se tietää terveen koodin olevan käynnissä; jos bugi, jumi tai odottamaton poikkeus estää kameraa ruokkimasta vahtikoiraa määritetyn aikakatkaisun sisällä, siru nollaa itsensä ja skripti käynnistyy alusta.

Käyttöön otetussa laitteessa, jonka lähellä ei ole ihmistä virtasykliä tekemään, tämä on ero sekunneissa toipuvan ohimenevän bugin ja huoltokäyntiä vaativan tiiliskiven välillä.

Kaavio vahtikoiralaskurista ajan kuluessa. Laskuri alkaa aikakatkaisuarvosta, laskee lineaarisesti kohti nollaa, ja ladataan uudelleen aikakatkaisuun joka kerta kun skripti kutsuu feed()-funktiota. Kolmen onnistuneen feed()-kutsun jälkeen neljännessä välissä ei ole feed()-kutsua ja laskuri saavuttaa nollan, mikä laukaisee MCU-nollauksen.

Vahtikoiralaskuri tikittää alaspäin aikakatkaisustaan. Jokainen feed() lataa sen uudelleen; jos se saavuttaa nollan, siru nollautuu.

3.27.1. machine.WDT-luokka

machine.WDT ottaa vahtikoiran käyttöön ja tarjoaa yhden metodin, feed(). Kerran käynnistettynä vahtikoiraa ei voi pysäyttää – ainoat ulospääsyt ovat sen ruokkiminen aikataulussa tai sen antaminen nollata siru:

from machine import WDT

wdt = WDT(timeout=2000)    # reset if not fed within 2 seconds

while True:
    do_work()
    wdt.feed()

timeout on millisekunteina. Oikea arvo riippuu siitä, kuinka kauan pääsilmukan pisin oikeutettu iteraatio kestää, mukavalla pelivaralla – 100 ms:n silmukalla, jonka aikakatkaisu on 2 s, on runsaasti marginaalia hitaalle iteraatiolle ilman tarpeettomia nollauksia.

3.27.2. Mistä feed() kutsutaan

Se, missä feed() sijaitsee, on ratkaiseva suunnittelupäätös; vahtikoira nappaa vain bugit niistä koodin osista, jotka eivät suoritu ruokintojen välillä.

  • Kutsu pääsilmukasta, ylhäältä tai alhaalta. Yleisin malli. Vahtikoira nappaa kaiken, mikä jumittaa pääsilmukan – lukkiumatilanteen, äärettömän while-silmukan, oheislaitteen, joka ei koskaan palaa – ja nollaa sirun takaisin silmukkaan.

  • Älä kutsu keskeytyskäsittelijästä. Vahtikoiran tarkoitus on napata jumit normaalissa koodipolussa. ISR, joka laukeaa riippumatta siitä, onko pääsilmukka jumissa, jatkaisi sellaisen vahtikoiran ruokkimista, jonka pitäisi laueta.

  • Älä kutsu pitkän estävän operaation sisältä. Verkkopyyntö tai sensorilukema, joka kestää kymmenen sekuntia, on juuri sellainen jumi, jonka vahtikoiran pitäisi napata. feed()-kutsun laittaminen sen sisään kumoaa suojauksen.

Useimmille ohjelmille toimiva ohjenuora: ruoki kerran pääsilmukan iteraatiota kohti, ja aseta aikakatkaisu useaan kertaan odotettua silmukan kestoa pidemmäksi. Jos yksi iteraatio tarvitsee oikeutetusti aikakatkaisua pidemmän ajan – vaikkapa tarkoituksellinen kalibrointivaihe – jäsennä se vaihe sarjaksi pienempiä paloja, joiden välissä on feed(), tai muuta aikakatkaisua timeout_ms()-metodilla (missä tuettu) ennen siihen siirtymistä.

3.27.3. Saatavuus

Vahtikoira on tarjolla useimmissa OpenMV-kameroissa mutta ei kaikissa – laitteisto on jokaisessa osassa, mutta Python-API:a ei ole vielä kytketty kaikkialle. Tarkista OpenMV-kortit tai yritä rakentaa WDT ja nappaa AttributeError, jos sitä ei tueta.

Myös kameroissa, joissa WDT ei ole tarjolla, kentälle otettu laite voi käyttää pehmeää vastinetta – erillistä tehtävää tai pääsilmukan vaihetta, joka valvoo edistymistä ja laukaisee machine.reset()-funktion, jos jokin näyttää jumiutuneen. Se on vähemmän vankka kuin laitteistovahtikoira (jumiutunut keskeytyskäsittelijä voi kaataa pehmeän valvojankin), mutta se kattaa samat tapaukset sovellustasolla.