Experience Embedded

Professionelle Schulungen, Beratung und Projektunterstützung

Automatische Multi-Core-Echtzeitvalidierung

Autoren: Felix Martin, Andreas Sailer, Michael Deubzer, Timing-Architects Embedded Systems GmbH, Jürgen Mottok, Ostbayerische Technische Hochschule

Beitrag - Embedded Software Engineering Kongress 2015

 

Der Trend zum Einsatz von Multi-Core Prozessoren, um den steigenden Leistungsanforderungen in eingebetteten Echtzeitsystemen gerecht zu werden, ist ebenso klar erkennbar wie die damit einhergehenden Herausforderungen hinsichtlich Zeitverhalten, Datenabhängigkeiten, Performanz und Zuverlässigkeit. Dieser Beitrag zeigt am Beispiel des freien Echtzeitbetriebssystems Erika Enterprise einen modellbasierten Ansatz, um die Einhaltung von sicherheitskritischen Echtzeitanforderungen mittels Tracing über den kompletten Entwicklungsprozess zu überwachen.

Einleitung

Ein modellbasierter Entwicklungsansatz erlaubt es bereits in der Planungsphase von Softwareprojekten, die Einhaltung von systemkritischen Anforderungen und Beschränkungen sicherzustellen [1]. Dazu wird ein Modell erstellt, welches das zeitliche Verhalten des Systems beschreibt.

Ein solches Modell besteht aus einem Hardware-, einem Betriebssystem- und einem Anwendungsteil. Der Hardwareteil beschreibt abstrakt das Verhalten des Prozessors, auf dem die finale Applikation durchgeführt werden soll. Der Betriebssystemteil modelliert das Verhalten von Serviceroutinen, wie zum Beipsiel die Anzahl an Instruktionen, die für eine Inter-Prozess-Aktivierung notwendig sind. Das Anwendungsmodell bildet die eigentliche Funktionalität der Applikation ab. Echtzeitkritische Softwaresysteme setzen sich aus verschiedenen Tasks zusammen, die wiederum anwendungsspezifische Funktionen, sogenannte Runnables, aufrufen.

Basierend auf einem solchen Modell können dann Anforderungen hinsichtlich des geforderten Zeitverhaltens definiert werden. Anforderungen können für alle Objekte, die im Anwendungsteil des Modells bestimmt sind, gestellt werden. Ein klassisches Beispiel hierfür ist die maximale Reaktionszeit einer Task, also die Zeit von ihrer Aktivierung bis zur Terminierung. Anforderungen an Datenabhängigkeiten können in Form von Data-Age-Constraints festgehalten werden [2]. Außerdem erlauben es sogenannte Ereignisketten, Zeitanforderungen für die Ausführung einer beliebigen Folge von Systemereignissen festzulegen.

Mit Hilfe einer diskreten Event-Simulation ist es nun möglich, das Laufzeitverhalten der finalen Applikation basierend auf einer solchen Systembeschreibung zu berechnen. Das Ergebnis ist ein sogenannter Trace - eine Abfolge von Ereignissen, die das Echtzeitverhalten des Systems wiedergeben. Dieser Trace kann nun ausgewertet und mit den definierten Anforderungen verglichen werden, was in Abbildung 1 (siehe PDF) dargestellt ist. So lassen sich Fehler im Systemdesign früh erkennen und beheben.

Auch wenn eine Applikation in die Entwicklungsphase geht, können die gestellten Anforderungen weiterhin validiert werden. Dazu ist es notwendig, das Verhalten der Software auf der Zielplattorm aufzuzeichnen - ein Prozess, der als Tracing oder Trace Recording bekannt ist. Der erste Teil dieses Beitrags zeigt die verschiedenen Möglichkeiten, um Traces von der Hardware aufzuzeichnen. Aufgezeichnete Tasks sind üblicherweise nicht in diesem Format, das für die Validierung der Echtzeitanforderungen geeignet ist. Aus diesem Grund erläutert der zweite Teil, welche Schritte zur Überführung in ein geeignetes Format notwendig sind. Abschließend wird beschrieben, wie diese Schrite unter Verwendung des Modells automatisiert werden können.

Tracing

