Modellgetriebene Softwareentwicklung für Embedded Systeme

Bei einigen Embedded-Herstellern ist modellgetriebene Softwareentwicklung (MDSE) ein zentraler Bestandteil ihrer Entwicklung. In zahlreichen Firmen ist der Begriff hingegen unbekannt oder wird mit überholten Techniken aus den 90ern assoziiert. Dies ist bedauerlich, denn MDSE eignet sich besonders für Geräte mit limitierten Ressourcen, um Komplexität beherrschbar zu machen und Entwicklungsproduktivität zu steigern.

Modellgetrieben3
MDSD

MDSE wird von einigen mit Computer-Aided Software Engineering (CASE) verwechselt. Der Kerngedanke bei CASE ist es, beliebigen Code aus UML-Modellen zu generieren. Bis auf einige Spezialfälle, bringt dieser Ansatz jedoch kaum Produktivitätsvorteile, da die Aufgaben zu komplex und UML zu ausdrucksschwach ist. Es macht mehr Sinn sich auf bestimmte Teilprobleme zu konzentrieren und in Richtung domänenspezifische Sprachen zu blicken.

MDSE hat seine Wurzeln in den frühen 2000er Jahren. Kerngedanke dabei ist es ein Modell als „Single Source of Truth“ zu verwenden und dieses dann mittels Generatoren in unterschiedliche Zieltechnologien abzubilden. Dadurch kann das für die Softwareentwicklung fundamentale Konzept „Don’t Repeat Yourself“ technologieübergreifend realisiert werden. Änderungen werden zentral am Modell durchgeführt und propagieren sich automatisch in alle abhängigen Teile.

MDSE ist gerade auch für Hersteller von Geräten mit Feldbusanbindung interessant. Die Schnittstellen zu solchen Geräten bestehen üblicherweise aus einer breiten öffentlichen Parameterstruktur, in die man Konfigurationsdaten schreiben und aus der man Telemetriewerte auslesen kann. Diese Parameterstruktur spiegelt sich an vielen Stellen auf und um das Gerät wieder:

  • die Parameter werden mit ID’s, Namen und Datentypen in der internen Datenbank des Geräts gehalten;
  • proprietäre Kommunikationsprotokolle benutzen die Parameter zur internen Kommunikation zwischen Modulen oder auf der M2M- bzw. Serviceschnittstelle;
  • in der technischen Dokumentation und im Benutzerhandbuch des Geräts werden die Parameter aufgeführt;
  • in der Konfiguration des Feldbusstacks in der Firmware werden bestimmte Parameter exponiert;
  • für die Gegenstelle wird eine Feldbusbeschreibungsdatei (DD) mit zur Firmware passender Parameterstruktur geliefert;
  • ein lokales Display (HMI) stellt die Werte bestimmter Parameter dar und
  • über ein webbasiertes Userinterface ist die vollständige Konfiguration des Geräts möglich.
Multifeldbus2

Noch interessanter wird es, wenn ein Gerät oder eine Gerätelinie mehrere unterschiedliche Feldbusse oder vergleichbare Kommunikationsstandards unterstützen muss. Wenn ein Parametername oder sein Datentyp sich ändert, müssen in diesem Fall sehr viele Artefakte angepasst werden. Diese Artefakte liegen zwangsweise in verschiedenen Formaten vor, da sie aus anderen Technologiebereichen stammen. Alle diese Artefakte automatisiert synchron zu halten, ist eine Musteraufgabe für MDSE.

