DE | EN | CN

ESE Block 2 Grundlagen UML und SysML

Moderne Mikrocontroller verfügen in einem Chip über mehr Leistungsfähigkeit als die ersten Personalcomputer. Das macht den Einsatz moderner Programmiersprachen wie C++ möglich. Damit kann die Softwarequalität und die Entwicklungsgeschwindigkeit signifikant verbessert werden. Bei den PC-Systemen haben sich schon lange objektorientierte Programmiersprachen durchgesetzt. Das zeigt sich auch zunehmend bei Mikrocontrollern.

Für viele ist Objektorientierung als Paradigma der Softwareentwicklung schwer fassbar. Selbst wenn man schon eine objektorientierte Programmiersprache wie C++, JAVA oder C# anwenden kann bedeutet es nicht zwangsläufig, dass aktiv objektorientierte Konzepte systematisch angewendet werden.

Für den Anfang soll das wichtigste Konzept der Objektorientierung beschrieben werden. In der Literatur wird dies als Abstraktion bezeichnet. Das klingt komplizierter als es ist. Wir können dieses Konzept in einfache Sprache übersetzen: „Wir geben den Dingen Namen.“

Das bedeutet, dass wir als Menschen über Dinge kommunizieren und auch über Dinge nachdenken indem wir ihnen einen Begriff zuordnen. Das ist essentiell für unsere Fähigkeit sich einer Sprache zu bedienen. Das ist für uns gar nicht schwierig. Wir machen das rund um die Uhr.

In den UML Modellen die wir erstellen werden drückt sich die „Namensgebung“ dadurch aus, dass wir Bausteine die wir programmieren wollen wie folgt darstellen.

Die Dinge über die wir sprechen und nachdenken stehen miteinander in Beziehung. Das zu berücksichtigen gehört ebenfalls zu den objektorientierten Konzepten. In der Sprache finden wir die Beziehungen zwischen den Dingen als Verben wieder (Subjekt-Prädikat-Objekt). Die LED ist verbunden mit dem Controller. Das können wir dann in der UML auch darstellen.

Eine sehr wichtige Art von Beziehung die wir in der Objektorientierung berücksichtigen ist die, dass etwas zu einer bestimmten Gruppe gehören kann. Der Controller den wir in in diesem Kurs programmieren werden gehört zur STM32 Familie. Mit der UML lernen wir diesen Sachverhalt abstrakt zu modellieren.

Zusammenfassung:

  • Objektorientierung bedeutet zuerst den Dingen sinnvolle Namen geben (Abstraktion, Klasse)
  • Dinge sind mit anderen Dingen verbunden
    • Dinge kennen/benutzen sich (Assoziation, Dependency)
    • Dinge bestehen aus anderen Dingen (Aggregation, Komposition)
  • Dinge gehören zu Gruppen (Abstraktion, Generalisierung, Spezialisierung, Realisierung, Wiederverwendung)

Die UML hat sich zu einer etablierten Darstellungstechnik entwickelt die besonders für die Modellierung objektorientierter Software geeignet ist. Mit dem internationalen Standard ISO 19505 ist die UML weltweit verbindlich geregelt. Für die Anwendung der UML reichen am Anfang schon wenige Diagramme und ein überschaubarer Symbolvorrat aus.

Wie der Darstellung zu entnehmen ist, umfasst die UML eine Reihe verschiedener Diagrammtypen die streng danach geordnet sind, ob Strukturen oder Verhalten visualisiert wird. Es gibt in der UML keine Darstellungstechnik die Struktur und Verhalten gleichzeitig umfasst.

Das Anwendungsfalldiagramm zeigt das zu entwickelnde System aus der Perspektive des Anwenders. Die UML und die SysML bieten diese Darstellungsform um zu klären WER macht WAS WOMIT. Es eignet sich bei der Entwicklung besonders zur Visualisierung der Hauptanforderungen oder bei der Dokumentation für die Darstellung der Hauptfunktionen eines Systems.

  • das WER ist Anwender, dieser wird als Strichmännchen dargestellt
  • ist der Benutzer des Systems ein anderes externes System dann wird dieses als Würfel dargestellt
  • das WOMIT ist das beschriebene System selbst
  • um darzustellen was zum System gehört und was außerhalb des Systems liegt sollte die Systemgrenze als Rahmen dargestellt werden
  • der Anwendungsfall ist das WAS, er ist eine Leistung die das System für einen Anwender oder ein anderes System erbringt
  • der Anwender steht mit dem Anwendungsfall den er benutzt in Beziehung, diese Beziehungen repräsentiert eine Interaktion des Anwenders mit dem System und sollte daher ohne eine bestimmte Richtung gezeichnet werden
  • Anwendungsfälle können sich gegenseitig aufrufen, diese Aufrufe werden gestrichelt dargestellt.

