- Ako funguje RTOS?
- Často používané pojmy v RTOS
- Inštalácia knižnice Arduino FreeRTOS
- Schéma zapojenia
- Príklad Arduino FreeRTOS - vytváranie úloh FreeRTOS v Arduino IDE
- Implementácia úlohy FreeRTOS v Arduino IDE
OS prítomný vo vnútri zabudovaných zariadení sa nazýva RTOS (Real-Time Operating System). Vo vstavaných zariadeniach sú úlohy v reálnom čase rozhodujúce tam, kde časovanie hrá veľmi dôležitú úlohu. Úlohy v reálnom čase sú časovo deterministické, čo znamená, že čas odozvy na každú udalosť je vždy konštantný, aby bolo možné zaručiť, že ku konkrétnej udalosti dôjde v stanovenom čase. RTOS je navrhnutý na prevádzkovanie aplikácií s veľmi presným načasovaním a vysokou mierou spoľahlivosti. RTOS tiež pomáha pri multitaskingu s jedným jadrom.
Už sme prebrali návod, ako používať RTOS vo vstavaných systémoch, kde sa dozviete viac o RTOS, rozdieloch medzi univerzálnym OS a RTOS, rôznych druhoch RTOS atď.
V tejto príručke začneme programom FreeRTOS. FreeRTOS je trieda RTOS pre vstavané zariadenia, ktorá je dostatočne malá na to, aby ju bolo možné prevádzkovať na 8/16-bitových mikrokontroléroch, aj keď sa jej použitie neobmedzuje iba na tieto mikrokontroléry. Je to úplne otvorený zdrojový kód a jeho kód je k dispozícii na stránkach github. Ak poznáme niektoré základné koncepty RTOS, potom je použitie FreeRTOS veľmi jednoduché, pretože má dobre zdokumentované API, ktoré je možné priamo použiť v kóde bez znalosti koncovej časti kódovania. Kompletnú dokumentáciu FreeRTOS nájdete tu.
Pretože FreeRTOS môže bežať na 8-bitovom MCU, môže byť spustený aj na doske Arduino Uno. Musíme si stiahnuť iba knižnicu FreeRTOS a potom začať implementovať kód pomocou API. Tento návod je určený pre úplného začiatočníka. Nižšie sú uvedené témy, ktorým sa budeme venovať v tomto návode pre Arduino FreeRTOS:
- Ako funguje RTOS
- Niektoré často používané výrazy v RTOS
- Inštalácia FreeRTOS do Arduino IDE
- Ako napríklad vytvárať úlohy FreeRTOS
Ako funguje RTOS?
Predtým, ako začneme pracovať s RTOS, pozrime sa, čo je to úloha. Úloha je časť kódu, ktorú je možné naplánovať na vykonanie CPU. Ak teda chcete vykonať určitú úlohu, malo by to byť naplánované pomocou oneskorenia jadra alebo prerušenia. Túto prácu vykonáva plánovač prítomný v jadre. V jednojadrovom procesore plánovač pomáha úlohám vykonávať sa v konkrétnom časovom úseku, ale zdá sa, že rôzne úlohy sa vykonávajú súčasne. Každá úloha beží podľa priority, ktorá je jej daná.
Teraz sa pozrime, čo sa stane v jadre RTOS, ak chceme vytvoriť úlohu pre blikanie LED v sekundovom intervale a dať tejto úlohe najvyššiu prioritu.
Okrem úlohy LED bude v jadre vytvorená ešte jedna úloha, ktorá sa označuje ako nečinná úloha. Nečinná úloha sa vytvorí, keď nie je k dispozícii žiadna úloha na vykonanie. Táto úloha vždy beží s najnižšou prioritou, tj. S prioritou 0. Ak analyzujeme vyššie uvedený časovací graf, je možné vidieť, že vykonávanie sa začína úlohou LED a beží po zadaný čas, potom po zvyšný čas beží nečinná úloha, kým nenastane prerušenie tickom. Potom jadro rozhodne, ktorá úloha sa má vykonať podľa priority úlohy a celkového uplynulého času úlohy LED. Keď je dokončená 1 sekunda, jadro znova vyberie vykonanú úlohu led, pretože má vyššiu prioritu ako nečinná úloha, môžeme tiež povedať, že úloha LED prednostne pred nečinnou úlohou. Ak existujú viac ako dve úlohy s rovnakou prioritou, budú po stanovený čas bežať spôsobom každý s každým.
Pod stavovým diagramom je znázornené prepnutie nebežiacej úlohy do spusteného stavu.
Každá novovytvorená úloha prejde do stavu Pripravený (súčasť nebežiaceho stavu). Pokiaľ má vytvorená úloha (Task1) najvyššiu prioritu ako ostatné úlohy, presunie sa do spusteného stavu. Ak táto spustená úloha predchádza druhá úloha, vráti sa späť do pripraveného stavu. Ak nie je blokovaná úloha1 pomocou blokujúceho rozhrania API, CPU nebude s touto úlohou interagovať, kým vyprší časový limit definovaný používateľom.
Ak je Task1 pozastavená v spustenom stave pomocou Suspend API, potom Task1 prejde do pozastaveného stavu a nie je znova k dispozícii plánovaču. Ak úlohu 1 obnovíte v pozastavenom stave, vráti sa späť do pripraveného stavu, ako vidíte na blokovom diagrame.
Toto je základná myšlienka toho, ako Úlohy prebiehajú a menia svoje stavy. V tomto tutoriále budeme implementovať dve úlohy v Arduino Uno pomocou FreeRTOS API.
Často používané pojmy v RTOS
1. Úloha: Je to kúsok kódu, ktorý je naplánovateľný na vykonanie CPU.
2. Plánovač: Je zodpovedný za výber úlohy zo zoznamu pripravených stavov do stavu spustenia. Plánovače sú často implementované, takže udržujú všetky počítačové zdroje zaneprázdnené (ako pri vyrovnávaní zaťaženia).
3. Preempcia: Jedná sa o akt dočasného prerušenia už vykonávanej úlohy so zámerom jej odstránenia z bežného stavu bez jej súčinnosti.
4. Prepínanie kontextu: V preferencii založenej na prioritách plánovač porovnáva prioritu spustených úloh s prioritou pripraveného zoznamu úloh pri každom prerušení systicku . Ak je v zozname nejaká úloha, ktorej priorita je vyššia ako spustená úloha, dôjde k prepnutiu kontextu. V zásade sa v tomto procese obsah rôznych úloh uloží do príslušnej pamäte zásobníka.
5. Typy politík plánovania:
- Preventívne plánovanie: Pri tomto type plánovania bežia úlohy s rovnakým časovým úsekom bez zohľadnenia priorít.
- Preventívne založené na prioritách : Najprv sa spustí úloha s vysokou prioritou.
- Kooperatívne plánovanie: K prepínaniu kontextu dôjde iba pri spolupráci na prebiehajúcich úlohách. Úloha bude bežať nepretržite, kým sa nevyvolá výnos úlohy.
6. Objekty jadra: Na signalizáciu úlohy, aby vykonala určitú prácu, sa používa proces synchronizácie. Na vykonanie tohto procesu sa používajú objekty jadra. Niektoré objekty jadra sú Udalosti, Semafory, Fronty, Mutex, Poštové schránky atď. Uvidíme, ako tieto objekty použiť v nasledujúcich výučbách.
Z vyššie uvedenej diskusie sme dostali niekoľko základných nápadov o koncepte RTOS a teraz môžeme implementovať projekt FreeRTOS v Arduine. Začnime teda inštaláciou knižníc FreeRTOS v prostredí Arduino IDE.
Inštalácia knižnice Arduino FreeRTOS
1. Otvorte Arduino IDE a choďte na Skica -> Zahrnúť knižnicu -> Spravovať knižnice . Vyhľadajte FreeRTOS a nainštalujte knižnicu, ako je uvedené nižšie.
Knižnicu si môžete stiahnuť z githubu a pridať súbor.zip v aplikácii Sketch-> Include Library -> Add.zip file.
Teraz reštartujte IDE Arduino. Táto knižnica poskytuje ukážkový kód, ktorý tiež nájdete v časti Súbor -> Príklady -> FreeRTOS, ako je uvedené nižšie.
Tu napíšeme kód od nuly, aby sme pochopili fungovanie, neskôr si môžete skontrolovať vzorové kódy a použiť ich.
Schéma zapojenia
Ďalej je uvedená schéma zapojenia pre vytvorenie úlohy Blikajúce LED pomocou FreeRTOS na Arduine:
Príklad Arduino FreeRTOS - vytváranie úloh FreeRTOS v Arduino IDE
Pozrime sa na základnú štruktúru písania projektu FreeRTOS.
1. Najskôr zahrňte hlavičkový súbor Arduino FreeRTOS ako
#include
2. Zadajte funkčný prototyp všetkých funkcií, ktoré píšete na vykonanie a ktoré sú napísané ako
void Task1 (void * pvParameters); void Task2 (void * pvParameters); .. ….
3. Teraz vo funkcii void setup () vytvorte úlohy a spustite plánovač úloh.
Na vytvorenie úlohy sa vo funkcii nastavenia volá API xTaskCreate () s určitými parametrami / argumentmi.
xTaskCreate (TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask);
Pri vytváraní akejkoľvek úlohy by malo byť predložených 6 argumentov. Pozrime sa, čo sú tieto argumenty
- pvTaskCode: Je to jednoducho ukazovateľ na funkciu, ktorá úlohu implementuje (v skutočnosti iba názov funkcie).
- pcName: Popisný názov úlohy. FreeRTOS to nepoužíva. Je zahrnutý iba na účely ladenia.
- usStackDepth: Každá úloha má svoj vlastný jedinečný zásobník, ktorý je pri vytváraní úlohy alokovaný jadrom k úlohe. Hodnota určuje počet slov, ktoré môže zásobník obsahovať, nie počet bajtov. Napríklad, ak je zásobník široký 32 bitov a hodnota usStackDepth je odovzdaná ako 100, bude v RAM pridelených 400 bajtov úložného priestoru (100 * 4 bajty). Používajte to s rozumom, pretože Arduino Uno má iba 2 kB RAM.
- pvParameters: Vstupný parameter úlohy (môže mať hodnotu NULL).
- uxPriority: Priorita úlohy (0 má najnižšiu prioritu).
- pxCreatedTask: Môže sa použiť na rozdávanie popisovača vytváranej úlohe. Tento popisovač sa potom dá použiť na odkazovanie na úlohu vo volaniach API, ktoré napríklad zmenia prioritu úlohy alebo odstránia úlohu (môže mať NULL).
Ukážka vytvorenia úlohy
xTaskCreate (task1, "task1", 128, NULL, 1, NULL); xTaskCreate (task2, "task2", 128, NULL, 2, NULL);
Tu má úloha 2 vyššiu prioritu, a preto sa vykoná prvá.
4. Po vytvorení úlohy spustite plánovač v nastavení neplatnosti pomocou vTaskStartScheduler (); API.
5. Funkcia Void loop () zostane prázdna, pretože nechceme spustiť žiadnu úlohu manuálne a nekonečne. Pretože vykonávanie úloh teraz rieši Plánovač.
6. Teraz musíme implementovať funkcie úloh a do týchto funkcií napísať logiku, ktorú chcete vykonať. Názov funkcie by mal byť rovnaký ako prvý argument rozhrania xTaskCreate () API.
void task1 (void * pvParameters) { while (1) { .. ..//y your logic } }
7. Väčšina kódu potrebuje na zastavenie bežiacej úlohy funkciu oneskorenia, ale v RTOS sa neodporúča používať funkciu Delay (), pretože zastaví CPU, a preto prestane fungovať aj RTOS. FreeRTOS má teda jadro API na blokovanie úlohy na konkrétny čas.
vTaskDelay (const TickType_t xTicksToDelay);
Toto API je možné použiť na účely oneskorenia. Toto API oneskoruje úlohu o daný počet kliešťov. Skutočný čas, po ktorý zostane úloha zablokovaná, závisí od rýchlosti zaškrtnutia. Konštantný portTICK_PERIOD_MS je možné použiť na výpočet v reálnom čase z hodnoty ticku.
To znamená, že ak chcete oneskorenie 200 ms, stačí napísať tento riadok
vTaskDelay (200 / portTICK_PERIOD_MS);
Pre tento tutoriál teda použijeme tieto API FreeRTOS na implementáciu troch úloh.
Rozhrania API, ktoré sa majú použiť:
- xTaskCreate ();
- vTaskStartScheduler ();
- vTaskDelay ();
Úloha, ktorá sa má vytvoriť pre tento tutoriál:
- LED bliká na digitálnom kolíku 8 s frekvenciou 200 ms
- LED bliká na digitálnom kolíku 7 s frekvenciou 300 ms
- Tlačte čísla na sériovom monitore s frekvenciou 500 ms.
Implementácia úlohy FreeRTOS v Arduino IDE
1. Z vyššie uvedeného vysvetlenia základnej štruktúry zahrňte hlavičkový súbor Arduino FreeRTOS. Potom vytvorte funkčné prototypy. Pretože máme tri úlohy, urobte tri funkcie a sú to prototypy.
#include void TaskBlink1 (void * pvParameters); void TaskBlink2 (void * pvParameters); void Taskprint (void * pvParameters);
2. Vo funkcii void setup () inicializujte sériovú komunikáciu rýchlosťou 9600 bitov za sekundu a vytvorte všetky tri úlohy pomocou rozhrania xTaskCreate () API. Spočiatku nastavte priority všetkých úloh na „1“ a spustite plánovač.
void setup () { Serial.begin (9600); xTaskCreate (TaskBlink1, "Task1", 128, NULL, 1, NULL); xTaskCreate (TaskBlink2, "Task2", 128, NULL, 1, NULL); xTaskCreate (Taskprint, "Task3", 128, NULL, 1, NULL); vTaskStartScheduler (); }
3. Teraz implementujte všetky tri funkcie, ktoré sú zobrazené nižšie, aby LED dióda task1 blikala.
void TaskBlink1 (void * pvParameters) { pinMode (8, OUTPUT); while (1) { digitalWrite (8, HIGH); vTaskDelay (200 / portTICK_PERIOD_MS); digitalWrite (8, LOW); vTaskDelay (200 / portTICK_PERIOD_MS); } }
Podobne implementujte funkciu TaskBlink2. Funkcia Task3 bude napísaná ako
void Taskprint (void * pvParameters) { int counter = 0; while (1) { counter ++; Serial.println (počítadlo); vTaskDelay (500 / portTICK_PERIOD_MS); } }
To je všetko. Úspešne sme dokončili projekt FreeRTOS Arduino pre Arduino Uno. Celý kód spolu s videom nájdete na konci tohto tutoriálu.
Nakoniec pripojte dve LED diódy na digitálny pin 7 a 8 a nahrajte kód na dosku Arduino a otvorte sériový monitor. Uvidíte, že počítadlo beží raz za 500 ms s názvom úlohy, ako je uvedené nižšie.
Sledujte tiež LED diódy, ktoré blikajú v rôznych časových intervaloch. Skúste sa pohrať s argumentom priority vo funkcii xTaskCreate . Zmeňte počet a sledujte správanie na sériovom monitore a LED diódach.
Teraz môžete pochopiť prvé dva vzorové kódy, v ktorých sa vytvárajú úlohy analógového a digitálneho čítania. Týmto spôsobom môžete uskutočňovať viac pokrokových projektov pomocou iba rozhraní Arduino Uno a FreeRTOS API.