Mittels Tracing kann das Verhalten von eingebetteten Systemen von der Hardware aufgezeichnet werden. Wie beim Simulieren ist das Result ein Trace, also eine Serie von Ereignissen, die verschiedene Vorkommnisse im System repräsentieren. Nach Ferrari [3] gibt es dafür drei prinzipielle Möglichkeiten: softwarebasiertes, hybrides und hardwarebasiertes Tracing.

Beim softwarebasierten Tracing wird ein spezieller Code zur Applikation hinzugefügt. Diese sogenannte Instrumentierung sorgt dafür, dass Ereignisse, die zur Analyse des Laufzeitverhaltens von Interesse sind, mit zugehörigem Zeitstempel im Speicher geloggt werden. Nach der Ausführung kann der Trace via Debugger oder serieller Schnittstelle ausgelesen werden. Dieser Ansatz verändert jedoch das Laufzeitverhalten der Applikation [4]. Darüber hinaus ist die maximal mögliche Tracedauer durch den verfügbaren Speicherplatz auf der Hardware limitiert.

Hybrides Tracing ist ebenso auf die Instrumentierung der Applikation angewiesen und verändert damit das Laufzeitverhalten. Im Gegensatz zum softwarebasierten Ansatz werden die aufgezeichneten Ereignisse direkt über eine dedizierte Schnittstelle zur weiteren Analyse versendet. Dies bedeutet, dass bei ausreichender Bandbreite die maximal mögliche Tracedauer nicht vom verfügbaren Speicherplatz limitiert wird.

Für hardwarebasiertes Tracing, auch bekannt unter dem Begriff "On-Chip-Trace", ist keine Softwareinstrumentierung notwendig. Stattdessen wird ein eigens dafür vorgesehener Bereich auf dem Prozessor dazu verwendet, die Befehlsabarbeitung und die Datentransfers der CPUs aufzuzeichnen. Diese Ereignisse können nach nutzerdefinierten Regeln gefiltert werden, um dann über ein spezielles Hardware-Trace-Interface vom Chip gesendet zu werden. Wird eine entsprechende Hochleistungsschnittstelle wie das AURORA-Interface verwendet, sind damit Aufzeichnungen von beliebiger Länge möglich [5].

Hardwarebasiertes Tracing ist die einzige Methode, die eine sinnvolle Validierung von Echtzeitanforderungen auf der Hardware erlaubt. Wie erwähnt wurde, verändern Ansätze, die auf Instrumentierung beruhen, das Laufzeitverhalten. Somit kann es besonders bei stark ausgelasteten Applikationen passieren, dass Anforderungen, die normalerweise erfüllt sind, aufgrund des zusätzlichen Rechenaufwands durch die Instrumentierung nicht mehr eingehalten werden. Darüber hinaus bedeutet es einen entwicklungstechnischen Mehraufwand, Instrumentierung zur Applikation hinzuzufügen und zu pflegen.

Grundsätzlich kann hardwarebasiertes Tracing drei Arten von Traces erzeugen: Instruction-, Daten- und Signal-Traces [6]. Instruction-Traces bestehen aus Befehlen, die von der CPU abgearbeitet wurden. Zusammen mit den Debuginformationen kann daraus der komplette Programmpfad der Applikation rekonstruiert werden. Daten-Traces enthalten Speicherzugriffe der CPUs, also beispielsweise Schreib- und Lesezugriffe auf Variablen der Applikation. Signal-Traces beinhalten Informationen über das Verhalten von Peripherals, wie zum Beispiel des Generic Timer Modules (GTM) der Infineon AURIX-Prozessor-Familie.

Das folgende Listing zeigt die textuelle Repräsentation eines Datatrace-Ereignisses, exportiert auf dem Tool TRACE32 der Lauterbach GmbH [7].

          0.0013952200,EE_th_status[0],"wr-data",00000003,0

Jedes Ereignis besteht aus fünf Feldern. Das erste entspricht dem Zeitstempel, zu dem das Ereignis aufgezeichnet wurde. Die Zeiteinheit ist Sekunden. Das zweite Feld repräsentiert die Variable, die von dem Datenzugriff betroffen ist. Das dritte Feld gibt an, ob ein Lese- oder ein Schreibzugriff stattgefunden hat. In diesem Fall handelt es sich um Letzteres ("write-data"). Das vierte Feld gibt den Wert an, der in die Variable geschrieben wurde. Das letzte Feld zeigt die ID des Prozessorkerns, auf dem das Ereignis stattgefunden hat.

