blogy logo
login PRIHLÁS SA
BLOG deadawp
ČLÁNKY
DISKUSIE
3
SLEDUJETE BLOG
PHP, Arduino programátor
deadawp



Ako spustiť neefektívny program efektívne? - FreeRTOS
pridal deadawp 21.6. 2022 o 20:21



Framework Wiring (Arduino Core) je veľmi populárny pre rýchly vývoj aplikácii pod mikrokontrolérmi. Najčastejšie v spojitosti s rozhraním Arduino IDE a populárnymi vývojovými kitmi Arduino. Postupom času získali podporu Arduino Core aj iné mikrokontroléry, medzi nimi napríklad ESP32 od Espressif Systems. Arduino Core pre ESP32 funguje ako wrapper pre nízkoúrovňové funkcie C/C++ frameworku ESP-iDF (Espressif IoT Development Framework). To znamená, že sa aplikačnou funkciou zavolá iná nízkoúrovňová funkcia (funkcie), prípadne môže používateľ tvoriť program aj z nízkoúrovňových funkcií.

Ako bolo v niekoľkých predcházajúcich článkoch spomenuté, mikrokontróler ESP32 podporuje aj operačný systém reálneho  času FreeRTOS. Operačný systém umožňuje spúšťať podprogramy ako úlohy (tasky), ktoré dokážu bežať nezávisle na sebe. Ide tak o plnohodnotný multitasking (nie pseudo-multitasking ako v prípade Arduino dosiek, ATmega čipov, ktoré nepodporujú FreeRTOS). Práve absencia FreeRTOS pri ATmega mikroprocesoroch mala za následok, že museli byť programy napísané efektívne, aby mikrokontróler dokázal obsluhovať viacero úloh naraz. 

Problémy začiatočníkov s návrhom programov
Najmä začiatočníci, ktorí nevedeli navrhnúť program dostatočne efektívne (s využitím knižnice Timer, alebo s časovaním cez millis() ) narážali na problém a potrebu multitaskingu v projektoch, kde sa vyžadovalo napríklad blikanie dvomi LED diódami zároveň, či blikanie LED diódou a obsluhou zberníc, či vykonávania inej úlohy. Ak používateľ blikal diódou a použil konštrukciu s funkciou delay(), bol beh programu zablokovaný po čas vykonávania delayu. Skúsenejší používateľ by delay() nahradil za podmienku s funkciou millis() a porovnaním či je rozdiel medzi starou millis() hodnotou a aktuálnou viac / rovné intervalu v akom mala LED dióda blikať. Obsah podmienky by už bola zmena stavu a znovuuloženie poslednej hodnoty millis().

FreeRTOS však dokáže aj program s blokovacou funkciou delay() spustiť bez toho, aby ovplyvnila dĺžku behu iného podprogramu, ktorý bude taktiež využívať funkciu delay(). Gro celého riešenia je v podpora wrappera, ktorý spustením funkcie delay() zavolá nízkoúrovňovú funkciu vTaskDelay, ktorá pozdrží vykonávanie konkrétneho tasku po určitú dobu a zároveň zavolá funkciu yield(), ktorá jadru procesora umožní pristúpiť k iným taskom, ktoré obsluhuje (dá im prioritu).

Každá úloha môže mať rôznu prioritu, čím sa úloha stáva dôležitejšia pre jadro procesora, ktorému je pridelená. ESP32 má dvojjadrový procesor Xtensa a tak je možné využívať aj oba jadrá procesora súčasne. Core 0 sa nazýva aj jadro protokolu a beží na ňom primárne Bluetooth a WiFi task, avšak jadro zvládne obsluhovať aj použivateľské programy.  Core 1 je aplikačné jadro a beží na ňom funkcia loop() - funkcie taktiež ako úloha a  toto jadro procesora môže byť využité aj pre ďalšie používateľské podprogramy.

Ukážka efektívneho behu neefektívneho programu vo FreeRTOS:
Čo môže byť lepšia ukážka nezávisleho behu programu pod FreeRTOS ako synchrónne blikanie viacerými LED diódami s funkciou delay()? Pripravil som jednoduchý program, ktorý bliká piatimi LED diódami. Celkovo som vytvoril 5 taskov, každá task bliká jednou LED diódou. Tasky sú vytvorené vo funkcii setup(). Aby LED diódy blikali nepretržite, využil som cyklus while(1) v ktorom bolo nastavenie stavu GPIO a pauza 500 ms cez delay().

