Der SystemTick in ARM C++

Den SysTick haben wir beim einfachen Programm bereits kennengelernt. Dieser stellt einen einfachen Zeitgeber für das Anwendungssystem dar. Standardmäßig ist der SysTick auf SystemCoreClock/100 konfiguriert. Damit verfügt unser System über ein vorgefertigtes 10 ms Ereignis.

Diese Übung wird wiederum eine einfache Verwendung der SysTickFunction zur Generierung zyklischer Ausgaben demonstrieren. Wir lassen die LEDs auf dem Board unterschiedlich blinken. Das folgende Blockbild verdeutlicht, welche Bausteine bei dieser Aufgabe eine Rolle spielen.

Die zwei LEDs auf dem XMC4500 Relax Kit sind immer noch fest mit den Pin1.0 und Pin1.1 verbunden. Der SystemTick soll so konfiguriert werden, dass dieses Ereignis alle 10 Millisekunden eintritt. Fassen wir die Aufgaben zusammen:

  1. Das SysTick-Ereignis auf 10 ms konfigurieren
  2. PORT1 BIT0 und BIT1 als Ausgang konfigurieren
  3. wenn das SysTick-Ereignis eintritt, die LEDs unterschiedlich blinken lassen

Falls Sie jetzt noch das Klassendiagramm geöffnet haben wählen Sie im Kontextmenü (rechte Maustaste) des Diagramms den Menüpunkt nach oben. Falls das Projekt nicht mehr geöffnet ist, öffnen Sie das SiSy UML-Projekt wieder. Legen Sie ein neues Klassendiagramm an und wählen Sie die Sprache ARM C++. Beachten Sie die Einstellungen für die Zielplattform XMC4500 Relax Kit. Beim Öffnen des Diagramms (rechte Maustaste, nach unten) laden Sie die Diagrammvorlage für eine PEC Applikation und fügen das Treiberpaket für den XMC4500 ein.

Die Aufgabe besteht darin die zwei LED's anzusteuern. Folgen wir der objektorientierten Sichtweise, sind die beiden LEDs Objekte und können über eine Klasse mit dem Namen Led abstrahiert werden. Die Klasse Led soll die spezifischen Merkmale (Struktur und Verhalten) von typischen LEDs auf der Anwenderebene abstrahieren. Also fragen wir uns was die zwei LEDs denn aus Anwendersicht so tun sollen. Diese können an oder aus sein, sie können ihren Zustand wechseln, also umschalten. Tun die LEDs das zyklisch, blinken sie.

Schauen wir uns noch mal kurz die Systemarchitektur des Framework an. Unsere Klasse Controller hat alle Eigenschaften des PecAppKernel und dieser wiederum alle Merkmale eines PecAppModul. Im folgenden eine vereinfachte Darstellung mit Controller, PecAppKernel und PecAppModul.

Die Klasse Controller überschreibt die virtuellen Operationen onStart und onWork des PecAppModul. Es ist zu erkennen, dass der PecAppKernel bereits über einen SysTick-Ereignishandler verfügt. Diesen könnten wir überschreiben, um das SysTick-Ereignis zu empfangen. Schauen wir uns vorher aber noch mal das folgende Sequenzdiagramm an.

Der SysTick wird demzufolge an den PecAppKernel und alle PecAppModule verteilt. Dabei werden aus dem SysTick-Ereignis die Ereignisse für 10 Millisekunden, 100 Millisekunden und 1 Sekunde generiert.

Der erste grobe Entwurf, den wir aus der Anwendersicht ableiten, sieht in etwa so aus:

Die Abstraktion der Klasse Led hat bereits jemand für uns geleistet. Wir finden diese als vorbereitete Klasse in der Bibliothek. Wir können diese, wie bereits erprobt, nutzen. Dazu muss die Led aus dem Navigator per Drag & Drop in das Klassendiagramm gezogen werden.

Wenn wir die Led hereingezogen haben, verbinden wir diese mit der Anwendung. Ziehen Sie von hier aus per Drag & Drop eine Verbindung von der Klasse Controller zur Klasse Led. Wählen sie als Verbindungstyp die Aggregation und als Rollenbezeichner +led mit der Multiplizität 2. Die Applikation hat jetzt zwei Led.

Wir sollten uns nicht direkt an den SysTick hängen, sondern an die aus demselben generierten Ereignisse für 100 Millisekunden und 1 Sekunde. Dazu überschreiben wir die Ereignishandler wie folgt:

  1. Ziehen Sie eine Operation aus der Objektbibliothek in die Klasse Controller.
  2. Daraufhin öffnet sich der Dialog zum Einfügen von Operationen. Wählen Sie die Schaltfläche Weiter.
  3. Findet das Werkzeug Operationen, die sich überschreiben lassen, bietet es diese zur Auswahl an.
  4. Wählen sie die Operation onEvent100ms.
  5. Bestätigen Sie Ihre Auswahl.

Dieses Vorgehen wird als Überschreiben bezeichnet.

Wiederholen Sie diesen Vorgang für das Ereignis onEvent1s. Danach sollte der Entwurf unserer Anwendung folgenden Entwicklungsstand erreicht haben:

Den Entwurf unterziehen wir einem kurzen Review. Dann können wir mit der Realisierung beginnen. Zuerst initialisieren wir die Geräte, sprich die LEDs. Diese sind mit GPIO-Pins 1.0 und 1.1 verbunden. Die Initialisierung soll beim Start der Applikation erfolgen.

Controller::onStart:

led[0].config(PORT1,BIT0);
led[1].config(PORT1,BIT1);
led[0].on();
led[1].on();

Bei 100 Millisekunden, also 10 mal Umschalten pro Sekunde, sollte sich das Blinken gut wahrnehmen lassen.

Controller::onEvent100ms:

led[1].toggle();

Einmal pro Sekunde umschalten sind dann gemütliche 0,5 Hertz.

Controller::onEvent1s:

// led[0].toggle();

Erstellen, Übersetzen und Übertragen Sie das Programm. Die LEDs blinken jetzt in unterschiedlicher Geschwindigkeit.

Videozusammenfassung

Erlernte und gefestigte Arbeitsschritte:

  1. Klassendiagramm anlegen und öffnen
  2. Diagrammvorlage für ARM C++ Applikation auswählen und laden
  3. Navigator auf UML Pakete umschalten
  4. gewünschte Klasse Led im Navigator suchen und ins Diagramm ziehen
  5. Klassen aggregieren
  6. Operationen anlegen und in eine Klasse einfügen
  7. Operationen einer Basisklasse überschreiben
  8. den nötigen Quellcode in den Operationen erstellen
  9. Erstellen und Brennen einer ARM Applikation im Klassendiagramm

Und hier diesen Abschnitt wiederum als Videozusammenfassung.

Übung

Erweitern Sie zur Übung die Anwendung derart, dass nur, wenn eine Taste gedrückt ist, die LEDs blinken.

Nächstes Thema