Programmierung von Eingebetteten Systemen

Programmierkonzepte

Funktionale Programmierung

  • Das Programm besteht aus einer Menge von Funktionen
  • Drei Konzepte: Funktionsdefinition, Funktionsapplikation, Funktionskomposition
  • Eine Funktion berechnet ein Ergebnis von Eingabedaten (Funktionsparameter)
  • Es gibt keinen Zustand und keine Speichervariablen

Prozedurale Programmierung

  • Funktionen können neben Berechnung auch Aktionen ausführen Ein- und Ausgabe
  • Es gibt einen Zustand und ein Speichermodell
  • Es gibt Funktionen (s.o.) und Prozeduren Kein Rückgabewert, nur Aktion
  • Das Programm wird in eine Menge von Funktionen und Prozeduren zerlegt
  • Es gibt Datenstrukturen: Arrays (einsortig), Records (mehrsortig)
  • Daten werden durch Funktionen und Prozeduren verändert

Programmierkonzepte

Objektorientierte Programmierung

  • Objekte bestehen aus Daten und Methoden die die Daten verändern (Schreiben) oder weiter geben können (Lesen)
  • Objekte werden von Klassen instanziiert
  • Eine Klasse definiert die Daten und Methoden
  • Klassen können wie Funktionen zusammengesetzt werden
    • Vererbung
    • Superklassen

figoop1

Programmierung in Lua

Datentypen

  • Daten (Werte) besitzen in Programmen bestimmte Datentypen:

    • Zahlen (Ganzzahl, reelle Zahl, usw.)
    • Boolesche Werte (true,false)
    • Arrays (von Werten)
    • Textzeichen (char)
    • Zeichenketten (strings, Arrays von Textzeichen)
    • Records (Prozedurale Datenstrukturen)
    • Objekte (Objektorientierte Datenstrukturen mit Methodenzugriff auf Daten)
    • Funktionen
  • Kerndatentypen sind in Lua:

    • number (i.A. Fliesskommazahl, 8 Byte)
    • string (Zeichenkette)
    • table (Universelle Tabellenstruktur für Arrays, Records, und Objects)
    • boolean
    • function
    • userdata (nur über definierte Operationen Zugriff möglich)

Programmierung in Lua

Werte

  • Zahlen (number): 0, 1, -1, 1.23, ..

  • Boolesche Werte: false, true

  • Zeichenketten: "text" oder 'text'

  • Datenstrukturen: {a=1,b=2, ..}

  • Arrays: {1,2,3,4..}

  • In Lua sind Funktionen Werte erster Ordnung: function () .. end

Programmierung in Lua

Variablen

  • Eine Variable ist gekennzeichnet durch:

    • Name (Identifizierer)
    • Wert (kann undefiniert sein)
    • Typ (kann polymorph sein)
  • In Lua kann eine Variable dynamisch zur Laufzeit Werte mit unterschiedlichen Datentypen speichern Polymorphe Variablen und dynamische Typisierung!

Definition 1. (Definition einer globalen und loakelen Variable)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{var}~\mathid{name}~[~=~\mathid{value}~]\\
\mdmathindent{2}\mathkw{local}~\mathkw{var}~\mathid{name}~[~=~\mathid{value}~]\\
\mdmathindent{2}\mathkw{local}~\mathkw{var}~\mathid{name}_1,\mathid{name}_2,..~=~\mathid{val}_1,~\mathid{val}_2,~..
\end{mdmathpre}%mdk
\]

Programmierung in Lua

Funktionen

  • Eine Funktion ist gekennzeichnet durch

    • Name (Identifizierer, optional!)
    • Parameter (keine, eine, oder mehrere Funktionsvariablen)
    • Anweisungen (lokale Variablendefinitionen, Berechnung, return, Kontrollanweisungen)
  • Funktionen können in Ausdrücken aufgerufen werden (Funktionsapplikation)

  • In Funktionen können weitere Funktionen ausgeführt werden (Funktionskomposition)

  • Funktionen (Prozeduren) können als Anweisung ausgeführt werden

  • In Lua kann eine Funktion auch ohne Namen anonym als Wert definiert werden!

  • Funktionen geben Werte durch die return v Anweisung zurück

