Stavy a Watchdog časovač

watchdog časovač, stavový stroj, stavový diagram, použitie watchdog časovača na mikrokontroléri ESP32, zotavenie systému

Introduction

  • (slide) Poznáte to. Na niečom dôležitom makáte, ste sústredení na riešenie problému, podávate zo seba to najlepšie, a vtedy to príde…

  • (slide) …Blue Screen of Death… Ktorý je tu s nami minimálne od verzie Windows 95. A vy ste v…

    Blue Screen of Death [@wikipediaBsod]
  • (slide) …teda možno ešte nie ste. Všetko záleží od toho, na čom ste pracovali alebo na akom zariadení ste sa k BSOD dopracovali. Ako napríklad na ATM machine (bankomat). Raz som sa tak nedostal domov, keď sa predomnou bankomat s kartou vo vnútri reštartol.

    Blue Screen of Death on ATM (zdroj)
  • (slide) Čo to ale je? Jedna z definícií hovorí, že:

    BSoD is an error screen displayed on a Windows computer system following a fatal system error. It indicates a system crash, in which the OS has reached a condition where it can no longer operate safely. (Wikipedia [@wikipediaBsod])

  • Skrátene môžeme povedať, že operačný systém (Windows) sa dostal do stavu, z ktorého sa nevie zotaviť. A systém je možné z tohto stavu vyslobodiť najčastejšie reštartom.

  • A o tom sa dnes budeme rozprávať - o stave vecí. A o tom, že

    • na každú vec sa vieme pozerať ako na stavový stroj,
    • stavový stroj vieme modelovať stavovým diagramom, a tom,
    • ako sa na zariadení správne kŕmiť strážneho psa, aby sme vyriešili problém s BSoD.

State Machine

  • (slide) Obecná definícia toho, čo je stavový stroj, znie zhruba takto:

    A state machine, is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some inputs; the change from one state to another is called a transition. An FSM is defined by a list of its states, its initial state, and the inputs that trigger each transition. (Wikipedia [@wikipediaFSM])

  • Táto definícia je obecná a má blízko ku gramatikám. My ju však upravíme, aby sme ju vedeli použiť pre naše potreby.

  • Stavový stroj (alebo aj konečný automat) je najjednoduchším z formálnych modelov počítača. Opisuje stroj, ktorý má konečný počet stavov, v ktorých sa môže nachádzať, pričom naraz sa môže nachádzať len v jednom z nich.

  • Prečo sa nám vlastne oplatí zaoberať sa stavovým strojom? Rozumieť stavom systému nám pomôže jednoduchšie opísať problém.

State Diagram

  • (slide) Stavové stroje môžeme modelovať pomocou stavového diagramu.

  • Stavový diagram je jedným z UML diagramov. Používa sa na modelovanie, resp. opis správania systémov (patrí do skupiny behaviorálnych diagramov).

Symbols and Notation

  • (slide) Stavový diagram je veľmi jednoduchý. Skladá sa z týchto symbolov:

    • stav - z angl. state, stavy reprezentujú situácie, do ktorých sa môže systém dostať počas svojho životného cyklu
    • prechod - z angl. transition, prechod reprezentuje cestu vedúcu k zmene stavu z jedného do druhého pomocou orientovanej šípky; môže byť doplnený popiskom o udalosti, ktorá daný prechod spustí
    • počiatočný stav - z angl. initial state, plný kruh vedúci do stavu, v ktorom sa bude systém nachádzať po spustení
    • koncový stav - z angl. final state, stav, z ktorého už nie je možné dostať sa do iného stavu