Das folgende Listing zeigt die textuelle Repräsentation eines Instruction-Trace-Ereignisses, ebenso exportiert aus TRACE32.

          +1408860; R_2_1; fstart; 0

Das erste Feld entspricht wieder dem Zeitpunkt, zu dem das Ereignis aufgezeichnet wurde. Diesmal ist die Zeit in Nanosekunden angegeben. Das zweite Feld gibt den Namen des Softwareobjekts an, das von dem Event betroffen ist. Das dritte Feld gibt an, welche Aktion für das Softwareobjekt ausgeführt wird, in diesem Fall startet die Funktion R_2_1. Das letzte Feld repräsentiert wieder den Prozessorkern, auf dem das Ereignis stattgefunden hat.

Zuordnung

In der Einleitung wurde beschrieben, wie Anforderungen für Systemobjekte, wie Tasks und Signale definiert werden können. Im Gegensaz dazu beziehen sich Ereignisse, die beim hardwarebasierten Tracing aufgezeichnet werden, auf Softwareobjekte, also Entitäten, die auf Source-Code-Level definiert sind, so wie Variablen und Funktionen.

Um hardwarebasierte Traces für die Validierung von Echtzeitanforderungen zu verwenden, ist es also notwendig, die Traces von Softwarelevel auf Systemlevel zu transformieren, was in Abbildung 2 (siehe PDF) veranschaulicht wird. Dafür müssen die verschiedenen Systemereignisse den entsprechenden Ereignissen auf Softwarelevel zugeordnet werden. Zur Repräsentation des Traces auf Systemlevel ist außerdem ein geeignetes Format, wie das Best Trace Format (BTF) [8], notwendig.

Zur Verdeutlichung der Transformation soll das Data-Trace-Ereignis von oben verwendet werden. Dieses sagt aus, dass nach 1395220 Nanosekunden der Wert 3 in das erste Feld des Arrays EE_th_status auf den Kern mit der ID 0 geschrieben wurde. Diese Aussage kann für die Evaluierung von Echtzeitanforderungen jedoch nicht verwendet werden, da zur Interpretierung des Ereignisses auf Systemlevel zusätzliche Informationen notwendig sind. Das Erika Enterprise Betriebssystem speichert den Zustand jedes Tasks in einem Feld des EE_th_status Arrays. Das Feld mit dem Index 0 bezieht sich in diesem Beispiel auf den Task T_IMS_0. Abschließend kann die Aussage des Events umformuliert werden: nach 1395220 Nanosekunden wurde der Task T_IMS_0 auf dem Kern 0 terminiert.

Das OSEK Run Time Interface (ORTI) wurde spezifiziert, um die Zuordnung von Software- zu Systemobjekten für OSE-konforme Betriebssysteme zu erleichtern. Es ermöglicht beispielweise die Art und Weise, wie das Betriebssystem Taskzustände speichert, automatisch zu detektieren. Dass bedeutet, der Nutzer muss nicht zwingend wissen, dass EE_th_status dafür verwendet wird. Stattdessen kann diese Information aus der ORTI-Datei gelesen werden.

Jedoch stellt ORTI nicht zwingendermaßen Informationen für alle Systemobjekte, die für die Analyse des Echtzeitverhaltens von Systemen von Interesse sind, zur Verfügung. Beispielsweise sind Runnables und Signale nicht durch ORTI abgedeckt. In diesem Fall ist es erforderlich, diese Informationen über andere Wege bereitzustellen. Ansonsten ist eine Zuordnung und damit eine Transformation für bestimmte Objekte nicht möglich. Das Instruction-Trace-Ereignis aus dem Beispiel von oben repräsentiert den Start der Funktion R_2_1. Nur wenn zum Zeitpunkt der Transformation bekannt ist, dass diese Funktion auf Systemlevel einem Runnable enspricht, kann das korrekte Systemereignis erstellt werden.