Programmierung in Lua

Definition 2. (Definition und Applikation von Funktionen)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{function}~\mathid{name}~(\mathid{parameter}_1,~\mathid{parameter}_2,~..)\\
\mdmathindent{4}\mathid{Anweisung}\\
\mdmathindent{4}\mathid{Anweisung}\\
\mdmathindent{4}..\\
\mdmathindent{4}[~\mathkw{return}~\mathid{value}~]~\\
\mdmathindent{2}\mathkw{end}\\
\mdmathindent{2}\mathkw{local}~\mathkw{function}~..~\mathid{end}\\
\mdmathindent{2}\mathkw{var}~\mathid{name}~=~\mathkw{function}~(..)~..~\mathid{end}\\
\mdmathindent{2}\mathid{name}~(~\mathid{value}_1,~\mathid{value}_2,~..)~$\,{-}\,{-}$~\mathid{Prozeduraler}~\mathid{Aufruf}\\
\mdmathindent{2}\mathid{x}=\mathid{name}~(~\mathid{value}_1,~\mathid{value}_2,~..)~$\,{-}\,{-}$~\mathid{Funktionaler}~\mathid{Aufruf}
\end{mdmathpre}%mdk
\]

Programmierung in Lua

Tabellen

  • In Lua gibt es keine Unterscheidung zwischen Arrays, Datenstrukturen, und Objekten!

  • Es gibt nur Tabellen die aus key-value Paaren bestehen (Schlüssel und Wert) Hashtabellen

  • Auf einen Tabelleneintrag kann mittes der Schlüsselreferenzierung t.key zugegriffen werden (in Ausdrücken lesend oder in datenanweisungen schreibend)

  • Die Definition von Records und Arrays ist sehr ähnlich

  • Bei Arrays ist der Schlüssel aber ein automatisch erzeugter Index 1,2,3, .. Erstes Element hat immer den Index 1! Die Länge eines Arrays kann über die #array Operation ermittelt werden

  • Da Records und Arrays tatsächlich Hashtabellen sind, und der Schlüssel immer eine Zeichenkette ist (auch Index 1!), sind folgende Schreibweisen isomorph: t.key == t["key"]

Programmierung in Lua

Definition 3. (Definition und Applikation von Tabellen)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{var}~\mathid{s}~=~\{~~~~$\,{-}\,{-}$~\mathid{Record}\\
\mdmathindent{4}\mathid{a}_1~=~\mathid{val}_1,\\
\mdmathindent{4}\mathid{a}_2~=~\mathid{val}_2,\\
\mdmathindent{4}..\\
\mdmathindent{2}\}\\
\mdmathindent{2}\mathkw{var}~\mathid{a}~=~\{~~~~$\,{-}\,{-}$~\mathid{Array}\\
\mdmathindent{4}\mathid{val}_1,~\\
\mdmathindent{4}\mathid{val}_2,\\
\mdmathindent{4}..\\
\mdmathindent{2}\}\\
\mdmathindent{2}\mathid{s}.\mathid{a}_1~=~\mathid{s}.\mathid{a}_2\\
\mdmathindent{2}\mathid{a}[1]~=~\mathid{a}[2]\\
\mdmathindent{2}\mathid{s}["\mathid{a}_1"]~=~\mathid{s}["\mathid{a}_2"]
\end{mdmathpre}%mdk
\]

Programmierung in Lua

Anweisungen

  • Programmanweisungen in Lua:
    • Datenanweisung (Wertzuweisung an Variablen)
    • Bedingte Verzweigung
    • Prozeduraufruf
    • Schleifen

Definition 4. (Datenanweisung)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathid{variable}~=~\mathid{expression}
\end{mdmathpre}%mdk
\]

Bedingte Verzweigungen

Definition 5. (Bedingte Verzweigung)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{if}~\mathid{condition}~\mathkw{then}~\mathid{anweisungen}_\mathid{true}~\mathkw{end}\\
\mdmathindent{2}\mathkw{if}~\mathid{condition}~\mathkw{then}~\mathid{anweisungen}_\mathid{true}~\\
\mdmathindent{2}\mathkw{else}~\mathid{anweisungen}_\mathid{false}~\mathkw{end}~\\
\mdmathindent{2}\mathkw{if}~..~\mathkw{elseif}~..~\mathkw{elseif}~..~\mathkw{else}~..~\mathkw{end}
\end{mdmathpre}%mdk
\]