State Diagram Example

  • (slide) Pozrime sa na jednoduchý príklad turniketu, ktorým sa potrebujete dostať na záchod na železničnej stanici:

    • turniket sa nachádza v dvoch stavoch: zamknutý a odomknutý
    • keď do neho zatlačíte, nepohne sa, pretože je zamknutý
    • ak do neho vhodíte mincu, odomkne sa a vy môžete zatlačiť a turniketom prejdete
    • ak je turniket odomknutý a znova do neho vhodíte mincu, zostane odomknutý
    • turniket sa znova zamkne, keď cez neho prejdete v stave odomknutý
    State Diagram of Turnstile [@s21]
  • Ďalšími podobnými bežnými dvojstavovými systémami môžu byť:

    • vypínač, ktorý môže byť zapnutý alebo vypnutý,
    • lampa, ktorá svieti alebo nesvieti,
    • dvere, ktoré sú zatvorené alebo otvorené,
  • Vyskúšajme komplexnejší príklad - otváranie brány. Brána bude mať niekoľko stavov:

    • zatvorená
    • otvorená
    • otvára sa
    • zatvára sa
    • stojí
  • (slide) Teraz však prejdime k elektronike a pozrime sa na jednoduchý príklad tu - The Blink. Ten netreba nijako predstavovať, nakoľko sa jedná o akýsi Hello world! vo svete hardvéru. Budeme blikať LED diódou.

  • Obecná implementácia vyzerá takto:

    from machine import Pin
    from time import sleep
    
    led = Pin(14, Pin.OUT)
    while True:
        led.on()
        sleep(2)
        led.off()
        sleep(1)
  • Identifikujme stavy, v ktorých sa systém môže nachádzať:

    • svieti, ktorý bude aj počiatočným stavom
    • nesvieti
  • A teraz sa pozrime na to, ako je možné prejsť z jedného stavu do druhého:

    • zo stavu svieti sa systém dostane do stavu nesvieti po uplynutí času 2s
    • zo stavu nesvieti sa systém dostane do stavu svieti po uplynutí času 1s

State Design Pattern

  • (slide) Ak programujete objektovo, tak v objektovom programovaní sa môžete stretnúť s reprezentáciou stavového stroja pomocou návrhového vzoru stav.

Other Areas

  • So stavovými strojmi a modelovaním systému pomocou stavov, sa dá stretnúť aj v iných oblastiach informatiky, ako je programovanie mikrokontrolérov. Obecne sa jedná o jeden z najdôležitejších a najjednoduchších formálnych nástrojov na opis správania systému.

  • Pozrime sa teda na niekoľko ukážok ďalších oblastí, kde sa dá s opisom pomocou stavových strojov, stretnúť.

Game Development

  • Pri programovaní hier sa dá stretnúť so stavovými strojmi na viacerých miestach. Jedným príkladom je modelovanie správania ľubovoľného aktéra hry, ktorý sa môže nachádzať v rozličných stavoch. Ak si napríklad vezmeme za príklad hernú postavičku Super Mario v jeho prvom dobrodružstve, tak môžeme hovoriť o niekoľkých stavoch:

    • pohyb doprava,
    • pohyb doľava,
    • výskok,
    • skrčenie,
    • smrť
  • Medzi jednotlivými stavmi aktér, ktorý reprezentuje Super Mária, prechádza po stlačení príslušnej klávesy alebo tlačidla na ovládači. Výnimkou je iba stav, ktorý reprezentuje smrť hráča, pretože do tohto stavu sa je možné dostať z každého jedného.

  • (slide) Ukážka stavového diagramu, ktorý reprezentuje aktéra, môžete nájsť v knihe Game Programming Patterns [@Nystrom2014], je na nasledujúcom obrázku.

    State Diagram Representing Game Actor [@Nystrom2014]
  • Iným príkladom použitia stavových strojov, s ktorými sa je možné stretnúť v počítačových hrách, je zmena jednotlivých scén, resp. obrazoviek. Príkladom môže byť:

    • úvodné menu,
    • zmena nastavení hry,
    • samotná hra,
    • pozastavenie hry,
    • prehranie cut scény,
    • záverečné titulky (credits),
  • Každá jedna obrazovka si totiž vyžaduje iné správanie. Napr. úvodné menu sa ovláda kurzorovými šípkami, ktoré sa počas hry používajú na ovládanie hráča. Alebo sa v ňom používa myš, pričom vidno jej kurzor, ale počas hry sa myš používa na riadenie pohľadu hráča.

  • Ukážku jednoduchej implementácie v jazyku Python pomocou PygameZero môžete nájsť v tomto článku [@Cross2019].

Application Development

  • postupnosť obrazoviek sprievodcovi

Watchdog (Timer)

