Esterel (Programmiersprache)
Esterel ist eine synchrone imperative Programmiersprache, deren Ursprung auf den Anfang der 80er und die Zusammenarbeit mehrerer Wissenschaftler (u. a. Gérard Berry) zurückzuführen ist.
Ursprung
Esterel entstand aus Unzufriedenheit zweier Forscher, Jean-Paul Marmorat und Jean-Paul Rigault, bei der Entwicklung eines Robotik-Autos. Sie erkannten die Notwendigkeit für spezielle Statements zum Umgang mit Zeit, besonders Zeitverzögerungen und Preemption (Entzug von „Komponenten“), und fanden, dass die Wiederholung eines Signals als eine eigene Zeiteinheit zählen sollte. Nach einigen wichtigen Weiterentwicklungen entstand 1987–1988 Esterel v3. Größere Programme wurden damit jedoch erschwert, da es häufig zu einer Explosion von Zuständen kam. Zur vorübergehenden Lösung wurden Hilfsprogramme entwickelt, um dies zu vermeiden. 1992 kam der Esterel v4-Compiler, welcher das Problem der Zustandsexplosion grundsätzlich beseitigte. Weitere Entwicklungen führten nun zum aktuellen Esterel v5-Compiler. Esterel wird seit den 90ern kommerziell vertrieben, z. Z. mit Esterel Studio, entwickelt durch die französische Firma Esterel-Technologies. Esterel kann entweder als Hardware-Software-Kombination oder als reine Hardware-Lösung implementiert werden.
Semantik
Da eine jederzeit bestimmbare Zeit nicht existiert bzw. Esterel auf der Multi-form time basiert, wird die Zeit durch Ereignisse (events) bestimmt, wobei die niedrigste Zeiteinheit ein tick bzw. instant darstellt. Reagiert wird nur auf Sensoren oder Signale. Dadurch sind beliebige Einheiten verwendbar, z. B. Minuten, Meter, Grad. Die Häufigkeit des Empfangs eines Signals bestimmt den eigentlichen Wert, z. B. 100 Meter. Sensoren dienen zum Empfang von Werten, Signale können gesendet und empfangen werden. Signale unterteilen sich in pure (ohne Wert) und wertbehaftete (mit Wert).
Esterel-Programme sind nicht selbst lauffähig und bedürfen einer Host-Sprache, aus der ein Import von Datentypen möglich ist. Esterel weist keine eigenen komplexen Datentypen (nur einfache ganzzahlige) auf und ist im Gegensatz zu Lustre für kontroll-intensive Systeme besser geeignet als für Daten-intensive. Signale sind Variablen meist vorzuziehen, weil Abfragen eines Variablenwerts Codezeilen und damit Laufzeit benötigt, Signale hingegen nicht. Eine weitere spezielle Eigenheit sind Combined Signals. Signalwerte, welche zum selben Zeitpunkt gesendet werden, können vom Empfänger addiert werden. Dies führt zu Ersparnis von Befehlslaufzeit, die sich ansonsten mit jeder weiteren Abfrage zusätzlich erhöhen würde.
Module, innere Operationen (engl. nested operations) und die Ausnahmebehandlung (engl. exceptions) stellen weitere wichtige Komponenten von Esterel dar. Module sind beliebig platzierbar. Innere Operationen können nach Prioritäten geschachtelt werden, wobei die äußerste Schachtelung die höchste Priorität erhält. In Verbindung mit Exceptions erhält man Prozessabläufe, welche jederzeit unterbrochen werden können. Treten in mehreren geschachtelten Programmabschnitten Exceptions auf, wird nur die äußerste Exception ausgeführt. Essentiell ist ebenso Broadcasting, das die Hauptkommunikation zwischen den Prozessen darstellt. Weder der Empfänger noch der Sender müssen wissen, wer ein Signal sendet bzw. empfängt. Erst bei der Laufzeit wird dies entschieden und das ohne Effizienzeinbußen. Es können auch externe Tasks aus der Hostsprache ausgeführt werden.
Das nachfolgende Modul, angelehnt an AVERAGE,[1] veranschaulicht den Vorteil laufende Prozesse ständig unterbrechen zu können:
module COUNTER: input INCREMENT_COUNTER(integer), DONT_COUNT(integer); output COUNTER_VALUE; var COUNTER_VALUE:=0 : integer in abort every immediate INCREMENT_COUNTER do COUNTER_VALUE := COUNTER_VALUE + 1; emit COUNTER_VALUE end when 1 DONT_COUNT end module
COUNTER_VALUE wird zu Beginn mit 0 initialisiert. Bei jedem Empfang von INCREMENT_COUNTER wird COUNTER_VALUE um 1 erhöht und mit emit der neue Counterwert gesendet. Empfängt das Modul hingegen zur gleichen Zeit neben INCREMENT_COUNTER ebenso ein DONT_COUNT-Signal wird mit abort eine Exception ausgeführt und der innere Codeabschnitt ignoriert.
Optimierung
Der Esterel-Compiler ist sehr effizient. Der Versuch bestehenden Code per Hand zu minimieren erweist sich als unnötig. Der Compiler übersetzt jedes Programm in einen äquivalenten, sequentiellen (linearen) Automaten, womit sich einzig die Kompilierungszeit erhöht.
Verifikation
Durch den deterministischen Automaten wird die Verifikation vereinfacht. Ein zur Verifikation verwendetes Tool wäre Verification AUTO.
Kompilierung
Esterel-Code kann entweder als ganzer Automat oder als mehrere kommunizierende Teilautomaten kompiliert werden. Beide Möglichkeiten haben Vorteile. Ein ganzer Automat braucht mehr Platz, spart jedoch Zeit. Mehrere Teilautomaten sparen durch die Form als Module Speicherplatz, der Zeitaufwand wird jedoch durch mehr Kommunikationsaufwand erhöht. Modifiziert man den Programmcode durch Entfernen eines Moduls, wirkt sich dies meist nicht bzw. kaum auf andere Module aus. Jedoch verkürzt sich die Kompilierungszeit. Es kann C-Code erzeugt werden, welcher in die Host-Sprache eingebunden wird. Ebenso ist das Übersetzen ins OC-Format möglich. Kommerzielle Programme generieren auch VHDL etc.
Simulation
Der Esterel v5-Compiler startet mittels der Option -simul eine Simulation. Die Eingabe erfolgt hierbei über das Terminal. Existierende grafikbasierte Anwendungen vereinfachen die Eingabe und das Ablesen von Ausgabewerten. Ebenso können Trace-Optionen verwendet werden. Generierter C-Code (eingebunden in der Host-Sprache) kann ausgeführt werden. Es muss dennoch beachtet werden, dass für Betriebssysteme unterschiedliche Auflösungen der Zeiteinheiten gelten (System V: 1s, BSD 4.3: 1/60s), womit zeitkritische Simulationen kaum möglich sind.