Programmierung in Lua

Definition 6. (Mehrfachauswahl (Extension, kein Standard))

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{case}~\mathid{x}~\mathkw{of}\\
\mdmathindent{4}\mathid{v}_{1}~=>~\mathid{anweisungen}~\mathkw{end}\\
\mdmathindent{4}\mathid{v}_{2}~=>~\mathid{anweisungen}~\mathkw{end}\\
\mdmathindent{4}\mathid{v}_{3},\mathid{v}_{4},..~=>~\mathid{anweisungen}~\mathkw{end}\\
\mdmathindent{4}\mathid{else}~=>~\mathid{anweisungen}~\mathkw{end}\\
\mdmathindent{2}\mathkw{end}
\end{mdmathpre}%mdk
\]

Programmierung in Lua

figdecision_making


Abb. 1. Kontrollfluss von bedingten Verzweigungen

Programmierung in Lua

Schleifen

Definition 7. (Zählschleife)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{for}~\mathid{index}~=~\mathid{a},\mathid{b}~[~,\mathid{step}~]~\mathkw{do}\\
\mdmathindent{3}\mathid{anweisungen}\\
\mdmathindent{2}\mathkw{end}
\end{mdmathpre}%mdk
\]

Definition 8. (Bedingte Schleifen)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{while}~\mathid{condition}~\mathkw{do}\\
\mdmathindent{3}\mathid{anweisungen}\\
\mdmathindent{2}\mathkw{end}\\
\mdmathindent{2}\mathkw{repeat}\\
\mdmathindent{4}\mathid{anweisungen}\\
\mdmathindent{2}\mathkw{until}~\mathid{condition}
\end{mdmathpre}%mdk
\]

Programmierung in Lua

figloops1


Abb. 2. Kontrollfluss von Schleifen in Lua (for, while, repeat)

Programmierung in Lua

Turtle Grafik

  • Um das Programmieren zu erlernen ist eine grafische Visualisierung von Programmabläufen und deren Ausgabe sinnvoll um Programmierkonzepte zu erlernen

  • Die Grafik ist das Rechenergebnis!

  • Die Turtle Grafik hat einfache Befehle, die eine symbolische Schildkröte als Dreieck benutzt um auf einer zweidimensionalen Fläche zu zeichnen.

    • Das Dreieck hat eine Ausrichtung die in Grad angegeben ist [0,360]
  • Dabei kann die Position des Dreiecks absolut (posn) oder relativ (jump,move) verändert werden.

    • Die relativen Verschiebungen des Dreiecks werden in der aktuellen Richtung des Dreiecks ausgeführt
    • Die Ausrichtung des Dreiecks kann relativ durch turn verändert werden

Programmierung in Lua

Definition 9. (Turtle Grafik)

\[\begin{mdmathpre}%mdk
\mdmathindent{2}\mathkw{move}(\mathid{delta}:\mathid{number})\\
\mdmathindent{2}\mathkw{turn}(\mathid{degree})\\
\mdmathindent{2}\mathkw{jump}(\mathid{delta})\\
\mdmathindent{2}\mathkw{posn}(\mathid{x}:\mathid{number},\mathid{y}:\mathid{number})\\
\mdmathindent{2}\mathkw{pnsz}(\mathid{width}:\mathid{number})\\
\mdmathindent{2}\mathkw{pncl}(\mathid{color}:\mathid{string})\\
\mdmathindent{2}\mathkw{crcl}(\mathid{x},\mathid{y},\mathid{r})\\
\mdmathindent{2}\mathkw{oval}(\mathid{x},\mathid{y},\mathid{w},\mathid{h})
\end{mdmathpre}%mdk
\]

Beispiel 1. (Iteratives Zeichnen einer Blume)

require "turtle"
for i=1,12 do
  for j=1,12 do
    move(50)
    turn(30)
  end
  turn(30)
  wait(0.1)
end

Programmierung in Lua

