Skip to main content

Über den Unterschied zwischen Architekturentwurf und Design

„Seit Jahrzehnten wird die Softwarearchitektur als wesentlicher Meilenstein auf dem Weg der Informatik zu einer „erwachsenen” Ingenieurs-Disziplin beschworen. Das planvolle Entwerfen und Bauen von Gebäuden und Brücken wird uns Softwareingenieuren als metaphorisches Zielbild für unser Tun aufgezeigt. .... .... Aber wie nah sind wir wirklich unserem Ziel, in den erlauchten Kreis der „echten” Ingenieure aufgenommen zu werden?
(Thomas Janning 2012)

Diese Worte entstammen dem Editorial der OBJECTspektrum Ausgabe 03/ 2012 mit dem Schwerpunktthema Architektur. Ich finde die Frage ist berechtigt. Wie auch Thomas Janning im weiteren Verlauf die Frage wieder relativiert, bin auch ich sicher, dass im Software Engineering heute hochgradige Ingenieurskunst geleistet wird. Aber das ändert nichts daran, dass wir Ingenieure im Bereich Software Architektur noch einige Hausaufgaben zu machen haben.

Leider richtet sich die OBJECTspektrum im wesentlichen an das Software Engineering für so genannte Enterprise Software. Und die meisten Inhalte darin sind nicht übertragbar auf das Software Engineering für Embedded Systeme.

Da das Thema aber auch in dieser Domäne nicht minder wichtig ist hat wieder eine Ausgabe des Embedded Software Engineering Reports das Thema Software Architektur

Architekturentwurf und nichtfunktionale Anforderungen

Ebenfalls in der OBJEKTspektrum lese ich den Artikel ,Softwarearchitektur in agilen Projekten: von Kathedralen und IT-Systemen‘ von Dr. Markus Voß. Und er führt noch einmal klar vor Augen, wie grundlegend wichtig es ist zwischen Architektur und Design zu trennen. Der architektonische Entwurf legt den Grundstein für das Software Design. Was ist nun der Unterschied zwischen Architekturentwurf und Design?

Stellen Sie sich vor, sie sollten ein Regalsystem designen. Dann gibt es grundsätzlich die funktionalen Anforderungen zu berücksichtigen, als da wären: Höhe, Breite, Tiefe, Anzahl der Regalböden, aber auch Anforderungen an Haptik und Optik. Unser Regal soll zum Beispiel aus Massivholz bestehen.

Funktionale Anforderungen wirken sich im wesentlichen auf das Design aus.

Wenn wir nun das Regal produzieren möchten stellen sich uns weitere Fragen. Z.B. könnten wir das Regal aus einem großen Baumstamm aus dem ,Vollen‘ fräsen. Sicher eine Ressourcen verschwendende und ineffiziente Vorgehensweise. Etwas eleganter wäre die Verwendung eines architektonischen Basis-Mechanismusses ,Teile und Herrsche‘ anzuwenden. Wir würden also den Baumstamm erst einmal in Bretter zersägen, um aus ihnen dann Seitenwände, Regalböden usw. aufzubauen. Entsprechend den Abmaßen der funktionalen Anforderungen könnten wir also die Bretter auf Maß zuschneiden.

Nun stellt sich eine wesentliche Frage: Wie verbinden wir die Bretter zum Gesamtsystem ,Regal‘? Wir können sie mit Leim und geeigneten Mustern z.B. einer Schwalbenschwanz-Verzahnung zusammenfügen. Hier sind wir beim Thema Architektur-Stil angelangt. Die Architektur hat starken Einfluss auf die Handhabbarkeit des Regals im so genannten Livecycle. Zum Beispiel im Fall eines Umzuges könnte das Regal nicht ab- und aufgebaut werden, es müsste ab dem Zeitpunkt der Produktion immer im Ganzen transportiert werden. Ebenso auf die Veränderbarkeit oder Erweiterbarkeit. Das nachträgliche Verändern der Höhe der Regalböden wäre nicht möglich.

Würden wir das Regal auf Basis von Schrauben aufbauen, dann würden sich Handhabbarkeit oder Erweiterbarkeit schon sehr viel verbessern. Für die Befestigung der Regalböden spezielle Architekturmuster anzuwenden, z.B, vorgebohrte Löcher mit kleinen Stiften, würde Flexibilität und Handhabbarkeit noch einmal stark verbessern.