Introduction

  • (slide) Vráťme sa však späť ku BSoD. Hovorili sme, že sa operačný systém dostal do stavu, z ktorého sa nedokáže zotaviť. Jediné riešenie, ktoré dokáže operačný systém znova spojazdniť, je častokrát len reštart systému.

  • (slide) Tento reštart však musí byť vykonaný manuálne. Vďaka tomu máme k dispozícii mnoho fotiek s BSoD, ktoré nás zabávajú, v rozličných priestor alebo na rozličných zariadeniach, pretože kým k danému zariadeniu príde operátor, ktorý ho reštartne, môžu prejsť minúty, hodiny a možno aj dni.

    BSoD on Gatwick Airport (zdroj: FB skupina CentrumXP.pl)
  • To, že sa do tohto stavu dostane OS vieme a máme s tým sami nejednu (bolestnú) skúsenosť. Ale rovnako tak sa do takéhoto stavu dokáže dostať aj mikrokontrolér. Tých dôvodov môže byť samozrejme mnoho. Výsledkom však nebude BSoD, ale nefunkčný mikrokontrolér. Následky môžu byť taktiež rozličné - od výpadku získavania údajov z mikrokontroléra až po život človeka.

  • Otázkou teda je, ako sa takémuto stavu vyhnúť? Resp. ak sa zariadenie do takého stavu dostane, ako z neho zariadenie dostať bez nutnosti ručného zásahu - teda manuálneho reštartu?

Watchdog (Timer)

  • (slide) Odpoveďou na túto otázku je časovač Watchdog (WDT). Jeho cieľom je práve reštartovať aplikáciu (mikrokontrolér), ak sa dostane do stavu, z ktorého sa nedokáže zotaviť.

    The WDT is used to restart the system when the application crashes and ends up into a non recoverable state. Once started it cannot be stopped or reconfigured in any way. After enabling, the application must “feed” the watchdog periodically to prevent it from expiring and resetting the system. (MicroPython [@s70])

  • (slide) Princíp fungovania je veľmi jednoduchý. Do systému vypustíme strážneho psa (nastavíme časovač). Každého psa ale treba pravidelne nakŕmiť (feed), pretože ak ho nenakŕmite, tak hryzie (bites).

  • Čo to však znamená vo svete mikrokontrolérov? Watchdog je reprezentovaný časovačom. Ten nastavíme na začiatku nastavíme na potrebnú dobu. Časovač plynie na pozadí a o jeho plynutie sa (v závislosti od mikrokontroléra) nemusíme starať. Akonáhle však dosiahne hodnotu 0, automaticky reštartuje mikrokontrolér.

  • Uplynutiu časovača však zabránime nakŕmením (feed) strážneho psa. V mikrokontroléri to znamená, že v pravidelných intervaloch, ktoré sú však kratšie, ako je doba časovača, časovač resetujeme. Tým pádom začne jeho doba opäť plynúť znova.

  • Ak sa následne mikrokontrolér dostane do stavu, z ktorého sa nedokáže zotaviť a strážny pes nebude nakŕmený, po uplynutí doby časovača ho automaticky reštartuje. Doba, kedy je mikrokontrolér nefunkčný, je max. taká dlhá, aká je doba WDT.

How to use WDT on ESP32

  • (slide) Použitie WDT v jazyku MicroPython je veľmi jednoduché. V balíčku machine sa nachádza trieda WDT, z ktorej je možné vytvoriť inštanciu časovača. Parametrom konštruktora je doba, na ktorú sa časovač nastaví. Vytvorením časovača sa časovač aj rovno spustí.

    from machine import WDT
    wdt = WDT(timeout=2000)  # enable it with a timeout of 2s
  • (slide) Následne je v kóde potrebné v pravidelných intervaloch strážneho psa nakŕmiť. To je možné zavolaním metódy .feed() nad objektom časovača, napr. pri každej iterácii v superloop:

    while True:
        wdt.feed()
        # the magic goes here
  • Tým je zabezpečené pravidelné kŕmenie. Ak v tomto momente dôjde k prerušeniu vykonávania programu, po uplynutí časovača sa mikrokontrolér reštartuje.