In diesem Kurs benutzen wir das Anwendungsfalldiagramm zur Visualisierung der Hauptanforderungen an zu erarbeitende Lösungen. Dabei werden die Darstellungen Schritt für Schritt komplexer.

Aktivitätsdiagramme nehmen eine starke Anlehnung an die lange bekannten und weit verbreiteten Flussdiagramme. Solche finden sich sogar in manchen Benutzeranleitungen. Sie sind selbsterklärend und leicht verständlich. Das rechst gezeigte Aktivitätsdiagramm ist die Verfeinerung des Anwendungsfalls: „Anwender ruft mit dem Smartphone jemanden an“. Dabei repräsentiert der Anwendungsfall die Hauptanforderung an das Smartphone damit telefonieren zu können. Das Aktivitätsdiagramm beschreibt näher wie das funktioniert.

  • Anwendungsfall = Hauptanforderung
  • Aktivitätsdiagramm = funktionale Anforderungen

Aus diesem Aktivitätsdiagramm kann man die textuellen Testanweisungen für das System automatisch als sogenannte Testfälle bzw. Testszenarien generieren.

Scenario: user make calls - path 1

1. / Start
2. user / switches on the smartphone
3. smartphone / booting
4. smartphone / asks for the PIN
5. user / enters the PIN
6. / PIN
7. smartphone / checks the pin
8. smartphone [PIN is wrong] / shows an error message
9. user / enters the PIN
10. / PIN
11. smartphone / checks the pin
12. smartphone [PIN OK] / shows the start screen
13. user / click the phone icon
14. smartphone / shows the numeric keypad
15. user / dials the phone number
16. smartphone / establishes the connection
17. user / speaks to the called party
18. user / hangs up
19. smartphone / closes the connection
20. / End

Das gezeigte Aktivitätsdiagramm besteht aus folgenden Darstellungselementen:

  • einzelne Aktionen = Rechtecke mit abgerundeten Ecken
  • Beginn des Ablaufes = schwarzer Punkt
  • Ende des Ablaufes = schwarzer Punkt im Kreis
  • Entscheidung = Raute mit zwei Ausgängen
  • Partition (Verantwortliche für Aktionen) = Rahmen um die Aktionen
  • Steuerfluss = Verbindungen mit Pfeil für die Richtung
  • Datenelement / Datenfluss = Rechteck

Klassendiagramme sind die wichtigsten UML Diagramme. Diese sind die eigentlichen Baupläne der Software. Anwendungsfalldiagramme und Aktivitätsdiagramme sind bis hier lediglich dafür da, dass der Softwareentwickler über ausreichend Informationen verfügt die Software zu konstruieren und zu realisieren. Wir benutzen das Klassendiagramm nicht nur für die Konstruktion sondern auch für die Realisierung. Man kann damit nicht nur die Struktur der Software darstellen sondern auch den Quellcode aus diesem Diagramm generieren.

Das wichtigste Element im Klassendiagramm ist die Klasse. Klasse können wir mit Systembaustein übersetzen. Alle Dinge aus denen ein eingebettetes System besteht sind potentielle Klassen. Das können Sensoren, Aktuatoren, Taster, LEDs, Displays andere Controller aber auch interne Bausteine wie Timer sein. Jeder Baustein wird durch eine Klasse (Rechteck) in der Konstruktionszeichnung repräsentiert. Jeder Baustein kann Eigenschaften (Attribute) und Verhalten (Operationen) haben. Diese werden im UML Klassendiagramm als Listen innerhalb des Klassensymbols angezeigt. Klassen sind dem Wesen nach Typen. Der Programmierer muss von den Klassen Instanzen (vgl. Variablen) anlegen um diese zu benutzen. Da in eingebetteten Systemen die verwendetet Hardware oft genau nur einmal als Instanz benötigt wird spielt in der Perspektive des Klassenentwurfs die Unterscheidung zwischen Klasse und Objekt bzw. Typ und Instanz eine untergeordnete Rolle. Das wird erst wichtig wenn C++ Code geschrieben werden muss um die gewünschte Logik zu realisieren.

  • Bausteine = Klassen mit
    • Eigenschaften = Attribute
    • Verhalten = Operationen
  • Objekt = Instanz einer Klasse

