# Embedded Software Engineering

Der Begriff Embedded Software Engineering setzt sich zusammen aus den Begriffen Embedded Systems (deutsch „eingebettete Systeme“) und Software Engineering, (deutsch „Softwaretechnik“). Ein eingebettetes System ist ein binärwertiges digitales System (Computersystem), das in ein umgebendes technisches System eingebettet ist und mit diesem in Wechselwirkung steht. Dabei hat das Computersystem die Aufgabe, das System, in das es eingebettet ist, zu steuern, zu regeln oder zu überwachen. Die Softwaretechnik beschäftigt sich mit der Herstellung von Software, also der Entwicklung und dem Betrieb von Programmen und der Organisation und Modellierung der zugehörigen Datenstrukturen.
Das Besondere der eingebetteten Systeme besteht in ihrer Eigenschaft als „universeller Systemintegrator“. Die technischen Systeme werden dabei durch interagierende Komponenten geformt. Die hohe Zahl der Komponenten, die wachsende Komplexität der einzelnen Komponenten und des Gesamtsystems und nicht zuletzt die Anforderungen ständig verbesserter Systeme machen es notwendig, die Einzelkomponenten sowie die Interaktionen mit immer mehr Funktionen auszustatten.

## Herausforderungen des Embedded Software Engineering

Bei der Entwicklung von Software für eingebettete Systeme stehen Entwickler besonderen Randbedingungen gegenüber, deren Erfüllung notwendig für die korrekte Funktion ist. Dazu zählen die Kopplung zu physikalischen Prozessen, die damit einhergehenden Anforderungen an Zuverlässigkeit und die zunehmende Anzahl von verteilten Systemen mit hoher Dynamik.

### Kopplung an physikalische Prozesse

Die physikalischen Prozesse, mit denen die eingebetteten Systeme gekoppelt sind und deren Wechselwirkungen durch die Software behandelt werden sollen, zwingen dem System ein vorgegebenes Zeitverhalten auf. Da sich die Zeitabläufe zum Beispiel bei gesteuerten Motoren nicht ändern lassen, muss das eingebettete System in Echtzeit arbeiten, also in seinem zeitlichen Verhalten dem umgebenden technischen System angepasst sein.
Hierbei wird zwischen hartem und weichem Echtzeitverhalten unterschieden. Die Differenzierung erfolgt dabei ausschließlich durch die Konsequenzen, die ein zeitliches Fehlverhalten hervorrufen kann: Stellt ein Fehlverhalten eine Gefährdung für Mensch und/oder Material dar, so darf es nicht vorkommen, und das System muss unter allen Umständen die zeitlichen Bedingungen erfüllen. Das wird als hartes Echtzeitsystem bezeichnet. Wird durch das Fehlverhalten lediglich eine Qualitätsminderung erzeugt, so wird von einem weichen Echtzeitsystem gesprochen.
Andere Anpassungen an das physikalische System können beispielsweise die maximal erlaubte Verlustleistung, etwa aufgrund der maximal verfügbaren elektrischen Leistung oder der Begrenzung der erzeugten Wärme, oder die mittlere Energieaufnahme betreffen. Im Fall von batteriebetriebenen Geräten etwa bestimmt die mittlere Energieaufnahme die Einsatzdauer. Anpassungen an die elektrischen Werte können meist nur durch gemeinsame Hard- und Software Engineering (Co-Design) erreicht werden.

### Zuverlässigkeitsanforderungen

Die Zuverlässigkeitsanforderungen, die in besonderem Maße an eingebettete Systeme gestellt werden, betreffen die Hard- und Softwarequalität. Softwarequalität ist die Gesamtheit der Merkmale und Merkmalswerte eines Softwareprodukts, die sich auf dessen Eignung beziehen, festgelegte oder vorausgesetzte Erfordernisse zu erfüllen. Als Merkmale gelten Funktionalität, Zuverlässigkeit, Benutzbarkeit, Effizienz, Änderbarkeit und Übertragbarkeit.
Die Zuverlässigkeit (englisch reliability) ist hierbei als Wahrscheinlichkeit definiert, dass ein System seine definierte Funktion innerhalb eines vorgegebenen Zeitraums und unter den erwarteten Arbeitsbedingungen voll erfüllt, das heißt intakt ist und es zu keinem Systemausfall kommt. Bei den Fehlern oder fehlerhaften Handlungen, die die Zuverlässigkeit herabsetzen, müssen zwischen der fehlerhaften Handlung (englisch error), die zu einem späteren Fehler führt, der fehlerhaften Stelle im Gerät oder Programmcode, auch als innerer Fehler (englisch fault) bezeichnet, und dem tatsächlichen Fehlverhalten, auch als Fehlerwirkung oder äußerer Fehler (englisch failure) bezeichnet, unterschieden werden. Die Rate der äußeren Fehler wird in FIT (Failure in Time, Anzahl der auftretenden Fehler pro 10$^9$ Betriebsstunden) gemessen. Die durch Software verursachten Fehler übersteigen die Hardwarerate ohne besondere Maßnahmen um etwa 100 bis 1000. Hierin besteht eine wesentliche Aufgabe des Embedded Software Engineering, diese Rate auf die geforderten Werte zu reduzieren.