Eventuell würden sich die Anwendung eines Architektur-Musters wiederum negativ auf die Gesamtstabilität des Regals auswirken.

Was erkennen wir daraus: Nichtfunktionale Anforderungen (Wartbarkeit, Erweiterbarkeit, Robustheit ...) zielen auf den Architekturentwurf eines Systems. Funktionale Anforderungen (Größe, Farbe, Funktion ...) zielen auf das Design eines Systems.

Die Rolle von Muster und Normen im Architekturentwurf

Bevor ich auf Architektur-Stile (Muster oder auch Pattern) im Software Engineering eingehe möchte ich noch etwas tiefer auf Muster an sich eingehen.

Vor einiger Zeit habe ich einen Bauernkasten von 1807 (so werden die alten Schränke in der Steiermark genannt) von meinen Großeltern geerbt. Er besteht aus zwei Teilen, die mit 4 Holzschrauben und Muttern verbunden sind. Für den Transport nach Deutschland habe ich ihn auseinander geschraubt. Als ich ihn dann, zuhause angekommen, wieder zusammen bauen wollte, stellte ich mit Erstaunen fest, dass jeweils nur eine Mutter auf genau eine Schraube passte. Die Gewinde waren noch von Hand erstellt.

Als Grundprinzip einer leicht lösbaren Verbindung, lässt sich schon an der 200 Jahre alten Schraube, das Muster (Pattern) des Gewindes erkennen.

Heute sehen Schrauben etwas anders aus, etwa wie in nebenstehender Abbildung zu sehen. Das Konzept des Gewindes ist gleichgeblieben, was ist dazu gekommen? Die Norm für metrische Gewinde.

Der Einsatz von so genannten Mustern erhöht die Effizienz im Engineering enorm. Verbunden mit Normen wird diese noch einmal potenziert. Muster in Kombination mit Normen ermöglichen hoch effizientes Outsourcing.

Heute ist es egal, wo auf der Welt Sie eine Mutter kaufen und wo diese Mutter hergestellt wurde. Wenn sie ein metrisches Gewinde und ein metrisches Schlüsselmaß hat, passt sie auf jede Schraube und das Werkzeug mit dem Schraube und Mutter genutzt werden passt auch.

Ohne Muster in Verbindung mit Normen wäre der Maschinenbau nicht dort wo er heute ist.

Produktion und Wartung heutiger Produkte in allen Industrien (Automitive, Aerospace, Railway ...) wären nicht denkbar.

Das Software Engineering steckt in dieser Beziehung noch in den Kinderschuhen. Oder etwa nicht?

Muster, Halbzeuge, Normen und Werkzeuge im Software Engineering

Muster (Pattern) werden im Software Engineering bereits seit Jahrzehnten eingesetzt, z.B. in Form von Scheduling Pattern. Eines der meist eingesetzten Muster in der Embedded Software ist sicher die ,main() Loop‘. Leistungsfähigere Scheduling Pattern können in Form von Halbzeugen als RTOS eingekauft werden.

OSEK OS oder UML liefern uns die Standardisierung in der Anwendung dieser Muster.

Wir sehen also noch einmal mehr, Muster und Normen liefern die Basis für die Umsetzung der nichtfunktionalen Anforderungen, Wartbarkeit, Erweiterbarkeit, Robustheit ... vor allem auch bezogen auf den Lebenszyklus.

Mit dem Hammer in der Hand sieht die Welt aus wie ein Nagel

Würde ein großer schwedischer Möbelhersteller seine Regalsysteme mit einem Schraubenset ausliefern, wie in Abbildung Nr. 2d zu sehen, dann würde die Parodie auf seine Werbung ,Schraubst du noch oder wohnst du schon?‘ eine ganz andere Bedeutung bekommen. Außerdem würde das mitzuliefernde Werkzeugset verglichen mit einem einzelnen Imbus-Schlüssel ganz andere Kosten verursachen.

