Operační systém v reálném čase - Real-time operating system

Operační systém v reálném čase ( RTOS ) je operační systém (OS), který má sloužit v reálném čase aplikace, které zpracovávají údaje, jak to přichází v, typicky bez pufru zpoždění. Požadavky na dobu zpracování (včetně jakéhokoli zpoždění operačního systému) se měří v desetinách sekund nebo kratších časových přírůstcích. Systém v reálném čase je systém vázaný na čas, který má dobře definovaná, pevná časová omezení. Zpracování musí být provedeno v rámci definovaných omezení, jinak systém selže. Buď jsou řízeny událostmi, nebo sdílejí čas . Systémy řízené událostmi přepínají mezi úkoly na základě jejich priorit, zatímco systémy pro sdílení času přepínají úlohu na základě přerušení hodin . Většina RTOS používá preventivní plánovací algoritmus.

Charakteristika

Klíčovou charakteristikou RTOS je úroveň jeho konzistence týkající se množství času potřebného k přijetí a dokončení úkolu aplikace ; variabilita je „ chvění “. „Tvrdý“ operační systém v reálném čase (Hard RTOS) má menší jitter než „měkký“ operační systém v reálném čase (Soft RTOS). Pozdní odpověď je špatná odpověď v tvrdém RTOS, zatímco pozdní odpověď je přijatelná v měkkém RTOS. Hlavním cílem designu není vysoká propustnost , ale spíše záruka kategorie měkkého nebo tvrdého výkonu. RTOS, který obvykle nebo obecně může splnit termín, je měkký OS v reálném čase, ale pokud dokáže termín splnit deterministicky , je to tvrdý OS v reálném čase.

RTOS má pokročilý algoritmus pro plánování . Flexibilita plánovače umožňuje širší orchestraci priorit procesů v počítačovém systému, ale OS v reálném čase se častěji věnuje úzké sadě aplikací. Klíčovými faktory v reálném čase OS jsou minimální latence přerušení a minimální latence přepínání vláken ; OS v reálném čase je ceněn více za to, jak rychle nebo předvídatelně může reagovat, než za množství práce, které může v daném časovém období vykonat.

Úplný seznam najdete ve srovnání operačních systémů v reálném čase . Podívejte se také na seznam operačních systémů pro všechny typy operačních systémů.

Filozofie designu

RTOS je operační systém, ve kterém je doba potřebná ke zpracování vstupního podnětu kratší než doba, která uplynula do dalšího vstupního podnětu stejného typu.

Nejběžnější návrhy jsou:

  • Řízené událostmi- přepíná úkoly pouze v případě, že událost s vyšší prioritou vyžaduje servis; nazývá se preemptivní priorita nebo prioritní plánování.
  • Sdílení času-přepíná úkoly na pravidelné taktované přerušení a na události; zvané round robin .

Návrhy sdílení času přepínají úkoly častěji, než je nezbytně nutné, ale poskytují plynulejší multitasking , což vytváří iluzi, že proces nebo uživatel používá výhradně stroj.

Počáteční návrhy CPU vyžadovaly mnoho cyklů na přepnutí úkolů, během nichž CPU nemohl dělat nic jiného užitečného. Protože přepínání trvalo tak dlouho, rané operační systémy se snažily minimalizovat plýtvání časem CPU tím, že se vyhnuli zbytečnému přepínání úkolů.

Plánování

V typických provedeních má úkol tři stavy:

  1. Spuštěno (spuštěno na CPU);
  2. Připraveno (připraveno k provedení);
  3. Blokováno (čekání na událost, například I/O).

Většina úkolů je blokována nebo připravena po většinu času, protože obecně lze na jeden procesor spustit současně pouze jeden úkol . Počet položek ve frontě připravených se může velmi lišit v závislosti na počtu úkolů, které systém potřebuje k provedení, a na typu plánovače, který systém používá. Na jednodušších nepřehledných, ale stále víceúlohových systémech se úkol musí vzdát svého času na CPU jiným úkolům, což může způsobit, že připravená fronta bude mít ve stavu připraveném ke spuštění větší počet celkových úkolů ( hladovění zdrojů ) .

Struktura dat připraveného seznamu v plánovači je obvykle navržena tak, aby se minimalizovala doba nejhoršího případu strávená v kritické části plánovače, během níž je předjímání zakázáno, a v některých případech jsou všechna přerušení zakázána, ale volba datová struktura závisí také na maximálním počtu úkolů, které mohou být na seznamu připravených.

Pokud na seznamu připravených není nikdy více než několik úkolů, je pravděpodobně optimální dvojitě propojený seznam připravených úkolů. Pokud seznam připravených obvykle obsahuje pouze několik úkolů, ale příležitostně obsahuje více, měl by být seznam seřazen podle priority. Hledání úlohy s nejvyšší prioritou tak nevyžaduje iteraci celého seznamu. Vložení úkolu pak vyžaduje procházení připraveného seznamu, dokud nedosáhnete buď konce seznamu, nebo úkolu s nižší prioritou, než má vložený úkol.