### Verteilte Systeme mit hoher Dynamik

Bei einer zunehmenden Anzahl von Systemen ist die Anzahl der (eigenständigen) elektronischen Komponenten sehr hoch, sie bewegt sich zwischen einigen 100 und über 1000 Komponenten. Entwicklungen wie Smart Sensors (Sensoren mit eingebauter Vorverarbeitung zum Beispiel durch Mikroprozessoren) oder MEMS (microelectromechanical system) zeigen, dass die Durchdringung eines physikalischen Prozesses mit elektronischen Komponenten zur Messung, Steuerung und Regelung sehr weitgehend sein kann und dass die Trennung physikalischer Prozess/Informationsverarbeitung nicht mehr aufrechterhalten werden kann.
Die Probleme in der Softwareentwicklung solcher Systeme lassen sich durch zwei meist geforderte Eigenschaften darstellen: Zum einen soll eine solche verteilte Applikation robust, zuverlässig und in Echtzeit arbeitend sein, zum anderen arbeitet die verteilte Applikation hochgradig parallel, und das Gesamtsystem ist meist auch dynamisch, das heißt die Applikation muss sich den wandelnden Bedingungen anpassen. Die Kombination aus Verteilung, Zuverlässigkeit und dynamischer Anpassung gilt als besondere Herausforderung.

## Ansätze zum Embedded Software Engineering

Neben der algorithmischen Korrektheit einer Applikation müssen bei eingebetteten Applikationen meist eine oder mehrere weitere Bedingungen eingehalten werden. Abgesehen von den grundlegenden Prinzipien des Software Engineering, die auch im eingebetteten Bereich zur Anwendung kommen, können zusätzliche Methoden zum Einsatz kommen, um diese Bedingungen zu erfüllen. Die Designmethoden unterscheiden sich dabei je nach zu erfüllender Bedingung.

### Referenzmodell für eingebettete Systeme

Bild 1 zeigt das allgemeine Referenzmodell eines nicht-verteilten eingebetteten Systems. Charakteristisch ist die starke Außenbindung mithilfe von Aktoren und Sensoren; sie stellen die wesentliche Kopplung an die technische Umgebung dar, in der das System eingebettet ist. Die Benutzerschnittstelle kann entfallen, in diesem Fall handelt es sich um ein tief eingebettetes System (englisch deeply embedded system). Die Referenzarchitektur zeigt, dass eingebettete Applikationen eine starke Eingabe/Ausgabe-(Input/Output-, I/O-) Bindung besitzen. Dementsprechend sind Hard- und Software stark I/O-dominant ausgeführt.

### Designmethoden zur Erfüllung zeitlicher Vorgaben

Die Echtzeitfähigkeit einer Software-Applikation ist die häufigste Bedingung, die erfüllt werden muss. Die Echtzeitfähigkeit bezieht sich dabei auf das Referenzmodell aus Bild 1, das heißt, das System muss im Allgemeinen auf Ereignisse von außen rechtzeitig reagieren. Die Rechtzeitigkeit besteht darin, dass eine maximale Zeit nach Eintreten des Ereignisses definiert ist, bei der die Reaktion eingetreten sein muss, unter Umständen auch eine minimale Zeit nach dem Ereignis, vor der die Reaktion nicht eintreten darf. Letzteres ist beispielsweise notwendig, wenn in einer eventuell verteilten Applikation mehrere Reaktionen gleichzeitig eintreten müssen.

#### Zeit-gesteuertes Design

Um die Kopplung zwischen Umgebungsereignissen und dem eingebetteten System herzustellen, bieten sich zwei Methoden an: Zeit-gesteuertes Design und Ereignis-gesteuertes Design. Das Zeit-gesteuerte Design (englisch time-triggered design) geht davon aus, dass es in der Software einen meist periodisch aufgerufenen Teil gibt, in dem das Vorliegen von Ereignissen festgestellt wird. Die Implementierung kann zum Beispiel durch einen periodisch per Timer ausgelösten Interrupt Request (IRQ) mit zugehöriger Interrupt Service Routine (ISR) erfolgen.
Dieser zyklisch ablaufende Teil stellt das Vorliegen von Ereignissen fest und startet die entsprechende Reaktionsroutine. Die Zykluszeit richtet sich dabei nach der geforderten maximalen Reaktionszeit für dieses Ereignis sowie anderen Zeiten im System. Diese Designmethodik ergibt ein statisches Design, bei dem alle Aktivitäten zur Übersetzungszeit (englisch compile time) bekannt sein müssen. Die Echtzeitfähigkeit dieses Designs lässt sich beweisen, wenn alle maximalen Bearbeitungszeiten (englisch worst-case execution time, WCET) und alle maximalen unterbrechungsfreien Zeiten (englisch worst-case interrupt disable time, WCIDT) bekannt sind.

#### Ereignis-gesteuertes Design

