Struktura programów dla mikrosterowników

Prosta pętla

Najprostsza organizacja programu to pętla która w kółko wykonuje potrzebne operacje. Taka organizacja jest przyjęta w środowiskach Arduino i Energia. Dokładniej, środowsko dostarcza funkcję "main" która najpierw wzywa "setup" a następnie w nieskończoność wywołuje funkcję "loop". Podobna organizacja jest używana w tzw. PLC (ang. Programmable Logic Conrtoller). Po starcie PLC się inicjuje a następnie powtarze cykle w których najpierw odczytuje linie wejściowe, potem wylicza odpowiedz, następnie wyprowadza na wyjście wyliczony wynik. Więcej informacji o PLC można znaleźć w książce o PLC. PLC używają swoje własne języki programowania, ale stukturę programu można zaadoptować do dowolnego języka.

Wątki wyzwalane czasem

Prosta pętla wykonuje wszyskie operacje jednakowo często, do tego częstość powtarzania operacji zależy od szybkości programu. To działa dobrze jeśli program jest dostatecznie szybki a przy tym "im szybciej tym lepiej". Ale może się okazać że operacje powinny być wykonane w ściśle określonym czasie, nie później i nie wcześniej. Np. pomiary które mają być poddane analizie Fouriera powninny być w równoodległych momentach czasu. Nawet jeśli metoda uogólnia się dla punktów które nie są równoodległe kod dla równoodległych punktów może być jedym który jest zaimplementowany w systemie (np. zwykłe średnie działają dobrze dla punktów równoodległych, a ogólniej trzeba by używać średnine ważone). Czasami chcemy by czynności były wykonywane w określonym czasie po prostu żeby zachowanie systemu było bardziej przewidywalne.

Wymaganie wykonania operacji w ściśle określonym czasie prowadzi do architektury wyzwalenej czasowo. Tzn. zegar systemowy generuje przerwania które inicjują potrzebne akcje. Akcja to oddzielna funkcja (wątek), przechowuje stan w zmiennych globalnych i wykonuje się tak długo aż wykona bieżące zadanie. Kiedy nie ma nic do roboty procesor śpi. Oczywiście, aby spełnić wymagnia czasowe poszczególne akcje muszą sie wykonywać dostatecznie szybko i zakończyć się przed czasem kiedy ma być wykonana następna akcja. Typowo impulsy zegarowe przychodzą w równych odstępach (np. co 1 ms) i wymaga się by wszystkie akcje zainicjowane danym impulsem zakończyły się przed przyjściem następnego impulsu. Może to wymagać rozbicia długotrwałych operacji na sekwencje krótkich kroków z których każdy zmieści się w pojedynczym slocie czasowym przy tym różne kroki wykonują się w różnych slotach.

W czystej architekturze wyzwalanej czasowo nie używa się innych przerwań niż przerwanie zegara, cała obsługa urządzeń odbywa się przez ich regularne odpytywanie. Mniej czyste warianty mogą wydelegować pilne działania (np. obsługę urządzeń które nie mogą czekać) do przerwań. Więcej informacji o architekturze wyzwalanej czasem można znaleźć w książce Patterns for Time-Triggered Embedded Systems (pod względem sprzętowym książka jest przestarzała, bo współczesne procesory nie mają wielu ograniczeń procesora 8051, ale reszta jest aktualana).

Wątki wyzwalane zdarzeniami

Zwykle mikrosterownik ma reagować na zjawiska zewnętrzne lub czas. Logiczna jest organizacja systemu tak by procesor normalnie spał a wykonywał obliczenia tylko w reakcji na zdarzenia. Dokładniej, rozmaite urządzenia mogą zgłaszać przerwania i wszystkie obliczenia są wykonywane w reakcji na przerwanie.

Wątki współpracujące

Złożone systemy często dzieli się na wątki, z których każdy jest odpowiedzialny za wykonanie pojedynczej funkcji. Ogólnie (jeśli dopuszczamy wywłaszcznie i potrzebujemy blokady) może to prowadzić to bardzo złożonych systemów które są trudne do analizy. W szczególności eksperymenty z systemami operacyjnymi ogólnego przeznaczenia pokazały że proces testowania i poprawiania błędów prowadzi do systemów które zwykle dobrze działają, ale w rzadkich (ale nie pomijalnych) przypadkach źle się zachowują.