Během tohoto hledání je třeba dávat pozor, aby se nebránila preemption. Delší kritické úseky by měly být rozděleny na malé kousky. Pokud dojde k přerušení, které připraví úkol s vysokou prioritou během vkládání úkolu s nízkou prioritou, lze tento úkol s vysokou prioritou vložit a spustit bezprostředně před vložením úkolu s nízkou prioritou.

Kritická doba odezvy, někdy nazývaná doba zpětného letu, je doba potřebná k zařazení nové připravené úlohy do fronty a obnovení stavu úlohy s nejvyšší prioritou. V dobře navrženém RTOS bude příprava nového úkolu trvat 3 až 20 instrukcí na jeden záznam připravené fronty a obnovení připraveného úkolu s nejvyšší prioritou bude trvat 5 až 30 instrukcí.

V pokročilejších systémech úkoly v reálném čase sdílejí výpočetní prostředky s mnoha úkoly, které nejsou v reálném čase, a připravený seznam může být libovolně dlouhý. V takových systémech by byl seznam připravený pro plánovač implementovaný jako propojený seznam neadekvátní.

Algoritmy

Některé běžně používané algoritmy plánování RTOS jsou:

Komunikace mezi úkoly a sdílení zdrojů

Víceúlohový operační systém, jako je Unix, je chudý na úkoly v reálném čase. Plánovač dává nejvyšší prioritu úlohám s nejnižší poptávkou po počítači, takže neexistuje způsob, jak zajistit, aby časově kritická úloha měla přístup k dostatečným zdrojům. Multitaskingové systémy musí spravovat sdílení datových a hardwarových prostředků mezi více úkoly. Obvykle není bezpečné, aby dva úkoly přistupovaly ke stejným konkrétním datovým nebo hardwarovým prostředkům současně. K vyřešení tohoto problému existují tři běžné přístupy:

Dočasné maskování/deaktivace přerušení

Univerzální operační systémy obvykle neumožňují uživatelským programům maskovat (deaktivovat) přerušení , protože uživatelský program mohl ovládat CPU tak dlouho, jak si přeje. Některé moderní procesory neumožňují kódu uživatelského režimu deaktivovat přerušení, protože taková kontrola je považována za klíčový prostředek operačního systému. Mnoho vestavěných systémů a RTOS však umožňuje samotné aplikaci běžet v režimu jádra pro větší efektivitu systémových volání a také pro aplikaci, aby měla větší kontrolu nad operačním prostředím bez nutnosti zásahu operačního systému.

V systémech s jedním procesorem je aplikace běžící v režimu jádra a maskování přerušení nejnižší metodou režie, která zabrání současnému přístupu ke sdílenému prostředku. Zatímco přerušení jsou maskována a aktuální úloha nevytváří blokovací volání operačního systému, aktuální úloha má výlučné využití CPU, protože žádný jiný úkol nebo přerušení nemůže převzít kontrolu, takže je kritická část chráněna. Když úkol opustí kritickou část, musí odmaskovat přerušení; případná čekající přerušení se poté spustí. Dočasné maskování přerušení by mělo být prováděno pouze tehdy, když je nejdelší cesta přes kritický úsek kratší než požadovaná maximální latence přerušení . Tento způsob ochrany se obvykle používá pouze v případě, že kritická část obsahuje jen několik pokynů a neobsahuje žádné smyčky. Tato metoda je ideální pro ochranu hardwarových bitově mapovaných registrů, když jsou bity řízeny různými úkoly.

Mutexy

Když musí být sdílený prostředek rezervován bez blokování všech ostatních úkolů (například čekání na zápis paměti Flash), je lepší použít mechanismy dostupné také v operačních systémech pro obecné účely, jako je meziprocesové zasílání zpráv mutex a OS. Takové mechanismy zahrnují systémová volání a obvykle při ukončení vyvolávají dispečerský kód operačního systému, takže ke spuštění obvykle potřebují stovky instrukcí CPU, zatímco maskování přerušení může u některých procesorů trvat jen jednu instrukci.

(Ne rekurzivní) mutex je buď zamčený, nebo odemčený. Když úkol zamkne mutex, všechny ostatní úkoly musí počkat, až mutex odemkne jeho vlastník - původní vlákno. Úkol může nastavit časový limit čekání na mutex. Existuje několik dobře známých problémů s návrhy založenými na mutexu, jako je prioritní inverze a zablokování .

Při inverzi priority čeká úkol s vysokou prioritou, protože úkol s nízkou prioritou má mutex, ale úkolu s nižší prioritou není CPU věnován čas na dokončení práce. Typickým řešením je nechat úkol, který vlastní mutex, „zdědit“ prioritu nejvyššího čekajícího úkolu. Ale tento jednoduchý přístup dostane složitější, pokud existuje více úrovní čeká: úkol A čeká na mutex uzamčen úkol B , který čeká na mutex uzamčen úkol C . Zpracování více úrovní dědičnosti způsobí, že se jiný kód spustí v kontextu s vysokou prioritou, a proto může způsobit hladovění vláken se střední prioritou.