System Recovery

  • (slide) V závislosti od toho, za čo všetko vec zodpovedá, netreba zabudnúť ani na mechanizmus automatického zotavenia sa po reštarte mikrokontroléru. Uvedomte si, že vaše zariadenie sa môže nachádzať na nedostupnom mieste a fyzický zásah môže predstavovať aj niekoľko hodinové cestovanie.

    Automatic System Recovery (zdroj: FB skupina L’Angolo di Windows)
  • Samozrejme mechanizmy zotavenia záležia od funkcionality zariadenia. Na mikrokontroléroch ESP32 je výhodné za týmto účelom využiť napr. flash pamäť mikrokontroléra.

Čo sa môže pokaziť, to sa pokazí.

  • (slide) Murphyho zákon hovorí, že _“Ak sa má niečo pokaziť, tak sa to aj pokazí.” A samozrejme toto nie je jediný zákon na túto tému, ale môžeme pokračovať ďalej:
    • Ak sa môže pokaziť viac vecí, vždy sa pokazí tá, ktorá spôsobí najväčšiu škodu.
    • Ak sa niečo nepokazí samo od seba, vždy sa nájde niekto, kto to pokazí.
    • Pravdepodobnosť toho, že sa niečo pokazí, sa zvyšuje s počtom dôležitých ľudí v miestonsti.
  • proste - treba rátať s tým, že sa niečo určite pokazí
  • ako sa však pripraviť na situáciu, že sa niečo pokazí?
  • zariadenie / aplikáciu / systém môžeme otestovať, pokiaľ ju máme u seba. a testovanie robíme pri vývoji a pri nasadzovaní každej jednej verzie. testujeme ako hardvér tak aj softvér. ale čo potom, keď sa dostane ku zákazníkovi?
  • budeme sa rozprávať o samotestovaní

Diagnostika

  • (slide) Jedna z definícií by mohla byť táto:

    Proces identifikácie, analýzy a určenia príčiny alebo povahy problémov v systéme, zariadení alebo situácii.

Samotestovanie

  • (slide)
  • z angl. self-test

Power-On Self Test (POST)

  • (slide) Jedna z definícií toho, čo je to POST test, je táto:

    A power-on self-test (POST) is a diagnostic process performed by firmware or software routines immediately after a computer or other digital electronic device is powered on or restarted. (Wikipedia)

  • Samotný systém sa naštartuje až po vykonaní samotestovania.

  • (slide) Pri POST teste sa v zariadení testuje napríklad:

    POST test
    • správna činnosť procesora
    • pamäť (napr. čítaním a zápisom)
    • pripojené úložisko (napr. len tým, či je pripojené)
    • klávesnica
    • pripojené ovládače (napr. v herných konzolách)
    • pripojenie zobrazovacej jednotky
    • čas
  • V prípade zlyhania testu dôjde k akusticko-vizuálnej notifikácii, že niečo nie je v poriadku. Chyba teda môže byť notifikovaná:

    • vypísaním správy na obrazovke
    • blikaním LED diódy
    • pípaním reproduktora
    • kombináciou uvedených spôsobov
  • Ak sa na notifikáciu používa výlučne blikanie alebo pípanie, je dôležité na základe blikajúceho alebo pípajúceho vzoru identifikovať konkrétny typ chyby. Ak by totiž dochádzalo vždy k rovnakému blikaniu a pípaniu, vedeli by sme iba povedať, že niečo nie je v poriadku, ale nevedeli by sme povedať, že čo konkrétne.

  • S POST testom sa dá stretnúť bežne pri počítačoch, kde sa spúšťa rovno po zapnutí.

  • S POST testami sa dá však samozrejme stretnúť aj v rozličných ďalších zariadeniach. POST testy sa napríklad spúšťajú aj v aute. Po otočení kľúčom sa obyčajne rozsvieti celá palubovka, začne pípať bzučiak a kontrolky otáčkomera a rýchlomera sa vytočia najprv úplne doprava a následne sa vrátia naspäť na nulu.

    POST test po otočení kľúča v aute
  • built-in self-tests (BIST)

  • môžu byť

    • kontinuálne
    • iniciované používateľom

Ako písať self-testy pre IoT zariadenia

V nasledujúcich častiach si ukážeme niekoľko príkladov, ako napísať self-test-y pre vybrané senzory a akčné členy.

Príklad self-test-u pre senzor DHT11