Selbst wenn ein Objekttyp - so wie Tasks - von ORTI unterstützt werden, können nicht zwingend alle Ereignisse auf Systemlevel rekonstruiert werden. Beispielsweise definiert BTF für Tasks ein mtalimitexceeded Ereignis, das dann eintritt, wenn ein Task aktiviert wird, für den keine weitere Aktivierung erlaubt ist. Über das ORTI lasterror Attribut ist es möglich, diese Ereignisse zu erkennen, jedoch ist es nicht möglich herauszufinden, für welchen Task das Ereignis ausgelöst wurde. In diesem Fall sind zusätzliche Informationen über die Funktionsweise des Betriebssystems notwendig. Erika Enterprise liest die Variable EE_th_rnact, um festzustellen, ob eine weitere Taskaktivierung erlaubt ist. Falls nicht, wird direkt nach dem Lese-Ereignis der entsprechende Fehlercode in lasterror geschrieben. Ist dieses Verhalten bekannt, kann trotz fehlender ORTI-Unterstützung das Ereignis rekonstruiert werden.

Entsprechend dieser Beispiele können prinzipiell alle Ereignisse, die von BTF spezifiziet sind, von Software- auf Systemlevel transformiert werden. Je nachdem, welche Anforderungen validiert werden sollen, ist mehr oder weniger Detailwissen über die Funktionsweisen des Betriebssystems notwendig.

Automatisierung

Wie aus den vorherigen Sektionen hervorgeht, ist eine Anforderungsvalidierung via Tracing nicht trivial. Zuerst muss eine geeignete Trace-Technologie ausgewählt werden, anschließend müssen die erzeugten Traces richtig interpretiert werden, um eine Echtzeitanalyse zu ermöglichen. Ein modellbasierter Entwicklungsansatz kann bei beiden Aufgaben unterstützen.

Zur Aufzeichnung eines korrekten Traces ist die korrekte Konfiguration der Trace-Hardware notwendig. Diese ist einerseits vom Prozessor und andererseits vom verwendeten Betriebssystem abhängig. Das oben erwähnte Modell des Systems enthält Informationen über diese beiden Aspekte. Dies bedeutet, dass basierend auf dem Modell die korrekte Trace-Konfiguration automatisiert erstellt werden kann. Beispielsweise kann der korrekte Prozessortyp aus dem Hardwareteil und die korrekte Konfiguration des Daten-Traces aus dem Betriebssystemteil erstellt werden.

Darüber hinaus kann der Applikationscode selbst automatisch aus dem Modell generiert werden. Das bedeutet, sobald ein Modell erstellt ist, kann ein erster Prototyp der Applikation auf realer Hardware getestet werden. Funktionen, die noch nicht implementiert sind, werden dabei durch Funktionsstubs, die Laufzeit entsprechend der Konfiguration im Modell verbrauchen, ersetzt. So bald neue Funktionsteile implementiert sind, werden die entsprechenden Stubs ersetzt. Basierend auf dem Zeitverhalten der realen Funktionen kann das Modell iterativ verbessert werden. Dieses Vorgehen erlaubt einen permanenten Abgleich zwischen Modell und realer Applikation und damit einhergehend eine kontinuierliche Überwachung der Anforderungen.

Mit einem automatisch generierten Prototyp der Applikation und der entsprechenden Trace-Konfiguration, welche ebenso automatisiert generiert wurde, können Hardware-Traces vollständig automatisiert aufgezeichnet werden. Anschließend muss der Trace auf Systemlevel transformiert werden, um eine Zeitanalyse durchzuführen. Ein Teil der dafür notwendigen Informationen kann aus dem Modell extrahiert werden. Zum einen kann basierend auf dem Modell entschieden werden, welche Funktionen Runnables sind, zum anderen, welche Variablen Signale sind. Dementsprechend werden Ereignisse für alle Objekte, die für die Echtzeitanalyse von Bedeutung sind, erstellt.