Um von der wartungsintensiven und fehleranfälligen manuellen Pflege der gleichen Information an vielen Stellen zu einer vollautomatisierten Lösung zu kommen, sind folgende Schritte notwendig:

  1. Domänenanalyse und Modellierung: Finden eines geeigneten Metamodells anhand relevanter Gemeinsamkeiten aus der Domäne. Für Parameterstrukturen aus dem obigen Bespiel kann man sich an vorhandenen Typsystemen orientieren. Es existieren einige gute MDSE-Open-Source-Frameworks, die Modellierungssprachen und Werkzeuge zur Transformation bieten.
  2. Modellerstellung: Erstellung von konkreten Modellen für ein oder besser mehrere Geräte auf Basis des Metamodells. Beschreibung von Daten, Eigenschaften und Zuständen funktioniert gut. Beschreibung von Prozessen und Verhalten wird schnell sehr komplex.
  3. Transformation: Das Schreiben der Generatoren ist eine zentrale Herausforderung, denn in ihnen steckt viel Know-how über die Zieltechnologien. Für das obige Beispiel könnten die Generatoren u.a. C/C++-Code, PDF, GSD und TypeScript ausgeben.
  4. Einbettung: In den jeweiligen Zieltechnologien müssen die generierten mit den manuell geschriebenen Artefakten integriert werden. Da beide nicht nachträglich modifiziert werden sollen, braucht es definierte Schnittstellen zwischen ihnen. An dieser Stelle sollten auch Erweiterungspunkte definiert werden, so dass spezifische Logiken, die nicht modelliert wurden, technologiespezifisch hinzugefügt werden können.
  5. Build: Aufsetzen eines automatisierten Prozesses zur Synchronisation aller Artefakte. Wird üblicherweise in die CI/CD-Pipelines integriert.
  6. Modellevolution: Modell ändert sich mit neuen Anforderungen, Gerätevarianten oder Zieltechnologien. Gegebenenfalls müssen Generatoren angepasst oder neue entwickelt werden.
MDSD_und_Plattform

Auf der folgenden Abbildung kann man die Anwendung modellgetriebener Softwareentwicklung für eine Produktplattform sehen. Die Produktvarianten unterscheiden sich in ihrer Parameterstruktur. Die konkrete Firmware einer Produktvariante, wird zunächst in in drei Teile segmentiert:

  • generischer Code, der von der Parameterstruktur der Produkte unabhängig ist;
  • schematischer Code, der spezifisch für jede Parameterstruktur und doch ähnlich über alle Produkte ist und
  • individueller Code, der spezifisch für jede Parameterstruktur und jedes Produkt ist.

Im nächsten Schritt folgt die Trennung der Segmente und Anwendung der MDSE:

  • Der generische Code wird in eine separate Plattform-Komponente überführt, die keine Compile-Time-Abhängigkeit zu den anderen beiden Segmenten mehr hat.
  • Für die Parameterstruktur aller Produktvarianten werden Modelle erstellt und daraus ihr schematischer Code generiert. Der schematische Code enthält Erweiterungspunkte und definierte Schnittstellen zu individuellem Code.
  • Der individuelle Code erzeugt produktvariantenspezifische Funktionalität und fügt Plattform und Parameterstruktur zur Laufzeit zusammen.

Durch alleinige Modifikation des Modells, ist es nun möglich einen neuen Parameter in allen Produktvarianten hinzuzufügen, der in der Firmware, allen Protokollen und Feldbussen, in der Dokumentation und an den graphischen Benutzerschnittstellen auftaucht.

Gerade Embedded-Hersteller müssen häufig zahlreiche klassische und modernere Kommunikationsstandards in ihrer Firmware unterstützen. Es ist jedoch nicht möglich eine Vielzahl von Modulen vorzuhalten, bei Bedarf nachzuladen oder Informationen zur Laufzeit zu generieren. Vielmehr muss diese Konfigurationsvielfalt zur Compile-Zeit erschlagen und Artefakte offline in allen Varianten vorbereitet werden. Modellgetriebene Softwareentwicklung ist ein gutes Werkzeug und diese Komplexität beherrschbar zu machen und die Redundanz im Griff zu behalten.

TECHNISCHE EXZELLENZ UND GLEICHBLEIBEND HOHE QUALITÄT​

Sie suchen einen zuverlässigen Entwicklungspartner mit sowohl tiefem als auch breitem Embedded Know-how, der nicht nur Softwaretechnologien, sondern auch Ihre Domäne versteht? Starten Sie ihr nächstes Projekt mit awinia! 

*Die Bilder auf dieser Seite wurden mit Hilfe von künstlicher Intelligenz erstellt.