Haben Sie schon einmal eine Kreuzschlitzschraube mit einem Schlitzschraubenzieher losgeschraubt? Das kann gut gehen, aber die Gefahr dabei Werkzeug oder Halbzeug zu zerstören ist groß. Leider treffe ich im Software Engineering oft auf ähnliche Situationen. Tools, Vorgehen und Muster werden in einer Kombination angewandt, wo nichts wirklich zueinander passt. Wenn sich dann die gewünschte Effizienz nicht einstellt werden Werkzeug, Notation oder Methode die Schuld gegeben.

Ich möchte hier exemplarisch eine immer wieder anzutreffende Kombination und die damit verbundenen Probleme aufzeigen.

Ein Basis-Muster, das jeder Embedded Applikation zu Grunde liegt ist der Scheduling Mechanismus. Im simpelsten Fall ist es die so genannte main() Loop. Grundsätzlich unterscheiden wir in der Charakteristik zwischen einer zeitkontinuierlichen Architektur auf Basis eines zeitgetriebenem Scheduling oder einer zeitdiskreten Architektur auf Basis eines ereignisorientierten Scheduling. (Siehe auch Embedded Software Engineering Report Nr. 27)

In den meisten mir bekannten Applikationen wird derzeit mit zeitgetriebenem Scheduling (Zeitscheiben) gearbeitet.

Nun ist die Modellierung auf Basis von Zustandsmaschinen (MATLAB® Stateflow oder UML Werkzeugen) stark in Mode gekommen. In Zustandsmaschinen gibt es Zustandsübergänge und im ursprünglichen Sinn (State Transition Diagrams nach David Harel 1987) basieren die Zustandsübergänge auf Ereignissen. Hier ergibt sich ein Zustands-Diagramm wie in Abbildung Nr. 3 links oben zu sehen ist. In einer zeitgetriebenen Architektur werden in der Regel jedoch keine Ereignisse sondern Signale (z.B. in Form von Variablen) verwendet.

Um auch in diesen Architekturen auf Basis von Zustandsmaschinen modellieren zu können ermöglichen heute die meisten Werkzeuge auch einen Zustandswechsel auf Basis eines so genannten ,Guard‘ (Überprüfung einer Variablen auf einen Inhalt) durchzuführen. Solch eine Zustandsmaschine sehen Sie in der Abbildung Nr. 3 rechts oben.

Beide Zustandsmaschinen scheinen, bezogen auf ihr logisches Verhalten, erst einmal Identisch zu sein. Betrachten wir jedoch das dynamische Verhalten in grenzwertigen Situationen aus zeitlicher Sicht, dann ergibt sich ein ganz andere Bild.

Mit großer Wahrscheinlichkeit wird unsere CPU neben diesem Verhalten noch andere so genannte Nebenläufigkeiten ausführen müssen. Aus Sicht unserer jeweiligen Zustandsmaschine würde die Zeit, in denen sich die CPU anderen Aufgaben widmet, wie eine Austastlücke erscheinen. (Siehe Abbildung Nr. 3 unten) Ändern sich nun in dieser Austastlücke zwei Signale oder treten zwei Ereignisse auf, dann ist das Verhalten beider Zustandsmaschinen unterschiedlich.

Die ereignisgetriebene Zustandsmaschine besitzt ein Gedächtnis in Form der Event Queue, in der die Reihenfolge der Ereignisse gespeichert sind. Die zeitgetriebene Zustandsmaschine hingegen kann die Reihenfolge der Änderungen nicht nachvollziehen.

Nun ist es in dieser Logik, in der auf Basis von 3 Tastern Lautstärke oder Helligkeit erhöht oder verringert werden kann ein Unterschied. Mit der Mode Taste kann zwischen Helligkeit und Lautstärke geschaltet werden, mit der Plus oder Minus Taste wird dann entweder Helligkeit oder Lautstärke verändert.

Steht also unser Mode in Helligkeit und wir möchten die Lautstärke erhöhen, dann würden wie zuerst die ,Mode‘ Taste drücken und danach die ,Plus‘ Taste. Die umgekehrte Reihenfolge würde anstelle dessen die Helligkeit erhöhen.

In der Praxis ereignen sich derartige Effekte immer wieder, wenn z.B. Jitter kurzzeitig Zeitverschiebungen verursachen. Das Finden derartiger Fehler ist in der Regel extrem zeitaufwändig, da die daraus resultierenden Fehler nur selten reproduzierbar sind. (Auch hier gilt das Nyquist-Shannon Abtasttheorem.)

