en
de

Ein Blick in die Zühlke Embedded Platform – Teil 1

7 April 2016
| |
Lesezeit: 4 Minutes

Schneller am Markt: Ein Blick in die Zühlke Embedded Platform

Der Wunsch nach einer Beschleunigung von Entwicklungprojekten ist beinahe so alt wie die Software-Entwicklung selbst. Aus diesem Grund enthält die Geschichte des Software Engineering auch zahlreiche Beispiele für entsprechende Ansätze. Drei davon wollen wir im Folgenden kurz unter die Lupe nehmen, denn der historische Rückblick ist ausgesprochen lehrreich.

Programming Systems

Da wäre etwa der Traum von der automatischen Programmierung, der bereits Ende der 1960er Jahre geboren wurde. Die radikale Idee: Die Umsetzung von Anforderungen in lauffähige Software durch menschliche Entwickler ist häufig zeitaufwendig, fehlerbehaftet und schwierig zu kontrollieren — deshalb sollte man diese Aufgabe Maschinen überlassen. Das klang vielversprechend, ist aber außerhalb sehr spezieller Nischen niemals Wirklichkeit geworden.

Der Grund für das Scheitern dieser Utopie ist retrospektiv leicht zu benennen: Damit Anforderungen maschinell übersetzbar sind, müssen sie nicht nur maschinell lesbar, sondern auch mathematisch präzise und konkret und hochgradig detailliert spezifiziert sein. Damit hat man den mühseligen Prozess der Umsetzung von natürlichsprachigen Anforderungen in eine ausführbare Software aber nicht eingespart, sondern lediglich verlagert. Man braucht vielleicht nicht mehr zehn Entwickler, die Anforderungen lesen können, dafür aber zehn Requirements Engineers, die zum Beispiel logisch oder deklarativ programmieren können.

Model-Driven Software Development

Deutlich weniger radikal als die automatische Programmierung ist der Ansatz der modellgetriebenen Software-Entwicklung. Hier lässt sich die Grundidee wie folgt zusammenfassen: Praktisch jede Software muss eine Aufgabe lösen, die mit statischen Strukturen und dynamischen Abläufen befasst ist — deshalb sollte man diese Strukturen und Abläufe nicht im Quelltext eines Software-Systems verstecken, sondern sie explizit und in einer dafür passenden Eingabesprache modellieren. Aus solchen Modellen können dann entsprechende Programmteile generiert werden — blitzschnell und ohne fehleranfällige manuelle Übersetzung –, die zusammen mit handgeschriebenen Teilen die Gesamtsoftware ergeben.

Heutzutage belegt die modellgetriebene Entwicklung verdientermaßen einen festen Platz in der Welt des Software Engineering. So ist es gerade bei eingebetteten Systemen gängige Praxis, eine Software in Komponenten zu zerlegen, wobei jede Komponente eine eigene Zustandsmaschine hat und Komponenten untereinander über Nachrichten kommunizieren, die wiederum Zustandsübergänge auslösen. Was läge da näher, als die Module sowie ihre Zustandsmaschinen und die dazugehörigen Nachrichten sauber und explizit zu modellieren?

Allerdings existiert auch für die modellgetriebene Entwicklung eine radikalere Schule — nämlich die, dass man alles modellieren und somit gleich die gesamte Software generieren sollte. Dieser Ansatz ist in der Praxis aber kaum durchzuhalten: Während sich High-Level-Aspekte, zum Beispiel fachliche Abläufe oder Grobzustände von Software-Komponenten, gut modellieren lassen, sind die oft grafischen Eingabesprachen einfach nicht ausdrucksstark genug, um andere Aspekte umzusetzen. Salopp gesagt: Kein Mensch schreibt ein board support package oder einen I2C-Treiber in Kästchen und Pfeilen.

Produktlinien und Plattformen

Eine dritte und besonders bodenständige Strömung besteht darin, einen sinnvollen Kompromiss zwischen zwei Extremen herzustellen: Einerseits sehen wir ein, dass es nicht möglich ist, eine Software zu schreiben, die alle zukünftigen Anforderungen automatisch umsetzen kann (denn das wäre wieder der Traum der automatischen Programmierung, siehe oben). Ebenso wissen wir, dass Architektur-Entscheidungen fast immer auch Trade-Off-Entscheidungen sind, bei denen Qualitätscharakteristiken in Konkurrenz stehen:

  • Wenn die Software besonders performant sein soll, kann sie nicht beliebig viel Funktionalität anbieten.
  • Wenn sie besonders sicher sein soll, senkt das zunächst ihre Verfügbarkeit.
  • Wenn sie gleichzeitig sicher und hochverfügbar sein soll, dann wird die Umsetzung teurer.

