- Jak funguje RTOS?
- Často používané termíny v RTOS
- Instalace knihovny Arduino FreeRTOS
- Kruhový diagram
- Příklad Arduino FreeRTOS - Vytváření úkolů FreeRTOS v Arduino IDE
- Implementace úlohy FreeRTOS v Arduino IDE
OS přítomný uvnitř vestavěných zařízení se nazývá RTOS (Real-Time Operating System). Ve vestavěných zařízeních jsou úkoly v reálném čase zásadní, kde načasování hraje velmi důležitou roli. Real-time tasks are Time Deterministic means the response time to any event is always constant so that it can be guaranteed that any specific event will occurs at a fixed time. RTOS je navržen pro spouštění aplikací s velmi přesným načasováním a vysokou mírou spolehlivosti. RTOS také pomáhá při multitaskingu s jedním jádrem.
Již jsme probrali návod, jak používat RTOS ve vestavěných systémech, kde se dozvíte více o RTOS, rozdílu mezi univerzálním OS a RTOS, různých typech RTOS atd.
V tomto kurzu začneme s FreeRTOS. FreeRTOS je třída RTOS pro vestavěná zařízení, která je dostatečně malá na to, aby ji bylo možné provozovat na 8 / 16bitových mikrokontrolérech, i když její použití není omezeno na tyto mikrokontroléry. Je to zcela open-source a jeho kód je k dispozici na github. Pokud známe některé základní koncepty RTOS, pak je velmi snadné použít FreeRTOS, protože má dobře zdokumentované API, které lze přímo použít v kódu, aniž byste věděli o backendové části kódování. Kompletní dokumentaci FreeRTOS najdete zde.
Protože FreeRTOS může běžet na 8bitovém MCU, může být spuštěn také na desce Arduino Uno. Musíme si jen stáhnout knihovnu FreeRTOS a poté začít implementovat kód pomocí API. Tento kurz je určen pro úplného začátečníka, níže jsou témata, kterým se budeme věnovat v tomto kurzu Arduino FreeRTOS:
- Jak funguje RTOS
- Některé často používané termíny v RTOS
- Instalace FreeRTOS do Arduino IDE
- Jak vytvořit úkoly FreeRTOS s příkladem
Jak funguje RTOS?
Než začneme pracovat s RTOS, podívejme se, co je to úkol. Úkol je část kódu, který je na CPU naplánovatelný k provedení. Pokud tedy chcete provést nějaký úkol, měl by být naplánován pomocí zpoždění jádra nebo pomocí přerušení. Tuto práci provádí plánovač přítomný v jádře. V jednojádrovém procesoru plánovač pomáhá úkolům provádět v určitém časovém úseku, ale zdá se, že různé úkoly se provádějí současně. Každý úkol běží podle priority, která mu byla dána.
Nyní se podívejme, co se stane v jádru RTOS, pokud chceme vytvořit úkol pro blikání LED s intervalem jedné sekundy a dát tomuto úkolu nejvyšší prioritu.
Kromě úlohy LED bude jádrem vytvořena ještě jedna úloha, která se označuje jako nečinná úloha. Nečinná úloha se vytvoří, když není k dispozici žádná úloha k provedení. Tento úkol běží vždy s nejnižší prioritou, tj. Prioritou 0. Pokud analyzujeme výše uvedený časovací graf, je možné vidět, že spuštění začíná úkolem LED a běží po stanovenou dobu, pak po zbývající dobu běží nečinná úloha, dokud nedojde k přerušení klíště. Poté jádro rozhodne, který úkol má být proveden podle priority úkolu a celkového uplynulého času úkolu LED. Když je dokončena 1 sekunda, jádro znovu zvolí led úlohu, kterou má provést, protože má vyšší prioritu než nečinná úloha, můžeme také říci, že LED úloha přednostní nečinnou úlohu. Pokud existují více než dva úkoly se stejnou prioritou, budou po stanovenou dobu běžet způsobem každý s každým.
Pod stavovým diagramem ukazuje přepnutí neběžícího úkolu do běžícího stavu.
Každá nově vytvořená úloha přejde do stavu Připraveno (součást neběžícího stavu). Pokud má vytvořená úloha (Task1) nejvyšší prioritu než ostatní úkoly, přejde do běžícího stavu. Pokud tento běžící úkol předjímá druhý úkol, vrátí se zpět do připraveného stavu znovu. Jinak, pokud je task1 blokován pomocí blokujícího API, pak CPU nebude s touto úlohou interagovat, dokud časový limit definovaný uživatelem.
Pokud je Task1 pozastaven v běžícím stavu pomocí Suspend API, pak Task1 přejde do pozastaveného stavu a není plánovači znovu k dispozici. Pokud Task1 obnovíte v pozastaveném stavu, vrátí se zpět do připraveného stavu, jak vidíte v blokovém diagramu.
Toto je základní myšlenka toho, jak Úkoly běží a mění své stavy. V tomto kurzu implementujeme dva úkoly v Arduino Uno pomocí FreeRTOS API.
Často používané termíny v RTOS
1. Úkol: Jedná se o část kódu, kterou lze na CPU naplánovat.
2. Plánovač: Je odpovědný za výběr úkolu ze seznamu připravených stavů do provozního stavu. Plánovače jsou často implementovány, takže udržují zaneprázdněné všechny prostředky počítače (jako při vyrovnávání zatížení).
3. Preemption: Jde o akt dočasného přerušení již prováděného úkolu se záměrem jeho odstranění z běžícího stavu bez jeho spolupráce.
4. Přepínání kontextu: V preempci založené na prioritách plánovač porovnává prioritu spuštěných úkolů s prioritou seznamu připravených úkolů při každém přerušení systicku . Pokud je v seznamu nějaký úkol, jehož priorita je vyšší než spuštěný úkol, dojde k přepnutí kontextu. V zásadě se v tomto procesu ukládá obsah různých úkolů do příslušné paměti zásobníku.
5. Druhy zásad plánování:
- Preventivní plánování: U tohoto typu plánování běží úkoly se stejným časovým úsekem bez ohledu na priority.
- Preemptivní na základě priorit: Úkol s vysokou prioritou se spustí jako první.
- Kooperativní plánování: K přepínání kontextu dojde pouze při spolupráci spuštěných úkolů. Úkol bude probíhat nepřetržitě, dokud nebude vyvolán výnos úkolu.
6. Objekty jádra: K signalizaci úkolu k provedení určité práce se používá proces synchronizace. K provedení tohoto procesu se používají objekty jádra. Některé objekty jádra jsou Události, Semafory, Fronty, Mutex, Poštovní schránky atd. Uvidíme, jak tyto objekty použít v nadcházejících cvičeních.
Z výše uvedené diskuse jsme dostali několik základních představ o konceptu RTOS a nyní můžeme implementovat projekt FreeRTOS v Arduinu. Pojďme tedy začít instalací knihoven FreeRTOS v Arduino IDE.
Instalace knihovny Arduino FreeRTOS
1. Otevřete Arduino IDE a přejděte na Skica -> Zahrnout knihovnu -> Spravovat knihovny . Vyhledejte FreeRTOS a nainstalujte knihovnu, jak je znázorněno níže.
Knihovnu si můžete stáhnout z githubu a přidat soubor ZIP v aplikaci Sketch-> Include Library -> Add.zip file.
Nyní restartujte IDE Arduino. Tato knihovna poskytuje ukázkový kód, který také najdete v nabídce Soubor -> Příklady -> FreeRTOS, jak je uvedeno níže.
Zde napíšeme kód od začátku, abychom porozuměli fungování, později si můžete zkontrolovat vzorové kódy a použít je.
Kruhový diagram
Níže je schéma zapojení pro vytvoření úlohy Blikající LED pomocí FreeRTOS na Arduinu:
Příklad Arduino FreeRTOS - Vytváření úkolů FreeRTOS v Arduino IDE
Podívejme se na základní strukturu pro napsání projektu FreeRTOS.
1. Nejprve přidejte soubor záhlaví Arduino FreeRTOS jako
#zahrnout
2. Uveďte prototyp funkce všech funkcí, které píšete k provedení a které jsou zapsány jako
void Task1 (void * pvParameters); void Task2 (void * pvParameters); .. ….
3. Nyní ve funkci void setup () vytvořte úkoly a spusťte plánovač úloh.
Pro vytvoření úlohy se volá xTaskCreate () API ve funkci nastavení s určitými parametry / argumenty.
xTaskCreate (TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask);
Při vytváření libovolného úkolu by mělo být předáno 6 argumentů. Podívejme se, jaké jsou tyto argumenty
- pvTaskCode: Je to prostě ukazatel na funkci, která úkol implementuje (ve skutečnosti pouze název funkce).
- pcName: Popisný název úkolu. To FreeRTOS nepoužívá. Je zahrnuta čistě pro účely ladění.
- usStackDepth: Každý úkol má svůj vlastní jedinečný zásobník, který je jádru přidělen úkolu při jeho vytvoření. Hodnota určuje počet slov, která může zásobník obsahovat, nikoli počet bajtů. Například pokud je zásobník široký 32 bitů a usStackDepth je předán jako 100, bude v paměti RAM přiděleno 400 bajtů prostoru zásobníku (100 * 4 bajty). Použijte to moudře, protože Arduino Uno má pouze 2 kB paměti RAM.
- pvParameters: Vstupní parametr úlohy (může mít hodnotu NULL).
- uxPriority: Priorita úkolu (0 je nejnižší priorita).
- pxCreatedTask: Lze jej použít k předání popisovače vytvářenému úkolu. Tento popisovač lze poté použít k odkazování na úkol ve voláních API, která například mění prioritu úkolu nebo odstraňují úkol (může mít hodnotu NULL).
Příklad vytvoření úkolu
xTaskCreate (task1, "task1", 128, NULL, 1, NULL); xTaskCreate (task2, "task2", 128, NULL, 2, NULL);
Tady má Task2 vyšší prioritu, a proto se provede jako první.
4. Po vytvoření úlohy spusťte plánovač v nastavení neplatnosti pomocí vTaskStartScheduler (); API.
5. Funkce Void loop () zůstane prázdná, protože nechceme spouštět žádné úlohy ručně a nekonečně. Protože spuštění úlohy nyní zpracovává plánovač.
6. Nyní musíme implementovat funkce úkolů a do těchto funkcí napsat logiku, kterou chcete provést. Název funkce by měl být stejný jako první argument rozhraní xTaskCreate () API.
void task1 (void * pvParameters) { while (1) { .. ..//y your logic } }
7. Většina kódu potřebuje funkci zpoždění k zastavení běžící úlohy, ale v RTOS se nedoporučuje používat funkci Delay (), protože zastaví CPU, a proto RTOS také přestane fungovat. FreeRTOS má tedy API jádra, které blokuje úkol na určitou dobu.
vTaskDelay (const TickType_t xTicksToDelay);
Toto API lze použít pro účely zpoždění. Toto API zpožďuje úkol o daný počet klíšťat. Skutečná doba, po kterou úkol zůstane blokován, závisí na rychlosti zaškrtnutí. Konstantní portTICK_PERIOD_MS lze použít k výpočtu v reálném čase z kurzu tick.
To znamená, že pokud chcete zpoždění 200 ms, stačí napsat tento řádek
vTaskDelay (200 / portTICK_PERIOD_MS);
Takže pro tento tutoriál použijeme tato FreeRTOS API k implementaci tří úkolů.
Rozhraní API, která se mají použít:
- xTaskCreate ();
- vTaskStartScheduler ();
- vTaskDelay ();
Úkol, který má být vytvořen pro tento kurz:
- LED bliká na digitálním kolíku 8 s frekvencí 200 ms
- LED bliká na digitálním kolíku 7 s frekvencí 300 ms
- Tiskněte čísla na sériovém monitoru s frekvencí 500 ms.
Implementace úlohy FreeRTOS v Arduino IDE
1. Z výše uvedeného základního vysvětlení struktury zahrňte soubor záhlaví Arduino FreeRTOS. Poté vytvořte funkční prototypy. Jelikož máme tři úkoly, vytvořte tři funkce a jejich prototypy.
#include void TaskBlink1 (void * pvParameters); void TaskBlink2 (void * pvParameters); void Taskprint (void * pvParameters);
2. Ve funkci void setup () inicializujte sériovou komunikaci rychlostí 9600 bitů za sekundu a vytvořte všechny tři úkoly pomocí rozhraní xTaskCreate () API. Zpočátku udělejte priority všech úkolů jako „1“ a spusťte 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. Nyní implementujte všechny tři funkce, jak je znázorněno níže, pro blikání LED úlohy 1.
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); } }
Podobně implementujte funkci TaskBlink2. Funkce Task3 bude zapsána jako
void Taskprint (void * pvParameters) { int counter = 0; while (1) { counter ++; Serial.println (čítač); vTaskDelay (500 / portTICK_PERIOD_MS); } }
A je to. Úspěšně jsme dokončili projekt FreeRTOS Arduino pro Arduino Uno. Celý kód spolu s videem najdete na konci tohoto kurzu.
Nakonec připojte dvě LED diody k digitálnímu kolíku 7 a 8 a nahrajte kód na desku Arduino a otevřete sériový monitor. Uvidíte, že počítadlo běží jednou za 500 ms s názvem úkolu, jak je uvedeno níže.
Sledujte také LED diody, které blikají v různých časových intervalech. Zkuste si zahrát s prioritním argumentem ve funkci xTaskCreate . Změňte počet a sledujte chování sériového monitoru a kontrolek LED.
Nyní můžete pochopit první dva vzorové kódy, ve kterých jsou vytvářeny úlohy analogového čtení a digitálního čtení. Tímto způsobem můžete provádět další pokrokové projekty pouze pomocí rozhraní Arduino Uno a FreeRTOS API.