Die Antwort auf dieses Problem in 90% der praktischen Fälle sehen Sie in Abbildung Nr. 4a. Hier ist eine Zustandsmaschine mit zeitgetriebener Architektur so modelliert, dass sie auch aus zeitlicher Sicht immer ein deterministisches Verhalten liefert.

Aber, wie sieht es jetzt mit der Verstehbarkeit aus? Auch wenn nun MATLAB® Stateflow Anwender evtl. anmerken, dass in Stateflow, die in diesem Diagramm auf Basis von Conditions definierten Reihenfolgen, direkt innerhalb von Zuständen angegeben werden können. Damit ist die überlagerte Logik nur weggeblendet. Die damit verbundene Komplexität im Verhalten aber trotzdem vorhanden. (Ich persönlich halte das für noch gefährlicher)

∨ mehr Text anzeigen

Was hier schief läuft erkennen wir, wenn wir die Zustandsmaschine in Abbildung Nr. 4b in die Betrachtung einbeziehen. Hier ist die gleiche Logik ebenfalls aus zeitlicher Sicht deterministisch modelliert, jedoch mit einem ganz anderen gedanklichen Ansatz. Woher dieser Ansatz kommt wird sofort klar, wenn wir das Aktivitätsdiagramm in Abbildung Nr. 4c betrachten. Ähnlichkeiten sind sicher nicht zu verleugnen.

In zeitgetriebenen Systemen mit Kommunikation auf Basis von Signalen kennen Nebenläufigkeiten (Prozesse) nach einem Scheduling ihre Vergangenheit nicht mehr. Es gibt keine Hinweise darauf welche Signale sich in der Austastlücke geändert haben, aus diesem Grund muss jedes Signal abgefragt werden. Das ist in einem Ablaufdiagramm (Aktivitätsdiagramm oder Flussdiagramm) sehr viel eleganter zu modellieren, als in einem Zustandsdiagramm.

Grundsätzlich gilt:

  • In zeitgetriebenen (zeitkontinuierlichen) Architekturen mit Signalen lässt sich Verhalten wesentliche eleganter mit ablauforientierten Diagrammen modellieren.
  • In ereignisgetriebenen (zeitdiskreten) Architekturen mit Ereignissen lassen sich Verhalten wesentlich eleganter mit Zustandsautomaten modellieren.

Das wird noch einmal richtig deutlich, wenn wir einen Blick auf den generierten Code aus den verschiedenen Lösungsansätzen werfen. (Abbildung Nr. 4 unten) In diesen Beispielen stehen ca. 250 Zeilen C-Code 30 Zeilen C-Code gegenüber.

Leider treffe ich sehr häufig auf Projekte, in denen symbolisch ausgedrückt Schrauben mit dem Hammer eingeschlagen werden und wenn das Resultat dann nicht den Vorstellungen entspricht werden Notation, Vorgehen oder Werkzeug die Schuld dafür gegeben.

Obiges Beispiel ist nur stellvertretend zu sehen. In der Praxis erlebe ich gerade im Bereich der Architektur historisch gewachsene, verkrustete Strukturen, die sich natürlich negativ auf die Software Qualitätsattribute auswirken.

Wie es besser geht

Ich möchte Ihnen nun einen Architekturentwurf vorstellen, der vielen Applikationen auf die ich in der Praxis stoße ansatzweise gerecht wird. Natürlich hat jede Applikation ihre individuellen nichtfunktionalen Anforderungen. Also sehen Sie folgendes Beispiel nicht als den Eierlegenden Wollmilchsau-Ansatz für eine Architektur, auch wenn es den Eindruck erwecken könnte.

Eine Architektur sollte grundsätzlich so einfach wie möglich gehalten werden und nur so komplex wie notwendig. Preemptives Scheduling zum Beispiel erhöht nicht nur die Komplexität des Scheduling, sondern damit verbunden auch die Latenzzeiten der Taskwechsel erheblich. Wo es nicht benötigt wird sollte es auch nicht eingesetzt werden. Auf der anderen Seite kann Preemptives Scheduling dort wo es sinnvoll ist das Systemdesign wesentlich vereinfachen. Aus Angst vor preemptivem Scheduling, die Komplexität in das Design zu verlagern, wäre genau so falsch.


