Bei sogenannten Embedded Systems handelt es sich um eingebettete (Computer)systeme, die - weitestgehend unsichtbar - ihren Dienst in einer Vielzahl von Anwendungsbereichen versehen, wie z.B. in Flugzeugen, Autos, Kühlschränken, Fernsehern, DVD-Playern oder allgemein Geräten der Unterhaltungselektronik.
"Embedded Systems" vereinigen daher durch ihre oftmals sehr hardware-nahe (und vergleichsweise) einfache Konstruktion die große Flexibilität von Software mit der Leistungsfähigkeit der Hardware.
Die Software-Entwicklung für diese Systeme ist daher nicht vergleichbar mit der für z.B. Desktop- oder PC-Systeme: oftmals werden Betriebssysteme eingesetzt, die zwar nicht über Speicherschutz verfügen, dafür jedoch Echtzeitanforderungen genügen.
Bevorzugte Programmiersprachen sind daher z.B. Assembler oder C. Übliche Embedded-Betriebssysteme sind z.B. VxWorks, zunehmend auch spezielle Linux-Derivate, NetBSD, aber auch für Java gibt es Ansätze wie etwa OSGi.
Beispiele
- Beispiel 1
- Die Elektronik in einem Kaffeevollautomaten ist ein eingebettetes System. Mit ihr wird beispielsweise die Kaffeemenge und -stärke reguliert. Die Kaffemaschine an sich ist kein datenverarbeitendes System.
- Beispiel 2
- Im weitesten Sinne ist jedoch auch die Elektronik in einem Videorecorder ein eingebettetes System, obwohl der Videorecorder selbst auch wieder ein datenverarbeitendes System ist. Man setzt deshalb für die Definition des eingebetteten Systems voraus, dass
- die genaue Aufgabe des Systems vor der Entwicklung feststeht
- Hardware und Software parallel entwickelt werden
- Beispiel 3
- Ein Mobiltelefon.
Charakterisierung
Embedded-Systeme basieren zumeist auf derselben Hardware wie Computer, sie unterliegen jedoch meist stark einschränkenden Randbedingungen: Minimale Kosten und damit geringer Platz-, Energie-, Speicherverbrauch. Die Fertigung in großen Stückzahlen, zumeist im Millionen-Bereich, ist ein weiterer wichtiger Punkt zur Kostenreduzierung. Hinzu kommt, dass die einzelnen Komponenten wie Prozessor und RAM auf Weiterentwicklungen älterer Komponenten basieren, was die Langlebigkeit steigert, Stromverbrauch und -kosten jedoch senkt.
Die hierbei verwendeten älteren Komponenten sind jedoch noch nicht die einzige Erklärung, warum diese Systeme langsam sind, denn die gesamte Architektur des ursprünglichen Systems wurde vereinfacht, um weitere Kosten zu senken.
Ein Beispiel hierfür wären die Peripheriegeräte (wie Drucker, Scanner), die durch ein synchrones serielles Interface kontrolliert werden, welche bis zu hundert Mal langsamer sind als vergleichbare Konzepte aus der Desktop-PC-Welt.
Die Programme auf einem Embedded System laufen meist im Echtzeitmodus mit stark reduzierten Ressourcen verglichen mit aktueller Computerhardware, zumeist ohne Festplatte, Betriebssystem, Tastatur oder gar Bildschirm. Ein ROM- oder Flash-Chip ersetzt meist mechanische Komponenten wie eine Festplatte: bewegliche Teile bedeuten Verschleiß, der hier unerwünscht ist. Wenn überhaupt, dann gibt es meist nur ein kleines Tastenfeld und die Ausgabe wird oft durch ein LCD realisiert.
Die Software auf einem solchen Gerät wird Firmware genannt. Sie befindet sich gewöhnlich auf einem ROM immer häufiger jedoch auf den teureren Flash-ROMs. Im Falle eines Flash-ROMs besteht die Möglichkeit eines Firmware-Updates, ohne dass der Chip ausgewechselt werden muss. Wenn man allerdings nur ein ROM hat, muss zumeist der gesamte Chip ausgewechselt werden und, da dieser meist fest auf der Platine ist, die gesamte Schaltung.
Plattformen
Embedded Systems werden mittels vielen verschiedenen CPU-Architekturen (MIPS, ARM, PowerPC, 68k/Coldfire, diverse 8/16 Bit-CPUs, ...) realisiert. Dies stellt einen wichtigen, wenn auch nicht den einzigen, Unterschied zum Desktop-Computer dar, da dieser zumeist nur durch zwei wesentliche Architekturen realisiert wird, momentan (2004) x86 und PowerPC (letzterer überwiegend in Computern der Firma Apple).
Betriebssystem
Bei Embedded Systems arbeitet man meist mit sehr spezialisierten Betriebssystemen (VxWorks, Nucleus). Oftmals verwendet man Konfigurationen mit harten/weichen real-time-Anforderungen, wie unten näher beschrieben.
Allerdings finden auch Standard-Betriebssysteme wie Linux (Embedded Linux), NetBSD oder Windows (CE, EmbeddedXP) inzwischen hier großen Anklang, welche dann mit einigen Modifikationen im System integriert werden können.
Entwicklungsumgebung, Werkzeuge
Die Software, also Compiler, Assembler und Debugger, welche zur weiteren Programmentwicklung verwendet werden, kommen zumeist von verschiedensten Orten oder Herstellern:
- Softwarefirmen, welche sich auf solche Geräte bzw. Programme spezialisiert haben.
- Die Programme wurden über einen Crosscompiler erzeugt, wie unter [1] beschrieben. Dieser Compiler kann auf einer ganz anderen Architektur laufen als das Zielsystem.
- Teilweise können Compiler anderer, schon unterstützter Architekturen, welche direkt mit der verwendeten Architektur verwandt sind, verwendet werden. Zumeist sind nur kleine Modifikationen nötig.
Debugging, die Fehlersuche
Debugging wird normalerweise mit einem "in-circuit-Emulator" realisiert, also einem Programm, welches die komplette Hardware auf Softwarebasis simuliert. Da man meist langsame Hardware im Embedded System verwendet und die heutigen Computer viel leistungsstärker sind, kann man damit genau so arbeiten, als würde man direkt mit der Hardware des Embedded Systems arbeiten. Die Vorteile sind jedoch wesentlich. So kann man die Software, welche später auf dem embedded System laufen soll, optimal und komfortabel mit dem Simulator entwickeln, ohne komplizierte und zeitaufwändige Eingriffe an der Hardware. Im konventionellen Fall müsste man jedes Update wieder auf den Chip des embedded Systems spielen, dieses dann starten und testen. Wenn man selbiges mittels Simulator macht, kann man auch die simulierte Hardware zur Laufzeit ändern und auf das evtl. Fehlverhalten testen. Inzwischen geht man auch im Embedded Bereich mehr und mehr dazu über, auf Java-Basis zu entwickeln - Gründe sind u.a. die Möglichkeit des einfacheren Plattformwechsels bzw. der Plattformunabhängigkeit und der Wegfall von Simulatoren (siehe OSGi und Embedded Java).
Alternativ, wenn man keinen Hardwareemulator zur Verfügung hat, wird oft mit Debuggern gearbeitet, welche interne Interrupts des Microcontrollers verwenden. Stichwort Microcode.
Der Microcode-Interrupt lässt den Debugger auf der Hardware arbeiten, auf welcher sonst nur die CPU arbeitet. Von dem Standpunkt der CPU aus können CPU-basierte Debugger dann benutzt werden, um die Elektronik des Computers zu testen und gegebenenfalls Fehler in dieser zu diagnostizieren. Diese Fähigkeit wurde an der PDP-11 (siehe Programmed Data Processor) erforscht und entwickelt.
Entwickler sollten auf alle Fälle die Möglichkeit des Debuggings, welche höhere Programmiersprachen mit sich bringen, nutzen. Diese verfügen über die Möglichkeit, in Programmen Haltepunkte zu setzen und dann kann das Programm im Single-Stepping- (Einzelschritt-) Modus durchlaufen werden. Man sollte auch einfache Programme verwenden, welche Sequenzen von Echtzeitereignissen mitloggen können, um Fehler effizienter zu finden.
Geschichte
Das erste bemerkenswerte moderne Embedded System war der Apollo Guidance Computer, welcher von Charles Stark Draper zusammen mit dem MIT Instrumentation Laboratory entwickelt wurde. Jeder Flug auf den Mond hatte zwei dieser Systeme, welche zur Steuerung verwendet wurden, dabei. Das inertial guidance system wurde sowohl im Kommandomodul als auch in dem LEM, also dem Mondlandemodul, verwendet.
Zu Beginn des Apollo-Projekts wurde genau dieses System als eines der riskantesten Komponenten des Projektes angesehen.
Die ersten Embedded-Systeme wurden allerdings schon vorher in der Minuteman-Rakete eingesetzt und als Folge dessen in Massenproduktion hergestellt. Die Anwendung war ein Wege-Such-System, welches der Rakete nach einmaliger Programmierung eine unabhängige Manövrierung ermöglichte. Die verwendeten integrierten Schaltungen (engl. Integrated Circuits) wurden nach einiger Zeit, dank der Massenproduktion, für jedermann erschwinglich und damit nutzbar gemacht.
Die entscheidende Eigenschaft des Minuteman-Computers war, dass man den Weg-Finde-Algorithmus später programmieren konnte, wodurch man die Rakete wesentlich präziser einsetzen konnte. Ein weiterer Vorteil war die Selbsttestfunktion der Rakete zur Statusabfrage und dass man auf größere Mengen von Kabeln zu Gunsten des Gewichtes verzichten konnte.
Design von embedded Systemen
Die Elektronik bildet meist ein Mikroprozessor mit entsprechender Peripherie oder ein Microcontroller. Einige größere, aber meist veraltete Systeme verwenden Allzweck-Mainfraims oder Minicomputers.
Folgende Aspekte spielen bei Designentscheidungen von Embedded Systemen eine Rolle:
- Integration
- Je mehr Funktionalität der verwendete Mikrocontroller bereits enthält, desto weniger Peripherie-Bausteine werden benötigt, um die Anbindung an die benötigten System-Schnittstellen(Ein/Ausgabe) zu ermöglichen. Je weniger Bausteine eine Platine benötigt, desto geringer ist der Platzbedarf der Leiterbahnen und die Signallaufzeiten zwischen den Bausteinen. Dies sind Gründe, weshalb sich auf den heutigen Microcontrollern meist schon eine gehörige Menge RAM und anderer Peripherie-Funktionen befinden.
- Echtzeitanforderungen
- Hohe Verfügbarkeit, kurze und definierte Antwortzeiten sind häufig gestellte Anforderungen an ein Embedded System und damit auch an dessen Betriebssystem und Software. Während sich unter Desktopbetriebssystemen wie Windows keiner daran stört, dass das Öffnen einer Datei einmal kürzer oder länger dauert, muss die elektronisch gesteuerte Bremse oder der Airbag nahezu unverzögert im Millisekundenbereich reagieren. Die einfache und geschlossene Bauweise sowie die Verwendung spezieller Echtzeitbetriebssysteme erlauben es schon in der Entwicklungsphase die Reaktionszeiten des Gesamtsystems abzuschätzen.
- Stückpreis
- Der Stückpreis hängt wie viele Waren des Marktes von den Entwicklungs- und Herstellungskosten ab. Je höher die Stückzahl, desto geringer ist der Anteil der Entwicklungskosten je Stück. Bei großen Produktionsmengen wird daher von der Entwicklung viel Energie in die Optimierung des Ressourcenverbrauchs gesteckt, um z.B. durch Speichereinsparung die Materialkosten weiter drücken zu können. Bei geringen Stückzahlen fallen die Materialkosten dagegen weniger ins Gewicht. Hier lohnt es sich dann wieder mit teureren, aber dafür flexibleren Bausteinen (z.B. FPGAs) die Entwicklungszeit zu veringern.
- Wartbarkeit
- Entwicklungsumgebung
- siehe Entwicklungswerkzeuge
Start-up
Alle Embedded-Systeme haben einen "Start-up Code", welcher nach dem Einschalten durchlaufen wird. Normalerweise deaktiviert dieser die Interrupts, kalibriert die interne Elektronik, testet den Computer (RAM, CPU und Programmcode) und nachdem alles erfolgreich getestet wurde, wird der Programmcode gestartet, den der Entwickler vorgibt.
Die meisten dieser Systeme sind innerhalb von 100 ms einsatzbereit. Selbst nach einem kleinen Stromausfall bzw. einer Spannungsschwankung laufen diese Geräte sofort weiter, da die interne Hardware dann den Selbsttest der Hardware und Software überspringt und direkt weiterarbeitet.
Verschiedene Typen von embedded Software-Architekturen
Es finden verschiedene Softwarekonzepte Anwendung:
control loop
In dieser Implementierung durchläuft die Software einfach eine endlose Schleife (eng. LOOP) und diese ruft dann Unterprogramme (engl. Subroutine) auf. Die Unterprogramme wiederum bilden dann die Software des Programmierers oder Systemaufrufe zur Hardware. Diese Interrupts (engl. Unterbrechungen) setzen Flags oder interne Zähler, welche dann wiederum vom System gelesen werden können.
Ein einfaches API dient zum Aktivieren oder Deaktivieren von Interrupts. Wenn dies richtig gemacht wird, können verschachtelte Aufrufe in verschachtelten Unterprogrammen realisiert werden. Diese können dann vorhergegangene Interrupt-Zustände in den äußersten Instanzen zurücksetzen. Dies ist eines der einfachsten Konzepte, um einen Exokernel zu erzeugen.
Normalerweise wird dazu ein Unterprogramm aus der Hauptschleife verwendet, um die Liste der "Software Timers" zu verwalten, welche besagen, wie lange ein Prozess schon gelaufen ist. Dazu wird ein periodischer Echtzeit-Systemaufruf (engl. Real Time Interrupt) verwendet. Wenn also einer dieser Timer abgelaufen ist, wird ein zugehöriges Unterprogramm aufgerufen, welches dann ein "Flag" setzt. Dies ermöglicht dann dem nächsten Unterprogramm, ausgeführt zu werden.
Bei einem nicht-unterbrechbaren Multitasking-Betriebssystem unterbrechen höher priorisierte Tasks niedriger priorisierte Tasks nicht automatisch. Nur an den von den Entwicklern vorgesehenen Stellen, kann die Kontrolle an die höher priorisierten Tasks vom Betriebssystem übergeben werden. Windows 3.11 war ein nicht-unterbrechbares Multitasking-Betriebssystem.
Preemptive timers
Preemptive tasks
Office-style operating systems
Benutzeroberfläche
Die Benutzeroberflächen von Embedded-Systemen variieren stark. Man kann von einem rudimentären 2x20 Zeichen-LCD ausgehen, wie auch einer Ausgabe am Computerbildschirm darunter verstehen. Da man aber meist leistungsschwache Hardware verwendet oder diese für wichtige Aufgaben verwenden möchte, bedient man sich hier anderer Konzepte.
- Netzwerkfähige Drucker und ähnliche Geräte verfügen meist über ein Webinterface, über welches man sehr einfach per Browser alle wichtige Konfiguration vornehmen kann. Der Netzwerkdrucker o. ä. muss nur mit einem PC verbunden werden, dann kann mittels eines Browsers und der Adresse des Netzwerkdruckers alles konfiguriert werden.
- Auch manche Switches stellen ihre Konfigurationsmenus, basierend auf demselben Prinzip wie oben beschrieben, zur Verfügung.
Der Vorteil liegt auf der Hand, die Konfiguration wird auf dem Embedded System selbst gemacht, das Interface wird auf ein anderes Gerät ausgelagert, wie z.B. dem PC. Dies spart Ressourcen und macht die Konfiguration einfacher. Ein anderer Vorteil ist, dass die Konfiguration von solchen Geräten völlig betriebssystemunabhängig gemacht werden kann, da man nun nur noch einen Browser zur Verfügung haben muss, wie er auf praktisch jedem System zur Verfügung steht.
Entwickler von solchen Interfaces empfehlen, möglichst früh in der Entwicklungsphase die Nutzungsqualität der Benutzerschnittstelle zu testen. Am besten, man nimmt den nächstbesten freien Mitarbeiter (noch besser eine Mitarbeiterin oder den Chef) und setzt ihn vor den PC, auf dem das Programm mit der gewünschten Oberfläche läuft. Wenn nun Fragen auftreten, sollte man die Gestaltung der Benutzeroberfläche überdenken und entsprechende Änderungen vornehmen.
Die Entwicklung der Oberfläche sollte am besten nur von einer Person geleitet oder erstellt werden. Im idealen Fall ist dies sogar jemand, der das Programm später benutzen will. Das Programm muss leicht bedienbar sein und intuitiv handhabbar sein, es nutzt wenig, wenn es viel kann, aber der Entwickler selbst der einzige ist, der in der Lage ist, es in seinem vollen Funktionsumfang zu nutzen.
Siehe auch
- ARM-Architektur
- MIPS-Architektur
- 68000-Architektur
- Coldfire-Prozessor
- PowerPC-Architektur