Abschließend wird der erzeugte Trace evaluiert und mit den gestellten Anforderungen verglichen. Basierend auf den Ereignissen kann ein Report erstellt werden, der den momentaren Status der Applikation wiedergibt. Genügt das Zeitverhalten nicht den gestellten Anforderungen, kann dies anhand des Reports festgestellt und das Systemdesign verbessert werden. Nach der Verbesserung wird der Prozess erneut durchlaufen, bis das Systemverhalten den Anforderungen genügt. Abbildung 3 (siehe PDF) visualisiert dieses Vorgehen.

Zusammenfassung und Ausblick

Ein modellbasierter Entwicklungsansatz erlaubt es, eingebettete Multi-Core-Applikationen bereits in der Designphase hinsichtlich ihres Zeitverhaltens zu untersuchen. Dies ist möglich, ohne sich auf einen Prozessor oder ein Betriebssystem festzulegen. Dieser Beitrag zeigt, wie die Anforderungen, die in der Designphase gestellt und via Simulation validiert wurden, auch in der Implementierungsphase weiter überwacht werden können. Dazu ist es notwendig, das Systemverhalten über hardwarebasiertes Tracing aufzuzeichnen und den resultierenden Trace in ein geeignetes Format zu übersetzen. Basierend auf einem Modell können diese Schritte automatisiert durchgeführt werden.

Moderne Multi-Core Prozessoren unterstützen drei Arten von Tracing. Im Moment werden nur zwei Arten zur Echtzeitvalidierung genutzt: Daten-Tracing und Instruction-Tracing. Die Möglichkeit, periphere Hardware, wie Timer Units oder CAN Module, via Signal-Tracing zu tracen, könnte in Zukunft dazu genutzt werden, das Kollektivverhalten von mehreren Prozessoren zu überwachen. Das bedeutet, die einzelnen Prozessoren werden nicht isoliert voneinander betrachtet, sondern auch die Kommunikation zwischen den distinktiven Einheiten wird in die Analyse des Echtzeitverhaltens miteinbezogen.

 

Quellenverzeichnis

[1]

M. Deubzer, A. Stingl, E. Simsek, S. Krämer, J. Mottok, "Performante und zuverlässige Embedded-Multi-Core-Systeme", ESE Kongress, Sindelfingen, 2014.

[2]

M.-A. Peraldi-Frati, A. Goknil, J. DeAntoni, J. Nordlander, "A timing model for specifying multi clock automotive systems: The timing augmented description language v2", in Engineering of Complex Computer Systems (ICECCS), 2012 17th International Conference on Engineering of Complex Computer Systems, Paris, IEEE, 2012, pp. 230-239.

[3]

D. Ferrari, Computer systems performance evaluation, Prentice Hall, 1987.

[4]

J. Kraft, A. Wall, H. Kienle, "Trace recording for embedded systems: Lessons learned from five industrial projects", in Runtime Verification, Springer, 2015, pp. 315-329.

[5]

A. Martin, "Tracedaten auf die Festplatte streamen", ESE Kongress, Sindelfingen, 2013.

[6]

J. Braunes, "Die neue Trace-Welt jenseits von Code- und Daten-Trace", ESE Kongress, Sindelfingen, 2013.

[7]

Lauterbach GmbH, "TRACE32 - General Commands Reference Guide T (Accessed: 2015-10-19)", Höhenkirchen-Siegertsbrunn, 2015.

[8]

Timing Architects Embedded Systems GmbH, "BTF-Specification", AMALTHEA ITEA2 Project.

[9]

Timing-Architects Embedded Systems GmbH, "TA Tool Suite - TA Inspector", (Accessed: 2015-10-20), Regensburg, 2015.

 

Beitrag als PDF downloaden

 


Multicore - unsere Trainings & Coachings

Wollen Sie sich auf den aktuellen Stand der Technik bringen?

Dann informieren Sie sich hier zu Schulungen/ Seminaren/ Trainings/ Workshops und individuellen Coachings von MircoConsult zum Thema Multicore /Mikrocontroller.

 

Training & Coaching zu den weiteren Themen unseren Portfolios finden Sie hier.


Multicore - Fachwissen

Wertvolles Fachwissen zum Thema Multicore /Mikrocontroller steht hier für Sie zum kostenfreien Download bereit.

Zu den Fachinformationen

 
Fachwissen zu weiteren Themen unseren Portfolios finden Sie hier.