Objekte und Klassen

  • Beben der reinen prozeduralen Programmierung mit Funktionen und Records (Tables) kann in Lua auch auf einfache Weise objektorientiert programmiert werden

  • Dabei werden Tabellen wieder verwendet um Objekte und Klassen zu implementieren

  • Jedoch ist die Unterstützung von Lua nur gering Verwendung der class Bibliothek, die in der pervasives Bibliothek enthalten ist (wird von lvm direkt geladen)

  • Bei der Instanziierung von Objekten werden i.A. Daten des Objekts mit Parameterwerten initialisiert Definition einer Initialisierungsfunktion erforderlich!

  • Ein Objekt kann sich selbst mit self referenzieren

Programmierung in Lua

Definition 10. (Definition von Klassen und Instanziierung von Objekten)

\[\begin{mdmathpre}%mdk
\mathkw{require}('\mathid{class}')\\
\mathid{geo}=\mathkw{class}()\\
\mathkw{function}~\mathid{geo}:\mathid{init}(\mathid{p}_{1},\mathid{p}_{2},\mathid{p}_{3})~\mathkw{self}.\mathid{a}=\mathid{p}_{1};~\mathkw{self}.\mathid{b}=\mathid{p}_{2};~..~\mathid{end}\\
\mathkw{function}~\mathid{geo}:\mathid{meth}_{1}()~\mathkw{self}.\mathid{xx}~=~..~\mathkw{end}\\
\mathkw{function}~\mathid{geo}:\mathid{meth}_{2}()~..~\mathkw{end}\\
\mathid{o}=\mathid{geo}:\mathkw{new}(\mathid{v}_{1},\mathid{v}_{2},\mathid{v}_{3})\\
..\\

\end{mdmathpre}%mdk
\]

Programmierung in Lua

Ein Objekt einer Klasse kann sich selber über die Variable self referenzieren.

  • Neben dem Punktoperator, mit dem allgemein ein Attribut eines Objektes ausgewählt werden kann, kann der Doppelpunktoperator verwendet werden, um Methodenaufrufe automatisch mit der Selbstreferenz auszuführen.
  • Bei der Verwendung des Punktoperators muss als erstes Argument immer das Objekt selber übergeben werden.
c.m(c,v1,v2,..)
-- Analog kurze Schreibweise
c:m(v1,v2,..)

  1. Eine neue leere Klasse mit der class Funktion erzeugen
c = class()

Programmierung in Lua

  1. Eine Initialisierungsfunktion für diese Klasse definieren. Die Initialisierungsfunktion wird bei jedem instanziierten Objekt einmalig aufgerufen.
function c:init (p1,p2,..) .. end
  1. Weitere Methoden der Klasse definieren:
function c:m (p1,p2,..) .. end
  1. Objekete mit der new Methode erzeugen
local o = c:new(v1,v2,..)

LUAOS

Konzept

LUAOS: Lua Operating System

  • LUAOS wird auf einem Rechner (Netzwerkknoten) durch eine Lua VM ausgeführt (lvm)

  • LUAOS bietet einen WEB basierten Zugriff auf Rechnerknoten

    • Skriptausführung über eine Shell mit Monitoring
  • LUAOS:

    • Ausführung von Skripten in einem Sandkasten
    • Scheduling und Multithreading
    • Einfache Sensor und Geräte API

Konzept

  • Ein Skript wird in einem eigenen gekapselten Thread ausgeführt (mit jeweils eigenen Ausführungszustand und VM)
    • Ein Skript kann weitere Fibers erzeugen
    • Ein Skript hat einem maximale durchgehende Laufzeit von einer Sekunde (danach wird das Skript abgebrochen)
    • Die Ausführung muss daher durch blockierende IO, der yield, oder der sleep Funktionen unterbrochen werden

WEB Interface

  • Das LUAOS ist über ein WEB Interface erreichbar

figluaosweb1


Abb. 3. Typische Schnappschuss der LUAOS WEBAPI mit Netzwerkübersicht (links oben) und verschiedenen Fenstern

LUAOS Architektur

figluaos


Abb. 4. Verteiltes LUAOS System mit WEB API

