FreeRTOS v Arduino IDE - ESP32
Operačný systém reálneho času FreeRTOS som na mojom sector blogu spomínal už v minulosti v súvislosti s experimentálnou implementáciou senzorového uzla na ESP32 pre projekt Hladinomer vo frameworku ESP-IDF. Dnes si skúsime úpravy programu do špecifík FreeRTOS bližšie predstaviť. Upravovať budeme existujúcu implementáciu senzorového uzla projektu Hladinomer (ESP32) v prostredí Arduino IDE. Treba však poznamenať, že Arduino IDE umožňuje pristúpiť iba k vyšším vrstvám mikrokontroléra a nie je v ňom možné robiť tak komplexné programy ako v ESP-IDF.
Arduino Core pre ESP32 je vlastne wrapper, ktorý spúšťa isté komponenty ESP-IDF. Programovanie je tak jednoduchšie, avšak programátor nemá takú kontrolu nad hardvérom, Arduino Core je tak vhodné pre prototypovanie. Arduino Core neumožňuje využívať ULP koprocesor, ani prácu s rôznými hardvérovými funkcionalitami napr. Secure Boot, či Flash Encryption, ktoré sú natívne podporované v ESP-IDF. ESP32 je mikrokontróler z produkcie čínskej firmy Espressif Systems.
Existuje mnoho modulov s týmto čipom. V dnešnom tutoriáli sa budeme držať najdostupnejšieho (a najlacnejšieho) modulu ESP32-WROOM-32. Modul je vybavený dvojjadrovým procesorom Tensilica Xtensa L6 harvardskej architektúry. Má externú flash pamäť s veľkosťou 4 MB a 512 kB dostupnej RAM pamäte (pre viac technických údajov pozri dokumentáciu).
![](https://392a561660.cbaul-cdnwnd.com/6b24fd06728cdbacb72a3228f095e765/200000380-0fc5f0fc61/ESP_SCHEME.jpg?ph=392a561660)
Hlavný procesor Xtensa môže realizovať výpočty, komunikáciu so senzormi a perifériami, s ktorými je mikrokontróler prepojený cez dostupné zbernice. Zároveň však riadi a obsluhuje aj WiFi / Bluetooth zásobník (stack) pre zabezpečenie konektivity. Za správu a obsluhu WiFi / Bluetooth zásobníka zodpovedá jedno z jadier procesora u ktorého má WiFi / Bluetooth zásobník maximálnu prioritu.
Jadrá sa najčastejšie označujú ako Core 0 (PRO_CPU) a Core 1 (APP_CPU). Na Core 1 štandardne beží používateľská aplikácia vo forme úlohy (tasku). Málokto vie, že funkcia void loop() - nekonečná slučka funguje v Arduino Core ako task. Rovnakým spôsobom funguje aj funkcia app_main() v prostredí frameworku ESP-IDF. Po vytvorení hlavného tasku je možné vytvárať aj iné tasky prostredníctvom plánovača FreeRTOS a spúšťať ich tak efektívne na jadre procesora s určitou prioritou.
Takto napísaný program nebude blokovať vykonávanie iných taskov, napríklad funkciou delay(), ktorá zastaví celý program pri štandardnom programovaní v Arduino IDE. Nakoľko v našom prípade potrebujeme pre aplikáciu hladinomera merať výšku hladiny vody prostredníctvom ultrazvukového senzora vzdialenosti a následne dáta zapisovať do vzdialeného webového rozhrania je vhodné vytvoriť 2 tasky. Aby odosielací task nadväzoval na prijaté dáta, využijeme blokovací mechanizmus Queue - FIFO buffer. Buffer bude mať celkovo veľkosť 20 prvkov typu INT (2 bajty).
Bloková schéma Queue FIFO buffra
![](https://392a561660.cbaul-cdnwnd.com/6b24fd06728cdbacb72a3228f095e765/200000381-1dbbe1dbbf/buffer.png?ph=392a561660)
Oba tasky je možné spúšťať na rovnakom jadre, alebo je ich možné rozdeliť na samostatné jadrá procesora Xtensa. Task komunikujúci cez WiFi je vhodné spustiť na Core 0 - jadro protokolu, kde beží WiFi stack. Task vykonávajúci meranie ultrazvukovým senzorom vzdialenosti spustíme na Core 1 - aplikačnom jadre, kde beží aj hlavný task - funkcia void loop().
Task 1 (producer task - tvorí dáta)
- Vykonáva meranie ultrazvukovým senzorom vzdialenosti
- Zapisuje hodnotu int do fronty
- Queue Čaká 300 sekúnd
![](https://392a561660.cbaul-cdnwnd.com/6b24fd06728cdbacb72a3228f095e765/200000382-f368ff3691/t1.png?ph=392a561660)
Task 2 (consumer task - používa dáta)
- Čaká v "nekonečnej slučke" na dáta vo fronte Queue
- Po prijatí dát vykoná jeden HTTP(S) POST request s dátami na webserver
![](https://392a561660.cbaul-cdnwnd.com/6b24fd06728cdbacb72a3228f095e765/200000383-d7693d7695/t2.png?ph=392a561660)
Webserver (PHP backend) po prijatí dát vykoná porovnanie API kľúča mikrokontroléra, v prípade, že je autentizovaný a od posledného zápisu ubehlo aspoň 300 sekúnd, vykoná sa zápis dát o výške hladiny vody do MySQL databázy. Dáta sú ihneď viditeľné používateľovi na webovom rozhraní Hladinomera v dashboarde s automatickým refreshom dát cez jQuery.
Bežiaca aplikácia s 2 taskami - FreeRTOS (vrátane Core Debug Level Verbose) - HTTP
![](https://392a561660.cbaul-cdnwnd.com/6b24fd06728cdbacb72a3228f095e765/200000384-9e8d89e8da/http.png?ph=392a561660)
Bežiaca aplikácia s 2 taskami - FreeRTOS (vrátane Core Debug Level Verbose) - HTTPS
![](https://392a561660.cbaul-cdnwnd.com/6b24fd06728cdbacb72a3228f095e765/200000385-83b3983b3b/https.png?ph=392a561660)
Projekt Hladinomer má vlastnú stránku, kde je možné nájsť technické informácie projektu, spôsob a početnosť meraní ultrazvukovým senzorom vzdialenosti, možnosť stiahnuť jednotlivé knižnice (NewPing, Ethernet2 pre Arduino a pod..): https://martinius96.github.io/hladinomer-studna-scripty/