Bei den Basiskonzepten der Objektorientierung haben wir bereits kennengelernt, dass die Beziehungen zwischen den Systembausteinen für einen objektorientierten Entwurf der Software eines eingebetteten Systems von großer Bedeutung sind. Was sich kompliziert anhört ist in der Praxis einfacher als gedacht. Man kann am Anfang die Entscheidung welche der verschiedenen UML Beziehungstypen zwischen Klassen benutzt werden soll auf lediglich zwei begrenzen. Wenn man diese Entscheidung in einfache Sprache übersetzt muss der Entwickler sich beim modellieren einer Beziehung zwischen zwei Klassen lediglich fragen:

  1. ist Klasse A eine Klasse B oder
  2. hat Klasse A eine Klasse B?

Beispiel 1:

  1. ist der Controller ein STM32 oder
  2. hat der Controller einen STM32?
  • die Antwort sollte ziemlich klar für „ist ein“ ausfallen

Beispiel 2:

  1. ist der Controller eine LED oder
  2. hat der Controller eine LED?
  • die Antwort sollte in diesem Fall deutlich zu „hat“ tendieren

Damit können wir am Anfang die benötigten Beziehungstypen auf folgende begrenzen:

  • Generalisierung / Realisierung = „ist ein“ dicker nicht ausgemalter Pfeil mit durchgezogener oder gestrichelter Linie
  • Aggregation = hat = schmaler Pfeil mit Raute am Anfang

Der folgende einfache Klassenentwurf zeigt die Anwendung des Beschriebenen:

In einfache Sprache übersetzt ist in diesem Klassenmodell folgendes zu lesen:

Es gibt die Bausteine SMT32, Controller, Button und LED.
Der Controller ist ein STM32.
Der Controller hat einen Button.
Der Controller hat eine LED.
Der Controller kann gestartet werden (start).
Der Controller kann laufen (run).
Der Controller kann alle 10 Millisekunden etwas tun (onTimer10ms).
Der Button kann gedrückt werden (isPressed).
Die LED kann eingeschaltet werden (on).
Die LED kann ausgeschaltet werden (off).
Die LED kann umgeschaltet werden (toggle).

Der Codegenerator liefert für die Klasse LED auf Knopfdruck folgenden Code für die Klassendeklaration in C++:

class LED
{
   public: LED();
   public: ~LED();
   public: void on();
   public: void off();
   public: void toggle();  
};

Sequenzdiagramme zeigen genauso wie Aktivitätsdiagramme WIE etwas im System abläuft. Der wichtigste Unterschied neben der Art und Weise der Darstellung ist, dass im Sequenzdiagramm schon konkrete Nachrichten modelliert werden. Nachrichten sind in letzter Konsequenz Aufrufe von Operationen. Das bedeutet, dass Sequenzdiagramme sehr viel konkreter sind und implementationsnahe. Aktivitätsdiagramme können von der konkreten Implementation in C++ oder einer andern objektorientierten Programmiersprache deutlich abstrahieren. Sequenzdiagramme sind ihrem Wesen nach viel näher an der Codierung. Das folgende Beispiel zeigt die direkte Übersetzung zwischen C++ Quellcode und UML Sequenzdiagramm in diesem Fall durch einen Generator automatisch erzeugt.

Controller::onEvent100ms()
{
  if (led.getState())
  {
	led.off();
  }
  else
  {
	if (button.isPressed())
	{
		led.on();
	}
  }
}

In diesem Kurs benutzen wir Sequenzdiagramme zur Dokumentation ausgewählter Codefragmente. Die Diagramme werden durch einen Generator automatisch erzeugt und können in Dokumentationen anstelle des Quellcodes verwendet werden.