Im Ereignis-gesteuerten Design (englisch event-triggered design) wird den Ereignissen selbst ein Interrupt Request zugewiesen. Das bedeutet, dass die zugehörigen Serviceroutinen zumindest teilweise als Interrupt Service Routine ausgelegt sein müssen, und ein Interrupt Priority Management muss die Prioritäten bei gleichzeitigem Auftreten regeln. Das Gesamtsystem ist hierdurch scheinbar weniger belastet, weil die Ereignisbehandlung nur dann aufgerufen wird, wenn tatsächlich etwas vorliegt. Das System selbst kann jedoch im Vergleich zum Zeit-gesteuerten Design nicht schwächer ausgelegt werden, weil die Echtzeitfähigkeit garantiert werden muss. Die Systemauslegung eines (harten) Echtzeitsystems muss immer der maximalen Last folgen, nicht einer mittleren.
Negativ am Ereignis-gesteuerten Design ist außerdem, dass die maximal definierte Ereignisrate nicht automatisch eingehalten werden muss. Zusätzliche Hardwaremaßnahmen sind erforderlich, falls – etwa durch prellende Schalter oder Teilprozesse, die außerhalb der Spezifikation arbeiten – angenommene Ereignisraten überschritten werden können, um die Arbeitsfähigkeit der Applikation zu erhalten.

### Designmethodik für verteilte eingebettete Systeme mit Echtzeitfähigkeit

Das Zeit-gesteuerte Design kann dahingehend verallgemeinert werden, dass ein synchrones Systemdesign gewählt wird. Dieses Systemdesign entspricht dem meist genutzten Modell der digitalen Hardware: Berechnungen werden durch ein (asynchrones) Schaltnetz durchgeführt und am Ende eines Zeittakts in Flipflops gespeichert. Übertragen auf das Softwaredesign heißt dies, dass algorithmische Berechnung und Kommunikation (vor oder nach der Berechnung) in einer angenommenen Zeitspanne durchgeführt werden und am Ende dieser Zeitspanne alle Ergebnisse als Eingang für den nächsten Zeitabschnitt gespeichert werden.
Die synchrone Designmethodik ergibt dann eine Systemarchitektur, die der eines komplexen, kooperierenden Automaten entspricht. Für echtzeitfähige verteilte Systeme muss die Kommunikationszeit selbst begrenzt sein, was durch spezielle Netzwerke (zum Beispiel TTP/C, Time-Triggered Protocol Class C oder diverse Echtzeit-Ethernet-Standards) gewährleistet ist. In der Entwicklung selbst muss dann die Annahme, dass die algorithmische Verarbeitung innerhalb einer vorgegebenen Maximalzeit erfolgt, nachgewiesen werden (WCET-Bestimmung). Synchrone Sprachen, die die Entwicklung unterstützen, sind Esterel, Lustre und Signal. Zur Zeitlichen Definition des Systemverhaltens, insbesondere auch bei verteilten Systemen, bietet sich auch Timing Definition Language (TDL) an.

### Designmethoden zur Erfüllung energetischer Vorgaben

Um energetische oder verlustleistungsbezogene Vorgaben zu erfüllen, existieren vergleichsweise wenig softwarebasierte Methoden. Die Auswahl eines Mikrocontrollers anhand der energetischen Eigenschaften oder sogar der Wechsel auf anderen programmierbare Architekturen wie Field Programmable Gate Arrays (FPGA) können hier wesentlich energiesparender wirken als reine Softwarelösungen. Innerhalb des Softwaredesigns können drei Methoden zur Senkung des Energiebedarfs und der Verlustleistung angewendet werden:
* Die tatsächliche Laufzeit des Programms pro betrachteter Zeiteinheit wird möglichst minimal gestaltet, und in den Zeiten, in denen der Prozessor idle ist, wird der Betriebszustand „schlafend“ oder ähnlich gewählt. Dieser Betriebszustand (der Hardware) ist dadurch gekennzeichnet, dass viele Teile des Prozessors abgeschaltet sind und dadurch der Energieumsatz stark minimiert wird. Wie weitgehend abgeschaltet werden kann und wie der Prozessor wieder aufgeweckt wird, kann nur im Einzelfall entschieden werden und ist abhängig von dem Prozessortyp, der Planbarkeit der Applikation und so weiter.
* In einem anderen Ansatz wird versucht, das Programm so zu gestalten, dass bei Einhaltung aller Zeitschranken möglichst gleiche Idle-Zeiten (pro betrachteter Zeiteinheit) entstehen. Im zweiten Schritt kann dann die Taktfrequenz des Prozessors (und damit auch die Betriebsspannung) so angepasst werden, dass keine Idle-Zeiten mehr existieren. Das liefert ein gleichförmig arbeitendes Design mit minimierter Verlustleistung. Die ideale Zeiteinheit, deren Ablauf optimiert wird, ist dabei die Superperiode (= kleinstes gemeinsames Vielfaches über alle verschiedenen periodischen Abläufe im System), die Anpassung der Taktfrequenz muss jedoch für jede einzelne Periode möglich sein.
* Alternativ oder zusätzlich können auch spezialisierte Compiler verwendet werden, die energetisch besonders günstigen Code liefern. So ist der Bedarf an elektrischer Energie für verschiedene Instruktionen unterschiedlich, das kann ausgenutzt werden.