Die Liste ließe sich leicht fortsetzen. Wichtig ist aber die Erkenntnis, dass Trade-Off-Entscheidungen immer nur im Hinblick auf einen gegebenen Anforderungskontext getroffen werden können.

Andererseits möchten wir aber nicht in jedem Entwicklungsprojekt wieder bei Null anfangen. Der Schlüssel liegt darin, eine Menge von Produkten (z.B. Geräten) zu identifizieren, die einander so ähnlich sind, dass sie auf der Basis einer gemeinsamen Software-Plattform realisiert werden können.

Das Erstellen einer Software-Plattform ist immer eine Gratwanderung: Bei welchen Aspekte der Software dürfen wir annehmen, dass sie über alle Varianten hinweg identisch sind? An welchen Stellen müssen wir hingegen Flexibilität vorsehen, etwa durch Erweiterungspunkte in der Architektur? Wenn wir zu stark zur erstgenannten Seite neigen, dann erhalten wir am Ende eine Software, die doch wieder nur zu einem einzigen Produkt passt. Wenn wir uns hingegen zu stark zur letztgenannten Seite orientieren, dann bleibt am Ende nichts Konkretes übrig — wir erhalten eine Plattform, die nur ein hohles Gerüst darstellt, die praktisch überhaupt keine greifbare Funktionalität bietet und bei der deshalb jede konkrete Instanziierung ungefähr so aufwendig wäre wie eine Neuentwicklung.

Der Weg zur Embedded-Plattform

In der Geräteentwicklung ist time to market ein besonders wichtiger Faktor. Somit wäre eine Embedded-Plattform besonders wünschenswert: eine Software-Plattform, die Entwicklungsprojekte für Geräte-Software dadurch beschleunigt, dass typische Standard-Aufgaben durch Standard-Komponenten aus einem geeigneten Baukasten gelöst werden. Aber ist das angesichts der oben aufgeführten Herausforderungen überhaupt möglich?

Tatsache ist, dass eine erfolgreiche Embedded-Plattform nur dann denkbar ist, wenn wir die richtigen Lehren aus den oben aufgeführten Erwägungen ziehen. Einige besonders wichtige Erkenntnisse, die sich unmittelbar aufdrängen, sind die folgenden:

  • Es ist völlig aussichtlos, eine Plattform entwerfen zu wollen, die allen erdenklichen Embedded-Projekten gerecht wird. Dazu sind deren Anforderungen, auch hinsichtlich der gängigen Qualitätscharakteristiken, viel zu unterschiedlich. Stattdessen muss man sich auf eine bestimmte Art von Projekten beschränken, die einander in hinreichend vielen Aspekten ähnlich sind.
  • Damit die Plattform irgendeinen Wert hat, muss sie möglichst genau an den Stellen konkrete Festlegungen treffen, die mit solcherlei stabilen Aspekten korrelieren. An diesen festgezurrten Stellen sollte sie dann auch konkrete Funktionalität anbieten, die in jedem neuen Projekt/Produkt sofort anwendbar wird.
  • Damit die Plattform ihren Namen verdient, muss sie andererseits an allen anderen Stellen möglichst viele Freiheitsgrade bieten, damit hier spezifische Varianten für jedes neue Projekt/Produkt umsetzbar sind.
  • Eine besonders elegante Möglichkeit zur Abbildung der Variantenvielfalt besteht darin, die konkreten Unterschiede und Ausprägungen einer jeden Variante modellbasiert spezifizierbar zu gestalten, z.B. mit Hilfe einer domänenspezifischen Sprache (DSL).

Soweit die allgemeinen Betrachtungen. Im zweiten Teil dieses Blog-Posts wollen wir auf konkrete Entscheidungen und den daraus resultierenden Aufbau der Zühlke Embedded Platform eingehen.

Kommentare (0)

×

Updates

Schreiben Sie sich jetzt ein für unsere zwei-wöchentlichen Updates per E-Mail.

This field is required
This field is required
This field is required

Mich interessiert

Select at least one category
You were signed up successfully.