„Nichts ist einfacher als das Komplizieren.“
Georges Elgozy ( Politiker und Autor, 1909-1989)

Wie wird eine Architektur entwickelt?

Die meisten Embedded Systeme entsprechen heute in ihrem Basis-Verhalten einem reaktiven System. Die Logiken von reaktiven Systemen wiederum lassen sich sehr elegant auf Basis von Zustandsmaschinen, und diese wiederum auf Basis von grafischen Zustandsdiagrammen z.B. nach David Harel (UML) modellieren.

Unterhalb der Steuerungen und logischen Verhalten befinden sich bei technischen Systemen häufig noch zeitgetriebene Funktionen (Operationen) wie z.B. Regler, Motorsteuerungen u.s.w.

Sehr häufig wird auf Grund der zeitgetriebenen Anforderungen dieser Operationen die Gesamtarchitektur eines Systems laufzeitorientiert (Zeitgetriebenes Scheduling) organisiert. Wie wir oben gesehen haben lassen sich Zustandsmaschinen mit einer zeitgetriebenen Laufzeitarchitektur nur sehr ineffizient kombinieren.

Nun muss aber nicht grundsätzlich auf die Modellierung auf Basis von Zustandsmaschinen verzichtet werden. Natürlich können verschiedene Architektur-Muster mit Modellierungsansätzen kombiniert werden, ohne das Wildwuchs entsteht. Hier ein Beispiel:

Die Anforderungen

Zu Beginn möchte ich ein paar Anforderungen definieren, die unsere Architektur erfüllen soll. Ich orientiere mich dabei an den Anforderungen, auf die ich in realen Projekten häufig stoße.

Unser fiktives System besitzt eine, in den Jahren immer komplexer gewordene, Systemebene. Diese muss auf Basis unterschiedlichster Betriebsmodi, situationsbedingt mit mehr oder weniger komplexen Abläufen auf Veränderungen in seiner Umwelt reagieren. Die meisten dieser Veränderungen haben aus äußerer Sicht den Charakter von Ereignissen.

Es gibt aber auch Signale, die abgetastet werden müssen und auf die mit Regelzyklen reagiert werden muss. Die Regelzyklen wiederum sind von den Betriebsmodi und Situationen abhängig und werden durch die Systemebene parametrisiert. Parallel zu diesen Regelungen muss weitere Sensorik und Aktorik bedient werden.

Typische Reaktionszeiten auf der Systemebene liegen in der Größenordnung von Millisekunden (ms). Typische Abtastraten und Reaktionszeiten der Regler und der Bedienung der Sensorik und Aktorik liegen in der Größenordnung von Mikrosekunden (µs).

Fehler des Systems, die im Betrieb auftreten, können bei den Anwendern zu finanziellen Schäden führen. Die aktuelle Produktlinie ist für Ihre Robustheit im Feld bekannt und das ist eines der Hauptverkaufsargumente. Das neue System soll dieser Robustheit entsprechen, darf aber nicht teurer sein als das derzeitige System. Wenn möglich sollen die Hardware-Kosten reduziert werden.

Das derzeitige System ist, auf Grund der seit der Einführung vor 12 Jahren stetig gestiegenen Anforderungen, nicht mehr effizient änderbar. Kleine Änderungen müssen mit hohem Testaufwand geprüft werden, damit die von den Kunden gewohnte Qualität weiterhin gesichert ist. Das neue System soll in dieser Hinsicht effizienter an neue Anforderungen angepasst und um neue Funktionalität erweitert werden können.

Der Lebenszyklus wird wie beim aktuellen System auf mindestens 8 Jahre geplant. Über diesen Zeitraum soll die Pflege und Weiterentwicklung effizient und ohne Qualitätsverlust gewährleistet sein.

Wenn Sie obige Anforderungen betrachten, was fällt Ihnen auf?

Ich habe ausschließlich nichtfunktionale Anforderungen definiert. Wie wir oben gesehen haben liefern die nichtfunktionalen Anforderungen die wesentlichen Aspekte zum Entwurf der Architektur. Und aus diesem Grund wird im Architektur-Entwurf auch der Grundstein für die Qualitätsattribute gelegt.