Blikanie každej LED diódy je však možné nastaviť na akýkoľvek čas. Jedna dióda môže blikať frekvenciou 10 Hz, iná 1Hz a nebudú sa vzájomne ovlyvňovať aj keď je v jednotlivých úlohách použitá blokovacia funkcia delay(), nakoľko zastaví iba konkrétnu úlohu a nechá procesor obslúžiť ostatné tasky, ktoré bežia na rovnakom jadre. Programová implementácia je veľmi jednoduchá a myslím, že ju zvládnu aj používatelia, ktorí sa s mikrokontrolérmi zoznamujú.

Výhodou je aj to, že program je možné škálovať a rozšíriť o väčší počet LED diód, alebo pridať aj iné funkcionality, napríklad Bluetooth, WiFi komunikáciu v režime klienta / webservera a podobne...

Ako je na obrázku vidieť, všetky tasky súvisiace s blikaním LED diód boli vytvorené na Core 0 a funkcia loop() beží na Core 1, kde je štandardne spustená. Cieľové jadro je možné nastaviť pri vytváraní tasku parametrom 0 / 1, alebo je možné parameter nastaviť na NULL a ESP32 si konkrétne jadro vyberie. V prípade novších ESP32 dosiek iba s jedným jadrom, ktoré je jadrom aplikačným a protokolu zároveň nie je možné nastavovať špecifické jadro.

Program som otestoval v simulátore Wokwi, ktorý plne podporuje najnovšie Arduino Core pre ESP32 - 2.0.3 a je pravidelne aktualizovaný. Treba však podotknúť, že FreeRTOS program je o niečo pomalší ako štandardný program. Aktuálny program sa vykonáva rýchlosťou 24 až 38% reálneho času, nejde tak o real-time simuláciu. Vyskúšajte program s LED diódami v simulátore Wokwi (nevyžaduje sa registrácia): 
https://wokwi.com/projects/334933481929835090

FreeRTOS má mnoho vychytávok s ktorými prichádzajú do kontaktu najmä skúsenejší používatelia. Ide najmä o podmienené spúšťanie a vykonávanie taskov cez FIFO buffer Queue, Semafór, či Mutex. V jednom z prechádzajúcich článkov som implementoval Queue pre inter-task komunikáciu a podmienené vykonávanie tasku pre prenos údajov na vzdialené webové rozhranie po odmeraní dát senzorom HC-SR04 / JSN-SR04T.

Ukážka Queue v Arduino Core pre ESP32 v projekte Hladinomer pre HTTP komunikáciu: 
https://github.com/martinius96/hladinomer-studna-scripty/blob/master/examples/Hladinomer/HTTP/RTOS_ESP32_Arduino/RTOS_ESP32_Arduino.ino

Ukážka Queue v Arduino Core pre ESP32 v projekte Hladinomer pre HTTPS komunikáciu (využíva Root CA certifikát pre SSL spojenie s webserverom): 
https://github.com/martinius96/hladinomer-studna-scripty/blob/master/examples/Hladinomer/HTTPS/RTOS_ESP32_Arduino/RTOS_ESP32_Arduino.ino



Prístupov 807
Kvalita článku
hlasov 0

PRÍSPEVKY
SLEDOVAŤ
Prosím prihláste sa pre možnosť pridania komentáru.
Prihláste sa, alebo použite facebook login facebook login
ĎALŠIE ČLÁNKY V BLOGU
Ako spustiť neefektívny program efektívn...
[ 21.6.2022] (príspevkov 0)
Wokwi - simulátor pre Arduino projekty
[ 14.4.2022] (príspevkov 0)
Ovládanie DC motorov - NodeMCU V2 + moto...
[ 29.1.2022] (príspevkov 0)
Kde hľadať VIN - Zetor UR1
[ 12.1.2022] (príspevkov 0)
Počítadlo otáčok so zastavením motora
[ 7.1.2022] (príspevkov 0)
FreeRTOS v Arduino IDE - ESP32
[ 2.1.2022] (príspevkov 0)
WiFi termostat - Espressif Systems - ESP...
[ 24.12.2021] (príspevkov 0)
ULP aplikácie - ESP8266 / ESP32
[ 14.11.2021] (príspevkov 0)