Weder der Quellcode noch das Sequenzdiagramm zeigen auf den ersten Blick was da programmiert wurde. Das bedeutet, dass man sich im Kopf erst mal zurechtlegen muss was da alle 100 Millisekunden passiert. Die Logik ist Ereignisgetrieben und an den Zuständen AN / AUS orientiert. Die folgende Darstellung zeigt genau den selben Algorithmus als den Übergang zwischen den Zuständen AN und AUS.

Dieses Zustandsdiagramm zeigt wesentlich deutlicher dass getrieben durch das 100-Millisekunden-Ereignis die LED bei gedrückter Taste zwischen den Zuständen AN und AUS wechselt also blinkt. In diesem Kurs nutzen wir das Zustandsdiagramm auch zur Programmierung. Aus Zustandsdiagrammen kann man wie aus Klassendiagrammen Quellcode generieren. Viele Aufgabenstellungen für eingebettete Systeme sind Ereignis- und Zustandsorientiert. Es lohnt sich Programmelogik aus sauber modellierten Zustandsmodellen zu generieren.

Wichtiges zur SysML

In der Einführung wurde bereits dargelegt, dass moderne Systeme fachübergreifend verstanden werden müssen. Es gab aber lange Zeit keine fachübergreifende Modellierungssprache. Jede Fachdomäne kennt zwar hochentwickelte und standardisierte fachspezifische Modellierungssprachen aber die können auch nur Fachleute wirklich verstehen. Zur interdisziplinären Kommunikation sind die domänenspezifischen Modellierungssprachen nicht geeignet. Die SysML ist eine Angebot diese Lücke zu schließen. Als allgemeine Modellierungssprache für Systeme abstrahiert die SysML von domänenspezifischen Symbolen der Elektrotechnik, Mechanik, Hydraulik, Pneumatik, Elektronik und Software. Zwar ist der Ursprung der SysML in der UML zu finden und viele Elemente entsprechen der UML aber der Fokus der SysML liegt nicht bei der Objektorientierung und bei Software sondern bietet Modellierungsmöglichkeiten für beliebige Arten von Systemen an. Ein nicht standardisiertes Mittel der interdisziplinären Darstellung von Systemzusammenhängen bildeten sogenannte Blockdiagramme. Diese wurde nach gut Dünken erstellt und verstanden oder auch nicht verstanden. Hier setzt die SysML an. Der Block als Grundelement der Modellierung, unabhängig ob es ein mechanischer, elektronischer, hydraulischer, pneumatischer oder ein Softwareblock ist wir standardisiert genauso wie die Darstellung der Beziehungen zwischen solchen Blöcken. Systembaustein - Block - Klasse. Wer diesen Zusammenhang herstellt ist schon sehr nahe an den Intentionen der SysML. Die Überschneidungen in der Konzeption der UML und SysML zeigen sie deutlich in der ähnlichen Struktur von SysML und UML. Vergleichen Sie die Taxonomie der SysML mit der der UML.

In diesem Kurs werden ausgewählte SysML Darstellungen verwendet Hardwarekonfigurationen darzustellen und Hardware und Software in einem Kontext zu visualisieren. Dafür verwenden wir einfache Notationselemente von Block-Definitions- und internen Block-Diagrammen. Anwendungsfalldiagramme und Aktivitätsdiagramme sind gemeinsame Darstellungstechniken der UML und SysML.

Drei wichtige Elemente sollen hier schon kurz vorgestellt werden.

  • Block, der Block ist ein klar abgrenzbarer Systembaustein. Dabei ist unerheblich ob es sich um einen mechanischen, elektrischen, elektronischen oder um einen Softwarebaustein handelt.

  • Flow, ein Fluss zeigt an, dass etwas übertragen wird. Das können Stoffflüsse, Energieflüsse oder Informationsflüsse sein.

  • Komposition, diesen Beziehungstyp zwischen Blöcken benutzt man um zu zeigen das ein Block aus anderen Blöcken zusammengesetzt wird

  • Interface, eine Schnittstelle zeigt, dass Bausteine mit auf eine definierte Art und Weise miteinander verbunden werden können oder verbunden sind. Das Symbol ist zwar bewusst an die Stecker-Buchse-Notation der Elektrotechnik angelehnt aber in der SysML können das mechanische, elektrische, hydraulische, pneumatische Anschlüsse oder Softwareschnittstellen sein.

Als Beispiel für ein einfaches Block-Definitions-Diagramm soll der Grundaufbau eines Smartphones dokumentiert werden.

Weiter mit