LUVM Architektur

  • Die LUAOS VM (LUVM) besteht aus:
    • LUA Parser Skripttext wird direkt in Bytecode Instruktionen übersetzt (kein Parserbaum und AST)
    • LUA Bytecode Interpreter (BC Loop ist in Assembler programmiert!)
    • LUA JIT Compiler der zur Laufzeit BC in nativen Maschinencode übersetzt
    • LUA-C API für native Erweiterungen
    • Automatisches Speichermanagement mit Garabage Collector (Nicht inkrementeller Mark & Sweep Algorithmus)
    • Asynchrone IO mit einer UV Loop (libuv, wird auch in node.js verwendet)
    • LUV: LUA-UV API Interface
    • LUV Module: Thread, Fiber, State, Filesystem (FS), Network (Net), Timer, Process, Pipe, Codec (Serialisierung)

LUVM Architektur

figluvm


Abb. 5. Aufbau der LUAOS VM

Skript API

function clock() → number

Gibt die aktuelle Systemzeit in Millisekunden zurück

function print(…)

Ausgabe von Text oder Werten auf der virtuellen Konsole

function sleep(millisec)

Der aufrufende Prozess wird für die angegebene Zeit blockiert

function yield()

Blockierender Aufruf des Schedulers und Abgabe der Ausführung (an andere Prozesse) mit späterer Fortführung

Fiber

  • Leichtgewichtige Tasks (werden geschachtelt sequenziell ausgeführt)
function fiber.create (function(args…), args…) → fiber

Erzeugt einen neuen leichtgewichtigen Prozess. Der Prozess ist sofort ausführungsbereit.

function fiber:join()

Der aufrufende Prozess wird blockiert bis der Subprozess terminiert ist

Skript API

HTTP

  • HTTP Server und Klienten
function http:new() → http

Erzeugt eine neue HTTP Instanz

function http:get(url, function (data,error))

Ausführung einer HTTP GET Anfrage. Das Ergebnis (Fehler oder Daten) wird durch eine asynchrone Rückruffunktion bearbeitet.

function http:put(url, data, function (data,error))

Ausführung einer HTTP OUT Anfrage. Das Ergebnis (Fehler oder Daten) wird durch eine asynchrone Rückruffunktion bearbeitet.

function http:service(ipport, function (url,address,params,body) → string)

Installation eines HTTP Service (IP Port ipport). Eingehende GET/PUT Anfragen werden durch eine Rückruffunktion bearbeitet. Das Ergebnis der Anfrage wird von dieser Funktion als Text zurück gegeben.

Skript API

HTML

  • Ein HTML Text Formattierer
function html:new() → html

Erzeugt eine neue HTML Formattierungssnstanz

function html:html(head:html string,body: html string) → string

Erzeugt den Rahmen einer HTML Seite

function html:head() → string

Erzeugt den Kopf einer HTML Seite

function html:body(html string table) → string

Erzeugt den Inhalt einer HTML Seite

function html:table(head table, body table table) string Weitere Funktionen: h1, h2, h3, ol, ul, li, dl, dt, dd

Skript API

Timer

  • Intervalltimer die in Fibers und Skripten benutzt werden können um periodisch Tasks auszuführen
function timer:new() → timer

Erzeugt einen neuen Timer.

function timer:start(interval:number,period:number)

Startet den Timer mit dem angegebenen Intervall und der Periodenzeit (oder 0). Nach Ablauf des Intervalls wird ein Ereignis signalisiert, auf welches mit der await Operation gewartet werden kann.

function timer:stop()

Stoppt den Timer. Es werden keine weiteren Ereignisse mehr signalisiert.

function timer:wait()

Auf ein Timerereignis warten. Der aufrufende Prozess wird blockiert.

Skript API

Sensor

  • Zugriff auf und Implementierung von Sensoren
function sensor:all() → table

Gibt eine Liste alle verfügbaren Sensoren zurück (Liste der Namen)

function sensor:new(sensorclass:string,…) → sensor

Erzeugt eine neue Sensorinstanz vom Typ sensorclass. Mögliche Klassen sind: “temperature”, “cpu”.

function sensor:read() → number|string|table|nil

Gibt den aktuellen Sensorwert zurück.

function sensor:calibrate?(…)

