Make or Buy - Entwicklung auf Bare Metal vs. RTOS
Bei der Entwicklung von Embedded Systemen, die echtzeitfähig sein sollen, ist eine der ersten und wichtigsten Fragen, ob die Applikationen unter einem Echtzeit-Betriebssystem (RTOS) laufen oder eine Bare-Metal-Lösung entwickelt werden soll. Unter Bare-Metal-Programmierung versteht man dabei im Allgemeinen, dass eine Anwendung direkt auf der Hardware geschrieben wird, ohne eine externe Programmierschnittstelle, also ein Betriebssystem zu verwenden. Anwendungen greifen hier direkt auf Hardwareregister von Mikrocontrollern zu. Dabei behilft man sich mit Ansätzen wie Endlosschleifen, die Tasks mit fester Rechenzeit ausführen. Von dieser sequenziellen Ausführung wird nur abgewichen, wenn ein Interrupt-Ereignis eintritt. Dieser Bare-Metal-Entwicklungsansatz für eingebettete Systeme ist daher auch als Super-Loop bekannt.
Im Gegensatz zur Bare-Metal-Programmierung werden in RTOS-basierten eingebetteten Systemen ein Betriebssystemkern mit Scheduler oder Gerätetreiber zwischen Hardware und Anwendungscode eingesetzt. Dies hat den Vorteil, dass Multithreading möglich wird, was insbesondere dann relevant ist, wenn auf einer Hardware anstatt einiger weniger klar umrissener Tasks, die gut bestimmbar im Sinne der Ressourcen sind, viele Tasks laufen sollen, von denen einzelne komfortabel priorisiert werden können und man dabei die Leistungsfähigkeit mehrerer CPU-Kerne bündelt. Mit anderen Worten: Echtzeitbetriebssysteme mit ihren Schedulern erlauben die parallele und vor allen Dingen flexible und priorisierbare Ausführung von Prozessen und übernehmen die Verantwortung für die Funktionstüchtigkeit des Gesamtsystems.
Im Allgemeinen bilden Betriebssystemkern und Gerätetreiber eine Schnittstelle zwischen dem eigentlichen Anwendungscode und der Hardware des Mikrocontrollers. Im Falle von SYSGOs PikeOS ist dies jedoch etwas anders: Hier wird ein sehr kleiner Microkernel, nur das Nötigste mitbringt und deshalb komfortabel zu zertifizieren ist, eingesetzt, während bestimmte Treiber im User Space laufen. Die Treiber werden in der Regel in einer Treiberpartition ausgelagert und mittels Techniken wie Interpartition Communication oder Queuing Ports angesprochen. Dabei kann der Betriebssystemkern wie bei SYSGOs PikeOS auch als Separation Kernel und Hypervisor ausgeführt sein, der eine strikte Trennung multipler Anwendungen ermöglicht, wie sie beispielsweise bei sicherheitskritischen Systemen erforderlich ist.
Bare-Metal-Programmierung hat den Vorteil, dass eingebettete Softwarelösungen detailliert für einen spezifischen Anwendungsfall auf kleinstmöglicher Ebene geplant werden können ohne den Overhead und mögliche Fehler eines Betriebssystems in Kauf nehmen zu müssen. Im optimalen Fall erhält man so eine maßgeschneiderte Lösung, die ressourcenschonend und zuverlässig Aufgaben erledigt. Dies ergibt immer dann Sinn, wenn die auszuführenden Aufgaben überschaubar sind, so dass man ein größtmögliches Maß an deterministischem Verhalten eines Systems sicherstellen kann. Anwendungsfälle findet man vor allen Dingen dort, wo Controller eingesetzt werden können.
Auf der anderen Seite machen Bare-Metal-Programmierer auch Erfahrungen mit der Schwierigkeit hohe Komplexitätsgrade zu verwalten. Sollten ohnehin schon nicht mehr ganz so kleine Projekte im Laufe der Umsetzungsphase unerwartet größer werden, wenn beispielsweise neue Features hinzukommen, die bei der Vorplanung noch nicht berücksichtigt wurden, kann es schwierig werden die Übersicht zu behalten. Wenn dazu in Assembler programmiert wird und die Dokumentation für eine Platine unzureichend ist oder die Hardware Abstraction Layer fehlt, kann auch ein geübter Programmierer ins Schwitzen geraten. Man kann Betriebsystemen Overhead vorwerfen und ihrer Funktionalität misstrauen, aber sie reduzieren zweifelsohne den Programmieraufwand, indem sie Funktionalitäten für das Speichermanagement und auch das Prozessmanagement zur Verfügung stellen und die Programmierung mit einer Hochsprache wie C zulassen, die Bibliotheken mitbringen, die das Leben des Programmierers einfacher machen, die bei der Bare-Metal-Programmierung hingegen nicht eingesetzt werden können. Es soll nicht verschwiegen werden, dass auch das manchmal aufwändig sein kann, z.B. indem man händisch mit Semaphoren Ressourcen blockieren muss. Allerdings erhält man in jedem Fall ein großes Maß an Gestaltungsfreiheit. Dies wird deutlich, wenn man sich vergegenwärtigt, dass durch die zeitliche und räumliche Separation von Ressourcen es möglich wird, dass sicherheitskritische Anwendungen neben Linux-/Android-Partitionen auf einer Hardware laufen können.
Die Abwägung, wann Bare-Metal-Programmierung Sinn ergibt und wann nicht, ist nicht immer ganz leicht zu treffen, auch wenn es unter Für- und Widersprechenden, Protegées gibt, die kategorisch das eine oder das andere vertreten. Aber einige (auch nicht-technische) Aspekte neben den bereits genannten, sollten dabei bedacht werden: Neben der Abwägung, wie viel Aufwand es bedeutet Programme direkt für entsprechende Hardware zu schreiben und dem Aspekt für eine Applikation ohne Wenn und Aber in der Verantwortung zu stehen im Positiven wie im Negativen, kann es zum Projektrisiko werden, wenn kurzfristig Mitarbeiter für eine längere Zeit ausfallen. Rasch Ersatz zu finden ist schon bei C-, Rust- oder Python-Programmierern nicht ganz einfach, aber kritisch wenn Assemblerkenntnisse benötigt werden. Das ist insbesondere dann der Fall, wenn ein Projekt weit fortgeschritten ist und vertiefte Expertise benötigt wird. Auf der technischen Seite wiederum werden häufig Reliabilitätserwägungen ins Feld geführt. Es ist sicher richtig, dass mit steigender Komplexität im Allgemeinen die Chance für Fehleranfälligkeit zunimmt und im besten Falle eine zu 100 Prozent fremdapplikationsfreie Anwendung überblickt werden kann, allerdings können auch bei der Bare-Metal-Programmierung Fehler unterkommen. Der Vorteil eines Beitriebssystems ist dann, dass gewisse Funktionalitäten praxiserprobt sind und sich nach strikten Safety-Standards wie der DO-178C in der Luftfahrt oder der ISO 26262 richten und deswegen ein begründetes Maß an Zuversicht in die Funktionstüchtigkeit erlauben.
Vernetzung und Security
Da heutzutage mit steigendem Grad der Vernetzung auch immer mehr die Submodule einer Anwendung bzw. eines eingebetteten Systems in den Fokus rücken, sei es aus Wartungsgründen oder solchen um die Effizienz eines Systems aus der Ferne zu überwachen, spielt die Veränderbarkeit bestehender Applikationen eine immer größere Rolle. Sicher gibt es Module, die auch zukünftig nicht vernetzt werden, etwa weil man sie erst gar nicht einer Gefahr im Sinne der IT-Sicherheit aussetzen möchte, aber ehrlicherweise wird man sagen müssen, dass dies künftig häufig nicht mehr den Anforderungen entsprechen wird, so dass eine Modifizierbarkeit der Systeme beziehungsweise des Codes nötig werden. Dies kann zu Schwierigkeiten führen, weil bei eingebetteten Bare-Metal-Architekturen, das Timing und die Antwortzeiten durch die Struktur des Codes festgelegt sind und sich zwingend ändern müssen, wenn funktionelle Änderungen oder Ergänzungen vorgenommen werden und dies zur Folge hat, dass der Aufwand- und die Dauer der Modifikation steigen. Im Gegensatz dazu ermöglicht ein RTOS in der Regel eine große Flexibilität bei vernetzten Systemen und bringt häufig bereits im Vorfeld eingebaute Sicherheitsfunktionen mit. Die Frage nach der Security wird, so ehrlich muss man ebenfalls sein, lauter werden und Anwender als auch Programmierer vor die Frage stellen, ob sie vernetzte oder unvernetzte Systeme möchten. Für den ersten Fall bieten RTOS wie PikeOS von SYSGO vorzertifizierte Artefakte und unterstützen neue Securitykonzepte wie den Zero-Trust-Ansatz.
Ein modernes RTOS bietet neben OS-Grundfunktionalitäten wie Scheduling, damit einhergehend Time Partitioning, auch die Möglichkeit der (hart-)echtzeitfähigen Priorisierung von Aufgaben und ermöglicht so deterministische Reaktionszeiten für Anwendungen. Zwar lässt sich mit Hilfe von Interrupts eine Form des Preempting auf Bare-Metal-Systemen realisieren, aber ein ausgereiftes RTOS bietet hier größtmögliche Komfortabilität und einen reichen Funktionsumfang. Dafür bietet Bare-Metal-Programmierung Vorteile, wenn eine sehr kurze und deterministische Boot-Zeit erforderlich ist. Ein RTOS wird in der Regel Sekunden für den Startvorgang benötigen.
Abstraktion erleichtert Integration
Ein wesentlicher Vorteil eines RTOS ist das in den meisten Fällen vorhandene Ökosystem. Viele Echtzeit-Betriebssysteme verfügen über komfortabel zu nutzende Middleware-Stacks wie Dateisysteme, USB oder TCP/IP, die sich leicht integrieren lassen. Ähnliches gilt für Gerätetreiber oder andere Third-Party-Komponenten. Die Verwendung eines RTOS macht diese Komponenten zu Plug-and-Play-Komponenten in der Software und kann die Softwareentwicklung drastisch beschleunigen. Die Entscheidung, Software von Drittanbietern zu verwenden, kann daher ein wichtiger Indikator dafür sein, dass ein RTOS einem Bare-Metal-Scheduler vorgezogen werden sollte.
Der Versuch, ein Bare-Metal-System mit solcher Middleware zu designen, wäre sehr zeitaufwändig und fehleranfällig. Hinzu kommt, dass ein RTOS die Entwicklung von portablem und wiederverwendbarem Code deutlich erleichtert, da eine RTOS-basierte Lösung in der Regel zu Firmware mit klar definierten Aufgaben führt, die sich für eine Wiederverwendung eignet. Auch führt die Abstraktion zwischen Hardware und Anwendung durch ein Betriebssystem dazu, dass ein Wechsel der Hardware oder die Integration von Third-Party-Modulen erheblich einfacher werden. Zudem ist ein RTOS die einzige Option, wenn man moderne, leistungsfähige Prozessoren mit MMU einsetzen will, da Bare Metal keine virtuelle Adressierung unterstützt.
Safety, Security und Zertifizierung
Ein modernes RTOS spielt seine Stärken aus, wenn das zu entwickelnde System sicherheitskritisch und umfangreich ist und eine Zertifizierung nach nationalen oder branchenspezifischen Standards erfordert, sei es in der Luftfahrt, im Eisenbahnwesen, in medizinischen oder industriellen Anwendungen. Kleine Änderung am Code einer Bare-Metal-Lösung haben zur Folge, dass eine komplette, aufwändige und daher teure Neuzertifizierung nötig wird. Bei einem RTOS ist der Aufwand deutlich geringer, weil nur einzelne Teile einer Neubetrachtung bedürfen. Zudem lassen sich einmal zertifizierte Teile wieder nutzen und veringern so im Allgemeinen Zertifizierungskosten.
Da kritische Systeme in der Regel neben der Kernfunktionalität auch weniger kritische Komponenten wie etwa einen Kommunikations-Stack enthalten, empfiehlt sich hier oft ein Separation-Kernel- und Hypervisor-basiertes RTOS. Bei einem solchen Echtzeit-Betriebssystem kann durch Ressourcen- und Zeitpartitionierung eine strikte Trennung kritischer und unkritischer Anwendungen erfolgen, so dass auch Mixed-Criticality-Systeme auf nur einer Hardware realisiert werden können. Den durchaus nachvollziehbaren Bedenken, dass Interferenzen entstehen können, die die Sicherheit beeinträchtigen, steht die erprobte Praxis auf Grundlage strenger Safety-Standards entgegen, die solchen Systemen auf dieser Grundlage ein extrem hohes Maß an Zuverlässigkeit attestiert. Einzelne Partitionen können unterschiedliche Gast-Betriebssysteme hosten, so dass weniger kritische Anwendungen etwa unter einem Embedded Linux wie ELinOS laufen können, während kritische Applikationen auf ARINC (Luftfahrt), AUTOSAR (Automobil) oder dem nativen RTOS betrieben werden. Bei SYSGOs PikeOS können zudem Posix-Partitionen realisiert werden, die mittelkritische Aufgaben übernehmen, für die Linux etwas zu riskant wäre.
Bei der Partitionierung findet eine statische Zuweisung aller verfügbaren und temporären Ressourcen statt. Jede Anwendung erhält garantierten Zugriff auf die zugewiesenen Ressourcen, hat aber keinen Zugriff auf Ressourcen anderer Partitionen. Die strikte Durchsetzung der Trennung garantiert, dass alle Anwendungen vollständig voneinander getrennt sind und nur über den Hypervisor oder spezifisch konfigurierte Kanäle miteinander kommunizieren können. So wird ausgeschlossen, dass ein Fehler in einer unkritischen Anwendung sich über das System propagieren und auch kritische Applikationen beeinträchtigen kann. So ermöglicht es PikeOS beispielsweise, ein Linux-basiertes Subsystem und eine sicherheitskritische Anwendung mit einem eigenen proprietären Betriebssystem auf einer einzigen CPU-Plattform auszuführen. Alle Partitionen laufen im Benutzermodus und haben keinen Einfluss auf den stabilen Kernelmodus.
Wegen der strikten Trennung der Applikationen haben Separation-Kernel- und Hypervisor-basierte Konzepte auch erhebliche Vorteile bei der Zertifizierung kritischer Systeme. So können Zertifizierungs-Artefakte wiederverwendet werden, und bei Änderungen müssen nur die neuen oder geänderten Partitionen erneut zertifiziert werden, was zum einen die Markteinführung beschleunigt und zum anderen die Kosten für die Zertifizierung spürbar senkt. Zudem ist PikeOS selbst nach EAL 3+ zertifiziert, so dass neben der funktionalen Sicherheit auch ein hohes Maß an IT-Security zuverlässig realisiert werden kann. Dies ist vor allem für Anwendungen wichtig, die mit der Außenwelt kommunizieren. Zwar können Bare-Metal-Anwendungen hinter einem Edge-Perimeter abgesichert werden, aber wenn diese Hürde einmal geknackt ist, fehlen weiterführende Security-Konzepte, die Schlimmeres verhindern können. Hier ist insbesondere auf heuristische Analysen beziehungsweise Mitigationsansätze wie Control Flow Integrity zu verweisen.
Mit seiner Partitionierung bietet PikeOS auch einen relativ einfachen Migrationspfad von Bare-Metal-Implementierungen zu RTOS-basierten Systemen. Zunächst können bestehende Bare-Metal-Anwendungen in eigenen Partitionen installiert werden und dann über API Calls mit dem Kernel und über diesen auch mit anderen Anwendungen kommunizieren.
Kommunizierende Systeme benötigen RTOS
Letztlich ist die Entscheidung für Bare-Metal oder ein RTOS eine klassische Make-or-Buy-Entscheidung. Wirtschaftliche Aspekte spielen ebenso eine Rolle wie die Frage, in welche Richtung sich eingebettete Systeme entwickeln werden, insbesondere in Hinsicht auf den Grad der Vernetzung. Kleine und einfache Systeme auf Bare Metal zu entwickeln ergibt zwar Sinn, aber ein RTOS hat wirtschaftliche Vorteile im Sinne des Return-On-Investment (ROI) und eine geringere Total Cost of Ownership (TCO) sowie technologische (im Sinne abzusehender, künftiger Entwicklungen). Durch die Wiederverwendung bestehenden Codes und gegebenenfalls von Zertifizierungs-Artfakten ist darüber hinaus eine in der Regel schnelle Marktreife gegeben. Aus denselben Gründen lassen sich mit einem RTOS und insbesondere einem Hypervisor-basierten RTOS auch neue Funktionen schnell, wirtschaftlich und funktionell sicher integrieren. Zudem sind RTOS-basierte Systeme in Fragen der IT-Sicherheit für künftige Entwicklungen gewappnet, ohne die in den heutigen vernetzten Umgebungen auch die funktionale Sicherheit nicht mehr gewährleistet werden kann.
Für Entwickler bedeutet der Einsatz eines RTOS zwar zunächst einen Lernaufwand, der sich jedoch sehr bald auszahlt. So wird durch entsprechende Tools und Middleware der Entwicklungsaufwand deutlich reduziert. Damit muss das Rad nicht jedes Mal neu erfunden werden und Projektrisiken können mitigiert werden. Schließlich spielt ein RTOS für Entwickler von eingebetteten Systemen seine wahre Stärke in Fragen des Multithreading aus, da hier der mitgebrachte Funktionsumfang die Programmierung deutlich komfortabler macht, während das Scheduling, wenn ausschließlich mit Interrupt-Routinen gearbeitet wird, nur schwerlich umzusetzen ist im Sinne des Determinismus und der Zuverlässigkeit. Mit integriertem Hypervisor sind darüber hinaus auch mixed-criticality Systeme möglich, auf denen beispielsweise wie in einem Auto ein Abstandsmesser neben einem Infotainmentsystem sicher laufen kann.
Mehr Informationen unter www.sysgo.com/pikeos