Sokszor érzem úgy, hogy a modern ipari elektronika kicsit olyan, mint egy túlpakolt svédasztal. Mindenki kész megoldásokat, gigantikus könyvtárakat és tízmegabájtos keretrendszereket akar lenyomni a torkunkon. Pedig sokszor csak annyit akarunk, hogy egy egyszerű szenzor adatait milliszekundumos pontossággal dolgozzuk fel. Amikor a Szoftverfejlesztés a fémek között: Így írj saját, testreszabott RTOS-t ipari mikrokontrollerekre, hogy valósidejű vezérlést adj a buta perifériáidnak témájával foglalkozom, mindig arra gondolok, mennyivel tisztább a végeredmény, ha nem egy kész csomagot használunk, hanem a saját igényeinkre szabott struktúrát építünk.
A dobozos RTOS-ek, mint a FreeRTOS vagy a Zephyr, fantasztikusak, de gyakran a problémáid 90 százalékát tartalmazzák, amire nincs szükséged, miközben a maradék 10 százalékot nem tudod úgy finomhangolni, ahogy szeretnéd. Amikor saját magad írod a scheduler részét, pontosan tudod, hány órajelciklust vesz igénybe egy kontextusváltás. Nincsenek fekete dobozok, nincsenek váratlan memória-foglalások, és ami a legfontosabb, a kódod nem fog furcsa módon lefagyni egy hónapnyi működés után.
A legtöbb ipari környezetben a buta perifériák egyszerűen csak várják a parancsokat, de a kommunikációs buszok, mint az SPI vagy az I2C, igénylik a gyors reakciót. Ha a fő ciklusodban egyetlen lassú függvényblokk is van, elszáll a valós idejű vezérlésed.
Egy saját RTOS nem rakétatudomány, ha a lényegre koncentrálunk. A valós idejű operációs rendszer lelke az ütemező, azaz a scheduler. Ez dönti el, hogy éppen melyik szál fusson. Nem kell bonyolult prioritás-kezelő algoritmusokra gondolni kezdetben, elég egy egyszerű, fix ciklusidő alapú átkapcsolás.
Az egész folyamatnak a hardver specifikus regisztereivel kell dolgoznia. A C és az assembly keverése itt elkerülhetetlen, de ettől nem kell megijedni. A vezérlő utasítások, mint a PUSH és POP, vagy a stack pointer kezelése tisztábbá teszi a rendszert.
A buta perifériák gyakran okoznak fejfájást, mert nem tudják magukat menedzselni. Itt jön képbe a megszakításkezelés és a pufferelés. Ne engedd, hogy a főprogramod közvetlenül a hardverrel kommunikáljon, mert akkor elveszíted az irányítást a timing felett.
Ez a módszer rengeteg időt spórol meg hibakeresésnél. Ha az adat nem érkezik meg időben, pontosan látod a puffer állapotán, hogy hol akadt el a kommunikáció.
Saját RTOS esetén a legnagyobb ellenséged a verem túlcsordulása. Mivel nincsenek biztonsági hálók, egy rosszul méretezett verem képes a semmibe irányítani a programfutást.
Ez a tesztelési módszer egyfajta saját készítésű biztonsági rendszert jelent. Ha a mintázatod megmarad a tesztek alatt, akkor nyugodtan aludhatsz, mert nem fog az utolsó pillanatban összeomlani a vezérlésed.
Lehet, hogy a fejlesztés elején sokkal lassabbnak tűnik ez az út, mint letölteni egy kész könyvtárat. Viszont a végeredmény egy olyan rendszer, amit kívülről-belülről ismersz. Amikor az ügyfél egyedi hardverrel áll elő, te nem a dokumentációt bújod, hogy a könyvtár támogatja-e, hanem átírod a schedulerben a megfelelő részt, és pár óra alatt működik is.
A kontroll érzése, amit egy általad épített kernel ad, páratlan. Nem kell alkalmazkodnod a keretrendszerek korlátaihoz, mert te határozod meg a kereteket. A buta perifériáid végre úgy fognak táncolni, ahogy te fütyülsz nekik, mert a valós idejű vezérlés felett te rendelkezel, nem egy harmadik féltől származó kód.
A kódolás közben figyelj arra, hogy a kód olvasható maradjon. A saját fejlesztésű RTOS nem azt jelenti, hogy érthetetlennek kell lennie. Dokumentáld a regiszterek állítását, és használj következetes elnevezéseket a szálak kezelésénél. Így, ha egy év múlva vissza kell nyúlnod a projekthez, nem fogsz idegenként tekinteni a munkádra. A hardver és a szoftver ilyen szintű összehangolása az igazi mérnöki munka lényege.