Die Steuerungs- oder Systemebene

Betrachten wir übliche Systeme, dann besitzen diese, wie unser Beispiel, in der Regel eine Steuerungs- oder Systemebene. Hier befindet sich in der Regel die eigentliche Komplexität, die üblicherweise über die Jahre gewachsen ist.

Die Steuerungen der Systemebene müssen auf Basis unterschiedlichster Betriebsmodi, situationsbedingt mit mehr oder weniger komplexen Abläufen auf Veränderungen der Umwelt reagieren. Die meisten dieser Veränderungen haben den Charakter von Ereignissen.

In dieser Ebene finden im Verlauf des Lebenszyklus die meisten Änderungen statt, die durch die stetig steigende Komplexität zunehmend ineffizient durchgeführt werden können.

Mit Hilfe von Zustandsautomaten auf Basis von Zustandsdiagrammen kann größere Komplexität implementiert und gewartet werden. UML Modellierungs-Werkzeuge, MATLAB® Stateflow, IAR VisualSTATE® und andere Werkzeuge erfreuen sich aus diesem Grund wachsender Beliebtheit. Auch in unserem Fall möchten wir Verhaltensanteile auf der Systemebene auf Basis von Zustandsmaschinen modellieren. Daraus lässt sich folgende Anforderung an die Architektur ableiten. 

1. Anforderung an die Architektur: Die Laufzeitarchitektur auf der Systemebene ist ereignisgetrieben.

Die Interruptebene

Aber unser System beinhaltet auch Regler. Nun lassen sich wiederum Regler auf Basis einer ereignisgetriebenen Laufzeitarchitektur nicht effizient abbilden. Ebenso haben wir Signale abzutasten, was für eine zeitgetriebene Architektur prädestiniert ist.

Die Reaktionszeiten dieser Anteile von Systemen sind in der Regel wesentlich schneller, als die auf der Systemebene. So auch in unserem Fall. Auf der Systemebene liegen die Reaktionszeiten im Bereich von ms die Abtastung bzw. Generierung der Signale der Aktorik und Sensorik und die Zykluszeiten der Regler liegen im Bereich von µs.

Aus diesem Grund bietet es sich an unterhalb der Systemebene zum Beispiel auf Basis des Interrupt Systems eine zeitgetriebene Laufzeitarchitektur zu realisieren.

Da sich das Zeitverhalten z.B. von Reglern direkt auf die Regeleigenschaft auswirkt, kommt es auf dieser Ebene auf ein sehr exaktes Zeitverhalten an. Bereits sehr kleine Jitter können die Genauigkeit von Reglern stark beeinflussen.

Bezüglich der beiden Ebenen können folgende Anforderungen definiert werden:

2. Anforderung an die Architektur: Unterhalb der Systemebene gibt es eine zeitgetriebene Laufzeitarchitektur auf der Interruptebene. Diese hat hohe Anforderungen an das Echtzeitverhalten. Reaktionen in µs mit geringst möglichem Jitter.

Grundsätzlich lässt sich nun folgendes zur Laufzeitarchitektur festhalten.