Senzor DHT11 je populárny a lacný teplomer aj vlhkomer v jednom. Podľa katalógových informácií sú rozsahy hodnôt teploty a vlhkosti, ktoré je možné pomocou neho odmerať, nasledovné:

  • rozsah merania teploty: 0-50 °C
  • rozsah merania vlhkosti: 20-90 %

Test, ktorý vytvoríme, overí, či sa namerané hodnoty nachádzajú v uvedených rozsahoch. Okrem toho v rámci testu overíme aj to, či je so senzorom možné pracovať, a teda, či je z neho možné teplotu ako aj vlhkosť odmerať.

from dht import DHT11
from machine import Pin

def self_test():
  sensor = DHT11(Pin(DHT_PIN))

  try:
    # perform sensor reading
    sensor.measure()

    # retrieve temperature value and check it's range
    temperature = sensor.temperature()
    if not 0 <= temperature <= 50:
      raise ValueError('Invalid temperature value.')

    # retrieve humidity value and check it's range
    humidity = sensor.humidity()
    if not 20 <= humidity <= 90:
      raise ValueError('Invalid humidity value.')

  except Exception as ex:
    print(f'DHT11 Self-Test Failed: {ex}')
    return False

  return True

Ako vytvoriť POST test ako v aute

  • Keď otočíte kľúčikom v aute, tak sa na chvíľu rozsvieti celá palubná doska, ručičky budíkov prejdú celou stupnicou a vrátia sa naspäť a celý čas bzučí bzučiak. Je to jednoduchý spôsob, ako po štarte otestovať funkčnosť všetkých prvkov na palubnej doske.

  • Ak by sme chceli urobiť podobnú funkcionalitu,

Implementácia POST testu

  • Ako už bolo uvedené vyššie, POST test sa spúšťa po zapnutí alebo reštartovaní zariadenia. Môže sa spustiť automaticky alebo je ho možné spustiť až po zásahu používateľa, napr. držaním tlačidla po dobu niekoľkých sekúnd.

  • Spustiť POST test automaticky je jednoduché - stačí priamo po štarte zavolať funkciu, ktorá tento test spustí. My sa však pozrieme na to, ako POST test spustiť až potom, ako používateľ pri štarte podrží stlačené tlačidlo po dobu niekoľkých sekúnd.

  • Najprv vytvoríme funkciu, ktorá overí, či držíme tlačidlo dostatočne dlho.

    def is_button_held(button, duration_threshold):
        start_time = time()
    
        while button.value() == 0:
            sleep(0.1)
    
            if time() - start_time >= duration_threshold:
                return True
    
        return False
  • Potom sa opýtame rovno po štarte mikrokontroléra, či náhodou tlačidlo nebolo držané požadovaný čas, ktorý je definovaný globálnou premennou DURATION_TRESHOLD. Ak áno, spustí sa POST test. Ak nie, mikrokontrolér bude pokračovať v hlavnom programe.

    if __name__ == '__main__':
        button = Pin(BTN_PIN, Pin.IN, machine.Pin.PULL_UP)
    
        if is_button_held(button, DURATION_TRESHOLD):
            print('>> running post')
            start_post()
    
        print('>> operating')

Conclusion

  • (slide) Dnes sme sa rozprávali o veľmi dôležitej téme z pohľadu softvérového návrhu a implementácie zariadení v IoT - o stavoch. Pozerať sa na zariadenie ako na stavový stroj nám umožní dekomponovať problém na menšie časti (stavy), ktoré vieme reprezentovať buď pomocou funkcií v prípade procedurálneho programovania alebo pomocou tried v prípade objektového programovania.

  • Ukázali sme si, že návrh takéhoto systému môže začať na papieri alebo tabuli, pretože takto navrhnutý systém vieme jednoducho modelovať pomocou diagramu stavov.

  • Okrem toho sme sa venovali aj špeciálnemu stavu, z ktorého sa systém nedokáže zotaviť a predstavili sme si mechanizmu strážneho psa, resp. špeciálneho časovača, ktorý pokiaľ nie je pravidelne kŕmený, tak mikrokontrolér reštartne. Tým pádom ho dostane práve z daného stavu a obnoví činnosť zariadenia.