Kalibriert den Sensor oder die Sensorfunktion.

Skript API

Actor

function actor:all() → table

Gibt eine Liste alle verfügbaren Aktuatoren zurück (Liste der Namen)

function actor:new(actorclass:string,…) → actor

Erzeugt eine neue Aktuatorinstanz vom Typ actorclass. Mögliche Klassen sind: “dotdisp”".

function actor:reset(…)

Setzt den Aktuator in einen definierten Anfangszustanf.

function actor:set(…)

Setzt eine Steuervariable mit einem neuen Aktuatorwert.

function actor:get?(string) → number|string|table|nil

Gibt den Wert einer Aktuatorvariable zurück.

function actor:control?(…)

Ausführung eines Steuerkommandos.

Skript API

Punktmatrix Ausgabegerät
  • 8 rows and 8 cols LED matrix
  • Driven by HT16K33 chip
  • Access to I2C communication pins

fig500px-KS0336_3

fig600px-Pinouts

Skript API

Beispiele

-- Actor DOTS Matrix
local dot = actor:new('dots')
dot:reset()
-- dot:set(on,row,col)
dot:set(1,4,4)
sleep(1000)
dot:set(0,4,4)

-- Sensor CPU Temperatur
local s = sensor:new('temperature')
print(s:read())

Asynchrone Ereignisverarbeitung

Synchrone Verarbeitung
Die aufrufende Operation, z.B. das Lesen aus einer Datei, wird solange “blockiert”/wartet (genauer die Prozessausführung), bis das Ereignis eingetreten ist, d.h. im Beispiel die Daten gelesen wurde.
  • Eine synchrone Operation (Prozedur) gibt das Ergebnis der Operation direkt zurück
Asynchrone Verarbeitung
Die aufrufende Operation wartet nicht auf das Eintreten des Ereignisses (keine Blockierung), und der Prozesse fährt unmittelbar danach in der Ausführung folgender Operationen fort.
  • Jetzt wird eine Rückruffunktion verwendet, um beim Eintreten des Ereignisses die Daten (oder das Ereignis) verarbeiten zu können.
  • In JavaScript werden i.A. alle Ein- und Ausgabeoperation asynchron ausgeführt. In Lua gibt es eine ausgewogene Mischung, bzw. die synchrone Variante ist vorherrschend.

Asynchrone Ereignisverarbeitung

Definition 11. (Synchrone Ereignisverabeitung)

\[\begin{mdmathpre}%mdk
\mathid{result}~=~\mathid{ioop}_{1}^\mathid{synchron}(\mathid{arg}_{1},\mathid{arg}_{2},..)\\
\mathid{result}~=~\mathid{ioop}_{2}^\mathid{synchron}(\mathid{arg}_{1},\mathid{arg}_{2},..)\\
..
\end{mdmathpre}%mdk
\]

Process=ioop1synchronioop2synchronnext

Definition 12. (Asynchrone Ereignisverabeitung)

\[\begin{mdmathpre}%mdk
\mathid{ioop}_{1}^\mathid{asynchron}(\mathid{arg}_{1},\mathid{arg}_{2},..,\mathkw{function}_{1}~(\mathid{p}_{1},\mathid{p}_{2},..)~\mathid{processing}~\mathkw{end})\\
\mathid{ioop}_{2}^\mathid{asynchron}(\mathid{arg}_{1},\mathid{arg}_{2},..,\mathkw{function}_{2}~(\mathid{p}_{1},\mathid{p}_{2},..)~\mathid{processing}~\mathkw{end})\\
..
\end{mdmathpre}%mdk
\]

Process=ioop1asynchronioop2asynchronnext..function1function2 |
ioop1asynchronioop2asynchronnext..function2function1 |
ioop1asynchronfunction1ioop2synchronnext.. | ..

Asynchrone Ereignisverarbeitung

Beispiele in Lua

  • Die sleep Operation kann verwendet um den aktuellen Programmfluss für eine bestimmte Zeit (Millisekunden) anzuhalten

Beispiel 2. (Synchrone Verzögerung einer Serviceschleife)

