PICAXE a multitasking

Multitasking je obecně schopnost operačního systému (alespoň zdánlivě) pracovat na více úlohách (programech) současně. Zavaděč mikrokontrolérů PICAXE řady M2 není jen zavaděčem programu, plní současně i funkci malého operačního systému, který dovoluje spuštění až čtyř programů běžících (víceméně) nezávisle. Kdy má smysl tuto vlastnost využít a kdy je naopak „cestou do pekel“?

Původní myšlenkou, proč historicky vznikl multitasking, bylo využít času procesoru počítače v situacích, kdy procesor na něco, typicky periferie, z jeho pohledu velmi dlouho čekal. Dnešní situace třeba v oblasti PC je jiná, multitasking především přináší pohodlí uživateli, který může bez ukládání dat a neustálého otevírání a uzavírání různých programů pracovat s více programy současně (a mnoho dalších na počítači běží, aniž o tom uživatel vůbec ví). Z hlediska mikrokontrolérů se multitasking hodí především v situaci, kdy se má vykonávat několik činností jakoby nezávisle na sobě, jde o zjednodušení a zpřehlednění psaní programů.

V případě PICAXE nejde samozřejmě o opravdový paralelní běh programů, nemáme k dispozici více jader, ale o jejich velmi rychlé střídání. A asi je už jasné, že když se má střídat několik programů, musí ještě „nad nimi“ běžet něco, co jim přiděluje čas a stará se o správu paměti, takže střídající se programy nemohou využít beze zbytku výkon procesoru, ale něco (a ne málo) padne na správu multitaskingu.

U PICAXE musíme obětovat možnost změny hodinového kmitočtu, jakmile je v programu multitasking, mikrokontrolér řady M2 se sám (skrytě) přepne na maximální hodinový kmitočet 32 MHz a všechny programy poběží přibližně tak, jak by běžely na kmitočtu 4 MHz. Tolik teorie. To samozřejmě na první pohled nevychází, ale to je právě ta správa programů, střídání procesů je hodně náročné a „ukrojí“ si z výkonu mikrokontroléru pořádný kus, zhruba polovinu. Už začíná být jasné, že multitasking nebude správnou volbou v případě, že potřebujeme plně využít výkonu mikrokontroléru aby se úloha vůbec stihla obsloužit.

Střídání procesů také způsobí, že jednotlivé programy se prakticky nemohou synchronizovat na stejné události, třeba dva programy okamžitě reagovat na stejný stisk tlačítka. Výměna parametrů mezi nezávislými vlákny (programy) se může uskutečnit nejjednodušeji přes proměnné.

Začátky jednotlivých programů pracujících v režimu multitaskingu jsou uvedeny pevně daným návěštím START0 (nebo jen START), START1, START2 a START3. To stačí, žádný nový speciální příkaz není třeba.

Máme konkrétně na PICAXE 08M2 připojeny tři LED, a to na piny 0, 1 a 2 (respektive C.0, C.1 a C.2). Snažíme se, aby všechny tři LED dělaly trojité krátké záblesky, které jsou naprosto shodné, ale prodlevy mezi trojzáblesky jsou u každé LED jiné. Když dosadíme do konstant určujících prodlevu prvočísla, bude trvat pořádně dlouho, než se sekvence blikání zase začne přesně opakovat (v tomto případě to je teoreticky více než 15 dnů nepřetržité činnosti). O jednotlivé LED se starají tři samostatné a téměř stejné programy uvedené návěštím start0, start1 a start2. Čtvrtý možný program start3 není využit.

REM sekvencer2 - PICAXE 08M2
start0:                                 ;první z paralelních programů
  for b0=1 to 3
    high 0 
    pause 20 
    low 0 
    pause 120
    next
  pause 1009 
  goto start0
start1:                                 ;druhý z paralelních programů
  for b1=1 to 3 
    high 1 
    pause 20 
    low 1 
    pause 120 
    next
  pause 1097 
  goto start1
start2:                                 ;třetí z paralelních programů
  for b2=1 to 3 
    high 2 
    pause 20 
    low 2 
    pause 120 
    next
  pause 1193 
  goto start2

Má v tomto případě smysl využít multitasking? Určitě ano, vlastně napíšeme jen jeden z programů, pak jej dvakrát nakopírujeme, jemně upravíme a je hotovo. Využíváme toho, že jde jen o blikání a nikdo nebude přesně sledovat, jestli  jsou bliknutí stejně dlouhá, naprosto stejně a pravidelně od sebe a podobně. Efekt to udělá, nic víc není třeba.

Další příklad začátečnického použití multitaskingu, který usnadní psaní programu,  už byl uveden v tomto článku.

Multitasking je velmi přehledný i při zápisu programů v podobě vývojových diagramů v programu logicator.

logicator


Typickým příkladem, kdy by se multitasking hodil, ale už narazíme na jeho omezení a nepříjemné vlastnosti, je obsluha multiplexovaného displeje, pro jednoduchost jen se dvěma LED znakovkami. Jedno vlákno programu se bude starat o to, co se má zobrazovat, v našem případě jen počítat od 0 do 99 a číslo ukládat do paměti, druhé vlákno se „na plný úvazek“ postará o multiplexované zobrazování.

LED4

REM LED displej s 4511 v multitaskingu - PICAXE 20M2
;desetinná tečka se může ovládat samostatně
start0:                       ;načítá postupně čísla 0 - 99 v b1
  for b1=0 to 99 
    pause 250 
    next b1
  goto start0
start1:                       ;zobrazuje číslo uložené v b1 (2 místa)
  dirsB=%00001111             ;port B bity 0-3 jako výstup pins
  zobraz:
    b0=b1//10                 ;nižší řád přes zbytek po dělení
    pinsB=b0 high b.5 pause 20 low b.5
    b0=b1/10                  ;vyšší řád
    pinsB=b0 high b.4 pause 20 low b.4
  goto zobraz