Es gibt zwei Ebenen mit den jeweiligen folgenden grundsätzlichen Anforderungen:

    Anforderung an die Systemebene

    • Große Komplexität, vergleichsweise geringe Zeitanforderungen
    • Steuert über die Interruptebene die Aktorik
    • Bekommt von der Interruptebene Veränderungen der Umwelt mitgeteilt

    Anforderung an die Interrupt Ebene

    • Geringe Komplexität, vergleichsweise hohe Zeitanforderungen
    • Reagiert auf Steuerungsanweisungen aus der Systemebene
    • Scannt Signale und gibt signifikante Änderungen an die Systemebene weiter
    • Regelungen auf dieser Ebene reagieren direkt auf Signale

    Die Kommunikation

    Nun gelten bezüglich der Architekturmuster in zeitgetriebenen und ereignisgetriebenen Architekturen ganz spezielle Anforderungen an die Kommunikation. Grundsätzlich kann angenommen werden, dass die Verwendung von Ereignissen in zeitgetriebenen Systemen ungünstig ist und die Verwendung von Signalen in ereignisgetriebenen Systemen. (Siehe auch Embedded Software Engineering Report Nr. 27)

    Das bedeutet für unseren Architekturentwurf folgende weitere Anforderungen:

    3. Anforderung an die Architektur: Auf der Systemebene werden zur Kommunikation ausschließlich Ereignisse eingesetzt.

    4. Anforderung an die Architektur: Auf der zeitgetriebenen Interruptebene werden zur Kommunikation ausschließlich Signale eingesetzt.

    Zwischen diesen beiden Ebenen gibt es einen Datenfluss. Zum Beispiel wird das Verhalten der Regler abhängig von Systemzuständen durch die Systemebene parametrisiert. Hierfür muss die Systemebene den Reglern auf der Interruptebene Daten liefern.

    Umgekehrt empfängt die Interruptebene von der Sensorik Daten, die in der Systemebene benötigt werden. Die Interruptebene muss also Daten an die Systemebene liefern können.

    In Kombination mit obigen Anforderungen ergeben sich folgende weitere Anforderungen:

    ∨ mehr Text anzeigen

    5. Anforderung an die Architektur: Zur Kommunikation von der Interruptebene zur Systemebene müssen Signale in Ereignisse konvertiert werden.

    6. Anforderung an die Architektur: Zur Kommunikation von der Systemebene zur Interruptebene müssen Ereignisse in Signale konvertiert werden.

    Da die Interrupt Ebene zeitlich schneller reagieren muss, als die Systemebene muss diese die Systemebene preemptiv unterbrechen. In unserer Architektur werden wir dem, durch die Nutzung von Interrupts, gerecht. Preemptives Verhalten hat nun wieder Anforderungen an die Kommunikation. Will z.B. eine Nebenläufigkeit auf der Systemebene, beispielsweise die Parametrisierung der Regler, die Daten für einen Regler auf der Interruptebene schreiben, kann diese durch den Regler selbst dabei unterbrochen werden. Dieses würde dann zu inkonsistenten Daten führen. Es muss also sicher gestellt werden, dass bei Unterbrechungen keine inkonsistenden Daten entstehen.

    Hierfür ist es üblich die Daten auf Basis von Semaphoren zu schützen. Diese haben aber einen großen Nachteil: sie agieren auf der Zeitebene.

    In unserem Fall würde das bedeuten, die Routine zur Reglerparametrisierung setzt vor dem Schreibvorgang ein Semaphor (i.d.R. in Form eine Interrupt-Sperre). Damit würde für den eigentlichen Regler ein Jitter in der Länge des Schreibvorganges erzeugt werden. Damit würden wir unserer Anforderung Nr. 2 widersprechen. Jedes Semaphor auf der Systemebene birgt die Gefahr das Zeitverhalten der Interruptebene zu verletzen.

    Es ergibt sich also eine weitere Anforderung:

    7. Anforderung an die Architektur: Das Schreiben der Daten auf der Systemebene darf keine zeitlichen Auswirkungen auf der Interrupt Ebene haben.

    Nun steht in obigen nichtfunktionalen Anforderungen, dass die größte Anzahl der Änderungen auf der Systemebene zu erwarten sind und diese effizient durchzuführen sind. Weiterhin gibt die 5. Anforderung vor, dass von der Interruptebene auf Basis von Ereignissen in die Systemebene kommuniziert werden, soll. Dafür muss die Adresse des Empfängers auf der Systemebene bekannt sein. Ändert sich diese, z.B. in einer neuen Variante, dann folgert dieses auch eine Änderung im Code der Interruptebene, was einer leichten Änderbarkeit der Systemebene entgegensteht.

    Hier gibt es den Architektur Pattern Publisher Subscriber, der es ermöglicht, dass der Sender von Daten den Empfänger nicht explizit kennen muss, woraus sich die folgende Anforderung ergibt.

    8. Anforderung an die Architektur: Sender auf der Interruptebene müssen die Adressen der Empfänger nicht kennen.

    Im folgenden möchte ich nun eine Architektur und ihre Muster vorstellen, die obigen Anforderungen entspricht.

    Der Architektur Entwurf

    In der folgenden Abbildung Nr. 5 ist ein Architektur-Entwurf mit zwei Ebenen dargestellt. Die obere Systemebene folgt den Anforderungen entsprechend dem zeitdiskreten Paradigma mit ereignisorientiertem Scheduling und Ereignissen zur Kommunikation zwischen Nebenläufigkeiten und zu anderen Ebenen. Auf dieser Ebene wird das Verhalten auf Basis von Zustandsautomaten modelliert.

    Die untere Interruptebene folgt den Anforderungen entsprechend dem zeitkontinuierlichen Paradigma. Auf Basis eines oder mehrerer Timer-Interrupts wird ein zeitgetriebenes Scheduling organisiert. Zur Kommunikation zwischen Nebenläufigkeiten und in andere Ebenen werden Signale verwendet.

    Auf Grund des zeitkontinuierlichen Paradigma wird das Verhalten der Nebenläufigkeiten NICHT auf Basis von Zustandsmaschinen, sondern ausschließlich ablauforientiert in C programmiert oder auf Basis von Aktivitätsdiagrammen oder Flowcharts modelliert.

    Nun fehlen uns noch die 7. und 8. Anforderung an die Architektur. Sie wirken sich auf die Kommunikations-Schnittstelle zwischen der System- und Interruptebene aus. Wie genau die Transformation der Kommunikation von Ereignissen zu Signalen und umgekehrt aussehen kann, vor allem in Form einer losen Kopplung, um den Architektur-Anforderungen 7 und 8 gerecht zu werden, werden wir im folgenden genauer betrachten.

    Transformation der Kommunikation und lose Kopplung

    Die Transformation der Ereignisse zu Signalen muss auf Basis von loser Kopplung auf der Zeitebene geschehen. Da die Systemebene keine Jitter auf der Interruptebene erzeugen soll. Das wird durch zwei Datenbereiche ermöglicht. Einer steht zum Schreiben von neuen Daten bereit. Erst wenn der Schreibvorgang abgeschlossen ist und die Daten gültig sind wird mit einem Pointer der Zugriff umgeschaltet. Dieser Vorgang kann atomar in einem CPU Zyklus durchgeführt werden und kommt ohne Interrupt-Sperren aus.

    Die Transformation der Signale in Ereignisse auf Basis von loser Kopplung auf der Datenebene.

    Um der Forderung der einfachen Änderbarkeit und Erweiterbarkeit der Systemebene gerecht zu werden benötigen wir eine lose Kopplung auf der Systemebene.

    Hierfür bietet sich die Anwendung des Publisher Supscriber Pattern an.

    In nebenstehender Abbildung Nr. 7 sehen wir eine grafische Darstellung. Lieferanten von Daten können bei einem Broker bekanntgeben, welche Daten sie liefern. Auf der anderen Seite können sich Konsumenten auf diese Daten beim Broker abonnieren. (Subscriben).

    Der Sender (Systemebene) muss also nicht die Adressen der Empfänger kennen. Er liefert die Daten an den Broker, und dieser versendet die Daten an die Konsumenten. (siehe auch Techletter 1 + 2)

    Architektur Implementation

    Die reale Implementation solch einer Architektur, zum Beispiel auf Basis eines UML Modells mit eingebundenen MATLAB Regler, finden Sie in der Techletter Nr. 2 beschrieben. Passend dazu liegt auf der Homepage von Willert Software Tools ein Rhapsody-Modell und in Kürze hoffentlich auch ein Enterprise Architekt-Modell.

     

    Autor:

    Andreas Willert
    Haben Sie noch Fragen oder Anregungen zum Thema? Dann freue ich mich über eine E-Mail: awillert@willert.de

    Herausgeber:

    WILLERT SOFTWARE TOOLS GMBH
    Hannoversche Straße 21
    31675 Bückeburg
    E-Mail: info@willert.de
    Tel.: +49 5722 9678 - 60

    Alle ESE-Reports im Überblick

    Aktuelles Know-how und neueste Entwicklungen und Trends rund um das Thema Emedded Software Engineering

    > zu den ESE-Reports

    Hinweis: Unsere Webseite nutzt Cookies. Wenn Sie fortfahren, nehmen wir an, dass wir Ihre Erlaubnis haben Cookies zu setzen. Informationen zum Einsatz von Cookies sowie unsere Datenschutzbestimmungen finden Sie in unserer Datenschutzerklärung und über unser Impressum.