\[\begin{mdmathpre}%mdk
\mathkw{local}~\mathid{s}~=~\mathid{sensor}:\mathid{new}('\mathid{temperature}')\\
\mathkw{local}~\mathid{doit}~=~\mathid{true}\\
\mathkw{while}~\mathid{doit}~\mathkw{do}\\
\mdmathindent{2}\mathkw{local}~\mathid{v}~=~\mathid{s}:\mathid{read}()\\
\mdmathindent{2}\mathkw{print}~('\mathid{The}~\mathid{current}~\mathid{temperature}~\mathid{is}~'..\mathid{v})\\
\mdmathindent{2}\mathkw{sleep}~(1000)\\
\mathkw{end}
\end{mdmathpre}%mdk
\]

Asynchrone Ereignisverarbeitung

  • Alternativ kann auch ein Timer erzeugt werden. Nach dem Start des Timers (mittels der start Methode und der Angabe des Zeitintervalls bis ein Timerereignis ausgelöst wird und dem Zeitintervall zwischen zwei Ereignissen) kann mittels der wait Methode der Prozessfluss angehalten werden bis ein Timerereignis eintritt

Beispiel 3. (Synchrone Verzögerung einer Serviceschleife mit einem Timer)

\[\begin{mdmathpre}%mdk
\mathkw{local}~\mathid{s}~=~\mathid{sensor}:\mathid{new}('\mathid{temperature}')\\
\mathkw{local}~\mathid{t}~=~\mathid{timer}:\mathid{new}()\\
\mathkw{local}~\mathid{doit}~=~\mathid{true}\\
\mathid{t}:\mathid{start}(1000,1000)\\
\mathkw{while}~\mathid{doit}~\mathkw{do}\\
\mdmathindent{2}\mathkw{local}~\mathid{v}~=~\mathid{s}:\mathid{read}()\\
\mdmathindent{2}\mathkw{print}~('\mathid{The}~\mathid{current}~\mathid{temperature}~\mathid{is}~'..\mathid{v})\\
\mdmathindent{2}\mathid{t}:\mathid{wait}()\\
\mathkw{end}
\end{mdmathpre}%mdk
\]

Asynchrone Ereignisverarbeitung

Beispiel 4. (Periodische asynchrone Ausführung einer Serviceschleife)

\[\begin{mdmathpre}%mdk
\mathkw{local}~\mathid{s}~=~\mathid{sensor}:\mathid{new}('\mathid{temperature}')\\
\mathid{setInterval}(1000,~\mathid{function}~()\\
\mdmathindent{2}\mathkw{local}~\mathid{v}~=~\mathid{s}:\mathid{read}()\\
\mdmathindent{2}\mathkw{print}~('\mathid{The}~\mathid{current}~\mathid{temperature}~\mathid{is}~'..\mathid{v})\\
\mathkw{end})
\end{mdmathpre}%mdk
\]

Beispiel 5. (Asynchrone Implementierung eines HTTP WEB Servers)

\[\begin{mdmathpre}%mdk
\mathkw{local}~\mathid{H}~=~\mathid{html}:\mathid{new}(\{\})\\
\mathkw{local}~\mathid{s}~=~\mathid{sensor}:\mathid{new}("\mathid{temperature}")\\
\mathid{http}:\mathid{service}(8080,\mathkw{function}~(\mathid{req},\mathid{url},\mathid{remote},\mathid{params})\\
\mdmathindent{2}\mathkw{return}~\mathid{H}:\mathid{html}(\mathid{H}:\mathid{head}(),\mathid{H}:\mathid{body}(\{\\
\mdmathindent{5}\mathid{H}:\mathid{h}_{1}("\mathid{Temperature}"),\\
\mdmathindent{5}\mathid{H}:\mathid{p}(\mathid{s}:\mathid{read}())\\
\mdmathindent{3}\}))\\
\mathkw{end})
\end{mdmathpre}%mdk
\]

Asynchrone Ereignisverarbeitung

Aufgabe

  1. Was ist der Nachteil bei der Verwendung eines Timers mit explizitem Warten auf das Ereignis im Vergleich zur sleep Operation oder der asynchronen Ausführung mittels setInterval?

  2. Was sind Vorteile und Nachteile der synchronen gegenüber der asynchronen Ereignis- und Datenverarbeitung?