V zablokování dva nebo více úkolů uzamkne mutex bez časových limitů a pak navždy čeká na mutex druhého úkolu, čímž vzniká cyklická závislost. Nejjednodušší scénář zablokování nastane, když dva úkoly střídavě zamknou dva mutex, ale v opačném pořadí. Deadlock je zabráněno pečlivým designem.

Předávání zpráv

Druhý přístup ke sdílení zdrojů je pro úkoly k odesílání zpráv v organizovaném schématu předávání zpráv . V tomto paradigmatu je zdroj spravován přímo pouze jedním úkolem. Když jiný úkol chce dotazovat nebo manipulovat se zdrojem, odešle zprávu řídícímu úkolu. Přestože jejich chování v reálném čase je méně ostré než systémy semaforů , jednoduché systémy založené na zprávách se vyhýbají většině nebezpečí zablokování protokolů a obecně se chovají lépe než systémy semaforů. Problémy jako ty u semaforů jsou však možné. Inverze priority může nastat, když úkol pracuje na zprávě s nízkou prioritou a ve své frontě příchozích zpráv ignoruje zprávu s vyšší prioritou (nebo zprávu pocházející nepřímo z úkolu s vysokou prioritou). K zablokování protokolu může dojít, když dva nebo více úkolů čeká, až na sebe navzájem odešlou zprávy s odpovědí.

Přerušit obslužné rutiny a plánovač

Protože obsluha přerušení blokuje spuštění úlohy s nejvyšší prioritou a protože operační systémy v reálném čase jsou navrženy tak, aby udržovaly latenci vlákna na minimu, jsou obsluhy přerušení obvykle udržovány co nejkratší. Obsluha přerušení brání veškeré interakci s hardwarem, pokud je to možné; typicky vše, co je nutné, je potvrdit nebo zakázat přerušení (aby se to znovu neobjevilo, když se obsluha přerušení vrátí) a upozornit na úkol, který je třeba provést. To lze provést odblokováním úlohy ovladače uvolněním semaforu, nastavením vlajky nebo odesláním zprávy. Plánovač často poskytuje možnost odblokovat úkol z kontextu obsluhy přerušení.

OS udržuje katalogy objektů, které spravuje, jako jsou vlákna, mutexy, paměť atd. Aktualizace tohoto katalogu musí být přísně kontrolovány. Z tohoto důvodu může být problematické, když obsluha přerušení zavolá funkci OS, když to aplikace také provádí. Funkce OS volaná z obsluhy přerušení mohla najít aktualizaci objektů v nekonzistentním stavu z důvodu aktualizace aplikace. K řešení tohoto problému existují dva hlavní přístupy: sjednocená architektura a segmentovaná architektura. RTOS implementující unifikovanou architekturu řeší problém jednoduše deaktivací přerušení při aktualizaci interního katalogu. Stinnou stránkou věci je, že se zvyšuje latence přerušení, což potenciálně ztrácí přerušení. Segmentovaná architektura neprovádí přímé volání operačního systému, ale deleguje práci související s operačním systémem na samostatný obslužný program. Tento obslužný program běží s vyšší prioritou než jakékoli vlákno, ale nižší než obslužné rutiny přerušení. Výhodou této architektury je, že přidává velmi málo cyklů k přerušení latence. Výsledkem je, že operační systémy, které implementují segmentovanou architekturu, jsou předvídatelnější a ve srovnání s unifikovanou architekturou se mohou vypořádat s vyšší rychlostí přerušení.

Podobně může režim správy systému na hardwaru kompatibilním s x86 trvat hodně času, než vrátí řízení operačnímu systému.

Přidělení paměti

Přidělení paměti je v operačním systému v reálném čase důležitější než v jiných operačních systémech.

Za prvé kvůli stabilitě nemůže dojít k nevracení paměti (paměť, která je přidělena, ale po použití není uvolněna). Zařízení by mělo fungovat neomezeně dlouho, aniž by bylo třeba restartovat. Z tohoto důvodu je dynamické přidělování paměti odsuzováno. Kdykoli je to možné, všechna požadovaná alokace paměti je staticky specifikována v době kompilace.

Dalším důvodem, proč se vyhnout dynamické alokaci paměti, je fragmentace paměti. Při častém přidělování a uvolňování malých částí paměti může nastat situace, kdy je dostupná paměť rozdělena do několika sekcí a RTOS není schopen přidělit dostatečně velký souvislý blok paměti, přestože je dostatek volné paměti. Za druhé, rychlost přidělení je důležitá. Standardní schéma alokace paměti skenuje propojený seznam neurčité délky, aby našel vhodný volný blok paměti, což je v RTOS nepřijatelné, protože alokace paměti musí proběhnout v určitém čase.

Protože mechanické disky mají mnohem delší a nepředvídatelnější doby odezvy, přepínání na soubory na disku se nepoužívá ze stejných důvodů jako výše popsaná alokace RAM.

Jednoduchý algoritmus bloků s pevnou velikostí funguje dobře pro jednoduché vestavěné systémy, protože má nízké režijní náklady.

Viz také

Reference