Přestože smyčka zobrazení běží bez zpoždění, kvůli multitaskingu je rychlost každého z paralelních běhů snížena na 4 MHz (přibližně) a výrazné blikání displeje ukazuje, že tato frekvence hodin pro multiplexní zobrazení nestačí ani při dvoumístném displeji. V tomto případě je tedy problémem to, že klesl maximální hodinový kmitočet pro běh programu, který zobrazuje.

Když napíšeme funkčně stejný program v jednom vláknu a necháme jej běžet s hodinovou frekvencí 32 MHz, PICAXE úlohu s přehledem zvládne, dokonce může multiplexovat použitelně až 4 znakovky.


Podívejme se na to, jak si PICAXE v multitaskingu poradí s programovým generováním frekvence. Nejprve využijeme nejjednodušší smyčku při základní frekvenci hodin a pro jeden pin:

start: toggle 1 goto start

výsledkem je kmitočet kolem 453 Hz v mírně nepravidelném téměř symetrickém obdélníku. Zkusíme totéž, ale s návěštím start0 – nestačí to k aktivaci multitaskingu? Kmitočet je stejný, 453 Hz, tato změna nic nezpůsobila. A teď zkusíme návěští start1:

start1: toggle 1 goto start1

A vida, frekvence se najednou zvýšila na 1190 Hz a výstupní signál už není symetrický obdélník ale to, co je na snímku. Podobně to dopadne, když použijeme návěští start2 nebo start3, takže máme první důležitý poznatek: Multitasking se aktivuje, když je v programu použito kterékoli z návěští start1, start2 nebo start3. Ve frekvencích jsou menší rozdíly, takže správa procesů zjevně nepřistupuje ke všem vláknům rovnocenně, ale rozdíly nejsou velké.

hantek538_1

Když napíšeme program v jednom vláknu a použijeme jedno ze tří uvedených návěští, zapneme tím skrytě multitasking a zvýšíme hodinovou frekvenci, program poběží zcela jinak rychle než v základním stavu. Multitasking s jedním vláknem se chová tak, jako by přiděloval čas i ostatním vláknům a částečně v nich čekal.

A teď, jaké frekvence dostaneme pro dvě současně využitá vlákna?

start0: toggle 1 goto start0
start1: toggle 2 goto start1

Výsledkem je symetrický obdélník 585 Hz, pro tři vlákna 395 Hz a pro čtyři vlákna 299 Hz. Zapnutí multitaskingu a počet vláken výrazně ovlivňuje rychlost běhu programu a teze, že je to jako by běžely čtyři programy současně při hodinové frekvenci 4 MHz, odpovídá skutečnosti jen hodně, hodně vzdáleně.


Stále to ještě vypadá, že programy v multitaskingu běží sice různě rychle, ale víceméně pravidelně. Jenže technické prostředky mikrokontroléru jsou jen jedny a když je nějaké z vláken začne využívat, doslova tím chvilkově (a mohou to být sekundy) odstaví ostatní vlákna. Podívejme se na příklad sériové komunikace.

start0: inc b0 sertxd (#b0,13,10) goto start0
start1: toggle 1 goto start1

Jedno vlákno bude cyklicky počítat a posílat výsledky do PC, druhé bude jako v předchozím případě dělat symetrické pulzy. Opravdu symetrické?

hantek538_2Tohle tedy symetrické pulzy nejsou, ale jsou alespoň pravidelné. Tak přidáme další dvě vlákna, obě budou generovat zvuk, rozdílné tóny. Jedno vlákno dělá pulzy zvuku dlouhé 20 ms, druhé 1 s. V ideálním případě by měly oba zvuky znít současně, čistě a nepřetržitě (cyklus by běžel neomezeně rychle). Asi můžeme čekat nějaké to tikání a přerývání zvuků, protože cyklus také chvíli trvá. A realita?

hantek538_3

start0: inc b0 sertxd (#b0,13,10) goto start0
start1: toggle 1 goto start1
start2: sound 2,(80,2) goto start2
start3: sound 4,(110,100) goto start3

Nad chodem mikrokontroléru se ujme vlády nejpomalejší vlákno (3), to které (teoreticky) opakuje tóny po 1 s. Jeho tón je téměř nepřetržitý a přerušovaný jen tikáním, které dává najevo střídání procesů.  Tón vlákna 2 zazní jen občas (jednou za sekundu), nic víc. Data po sériové lince (vlákno 0) chodí nepravidelně po jedné nebo dvou sekundách. A na obrázku je signál generovaný vláknem (1) bez jakéhokoli dalšího zpoždění. Je to sice symetrický obdélnék, ale ouha, nemá stovky Hz, ale sotva 0,5 Hz (a je fakticky synchronizován na vlákno 3).


Multitasking mikrokontrolérů PICAXE řady M2 opravdu funguje a je to skvělá věc a nástroj, který nám umožňuje zkrátit a hlavně zjednodušit programy, aby byly pro začátečníka přehledné a „průhledné“. Je to výborná učební pomůcka pro vysvětlení  chodu multitaskingu a takové úlohy, jako je řízení křižovatky několika semafory, různé blikače s nesoudělnou periodou a podobně.

Bohužel v situaci, kdy je potřeba využívat nějaké procesy pracující s reálným časem, sériové přenosy, generování zvuků, programové řízení PWM a podobně, když by zkušený uživatel rád sáhnul po multitaskingu, je tento režim prakticky nepoužitelný a dává nečekané výsledky. Zkrátka pro jednoduché ukázky při výuce výborné, ale pro praktické využití většinou k ničemu.