Zephyr-RTOS-Benchmark Wie misst man das Timing von Zephyr?

Von Diplom-Ingenieur (FH) Andreas Klinger 5 min Lesedauer

Anbieter zum Thema

Zephyr ist bekanntlich ein Realtime-Operating-System (RTOS). Das heißt aber noch lange nicht, dass alles, was auf dem System läuft, auch echtzeitfähig ist. Um dies zu ermitteln, kann man das System vermessen.

Bild 1: Funktionsweise und zeitlicher Verlauf der Messung mit zyclictest.(Bild:  Andreas Klinger)
Bild 1: Funktionsweise und zeitlicher Verlauf der Messung mit zyclictest.
(Bild: Andreas Klinger)

In Zephyr existiert eine ganze Reihe von Benchmarks, welche für die Messung von betriebssysteminternen Vorgängen genutzt werden können. Diese befinden sich im Zephyr-Repository im Verzeichnis tests/benchmark. Beispielsweise kann die Kontext-Switch-Zeit zwischen Threads oder zwischen Interrupts und Threads gemessen werden. Ebenso können die vielen Interprozesskommunikationsmöglichkeiten von Zephyr vermessen werden. Beispielsweise wie lange es dauert, eine Message über eine FIFO zu versenden und dergleichen mehr. Viele dieser Messungen befinden sich in den Applikationen app_kernel und latency_measure.

All diese Messungen wurden als separate Applikationen implementiert. Dies bedeutet, dass auf dem zu messenden System lediglich die Benchmark-Applikation läuft. Die eigentliche Applikation des Zielsystems läuft nicht und es wäre aufwendig diese Messungen in das Zielsystem zu integrieren.

Die Konsequenz ist, dass mit dieser Methode nur der Gutfall im ansonsten unbelasteten System gemessen werden kann. Eine Messung unter Last und unter Nutzung der Ressourcen ist nicht möglich.

Zyclictest

Inspiriert durch das von Linux her bekannte Tool cyclictest steht der Name für "Zephyr-Cyclictest". Ziel ist die Messung des Echtzeitverhaltens unter realen Bedingungen, also während die Applikation läuft. Da es bei Zephyr keine beliebig durch die Shell startbare Applikationen wie bei Linux gibt, würde die Implementierung als Applikation bedeuten, dass man Zyclictest laufen lassen kann, aber keine Applikation, welche Last geniert und Resourcen nutzt, und dann wäre dies unberücksichtigt. Daher wurde Zyclictest in die Zephyr-Shell integriert. So ist sie jederzeit startbar, wenn die eigentliche Applikation gerade läuft. Der Test findet im realen Umfeld statt und der Test kann in jedem Entwicklungsschritt einfach durchgeführt werden.

Messmethode

Wie wird nun gemessen? Zyclictest startet einen zyklischen Timer, welcher Interrupts generiert. Der Zeitpunkt, zu dem der Interrupt programmiert wird, ist bekannt. Außerdem wird ein Thread gestartet, welcher sich auf den Timer einsynchronisiert. Wenn nun der Timer abläuft, wird im Timer-Handler, der ja im Interrupt-Kontext ausgeführt wird, die Zeit ermittelt und davon die programmierte Zeit abgezogen. Dies ergibt die Latenz des Hardware-Interrupts. Diese Latenzzeit beinhaltet die Zeit, welche aufgrund von Interrupt-Sperren und auch Interrupts-Bursts entstanden ist.

In der Timerbehandlung von Zephyr wird außerdem der auf den Timer wartende Thread aufgeweckt. Dieser ist nun rechenbereit. Wenn der Thread Rechenzeit bekommt, fällt dieser aus der Synchronisierungsfunktion raus und ermittelt ebenso die Zeit und zieht die geplante Zeit ab. Dies ergibt die Latenz des Threads. Diese Zeit beinhaltet zusätzlich die Scheduling-Latenz des Threads, Zeiten, in denen höher priorisierte oder auch kooperative Threads und Meta-IRQs gerechnet haben. Bild 1 erläutert die Funktionsweise und den zeitlichen Verlauf der Messung.

Messdurchführung

Die Applikation wird ganz normal ausgeführt und getestet. Parallel dazu wird Zyclictest gestartet. Dabei ist darauf zu achten, dass Zyclictest mindestens eine Prioritätsstufe höher gestartet wird als der zu untersuchende Applikationsthread. Die Zykluszeit sollte zunächst auf das Doppelte der zu erwartenden Worst-Case-Latenz des Threads eingestellt werden. Sollte sich herausstellen, dass es während der Messung zu Overflows kommt, dann ist die Messung unbrauchbar. Ein Overflow passiert, wenn die Periode des zyklischen Timers kleiner als die Worst-Case-Latenz des Threads ist. Dann wird nämlich schon wieder der nächste Timer ausgelöst, noch bevor der letzte abgearbeitet ist. In diesem Fall ist die Zykluszeit entsprechend anzupassen, sodass es zu keinen Overflows mehr kommt.

Stellt man fest, dass es keine maximale Latenz gibt, sondern die Latenz vielmehr eine Funktion der Last ist, dann verhält sich der gemessene Thread nicht deterministisch, ist also nicht echtzeitfähig.

Jetzt Newsletter abonnieren

Verpassen Sie nicht unsere besten Inhalte

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung. Die Einwilligungserklärung bezieht sich u. a. auf die Zusendung von redaktionellen Newslettern per E-Mail und auf den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern (z. B. LinkedIn, Google, Meta).

Aufklappen für Details zu Ihrer Einwilligung

Innovate Your Software – for a Smarter Future

Deutschlands Leitkongress der Embedded-Softwarebranche

Embedded Software Engineering Kongress

Das Programm des ESE Kongress umfasst 96 Vorträge, 21 Seminare und 3 Keynotes. Seien Sie dabei, wenn sich die Embedded-Software-Community trifft, und nutzen Sie Diskussionen und Expertengespräche für einen ergiebigen Wissenstransfer und erfolgreiches Networken. Während der vier Kongresstage erwartet Sie zudem eine große Fachausstellung mit den führenden Firmen der Branche. Erfahren Sie alles über die neuesten Trends, Herausforderungen und Lösungen im Embedded Software Engineering, von KI, Safety und Security bis hin zu Management und Innovation.

Verwendung

zyclictest start [options] -i <interval> Interval in microseconds -l <loops> Use loop mode -p <prio> Setup priority of threadzyclictest stop [options] -c Cancel loop mode prematurely -q Quiet mode with summary, but without histogram

Wenn Zyclictest gestartet wird, kann man das Intervall angeben. Dieses sollte mindestens zwei Mal die zu erwartende Thread-Latenz sein, um genügend Spielraum für die Messung zu haben.

Gibt man keine Priorität an, dann wird die höchste Priorität der kooperativen Threads genommen. Mit Angabe einer Anzahl an Loops kann der Loop-Mode verwendet werden. Dabei läuft Zyclictest nicht frei bis zum Beenden durch ein Kommando, sondern zählt die Durchläufe und bei Erreichen der angegebenen Anzahl an Durchläufen beendet es sich und gibt einen Hinweis darauf aus.

Bild 2: Beispielhafte Ausgabe der Messergebnisse.(Bild:  Andreas Klinger)
Bild 2: Beispielhafte Ausgabe der Messergebnisse.
(Bild: Andreas Klinger)

Wenn Zyclictest gestoppt wird, gibt es die gemessenen Werte aus. Dazu gehören sowohl für den Interrupt als auch für den Thread die minimale, durchschnittliche und maximale Latenz. Außerdem wird ausgegeben, ob es Overflows gab. Abschließend werden die Histogrammwerte ausgegeben in einer Form, die es ermöglicht, beispielsweise mit GNUPlot ausgewertet zu werden.

Wenn Zyclictest im Loop-Mode läuft, kann es auch abgebrochen werden. Dann werden die bis dahin gemessenen Werte ausgegeben.

Beispiel: Starten von Zyclictest im Loop-Mode mit 50 Mio. Durchläufen:

uart:~$ zyclictest start -l 50000000Cycle interval: 1000 usPriority: -16Finished thread with count: 50000000

Beenden (eigentlich ist der Thread schon beendet) und Ausgeben der Messergebnisse (siehe Bild 2):

uart:~$ zyclictest stop

Bild 3: Auswertung der Daten mit GNUplot.(Bild:  Andreas Klinger)
Bild 3: Auswertung der Daten mit GNUplot.
(Bild: Andreas Klinger)

Eine Auswertung der Daten beispielsweise mit GNUPlot könnte dann wie in Bild 3 gezeigt aussehen.

Messung mit Oszilloskop und GPIOs

Eine noch verlässlichere Messung ist die von außen mit Oszilloskop. Dabei wird ein kleiner Treiber erstellt, welcher einen GPIO-Interrupt verwendet und wenn der Interrupt kommt in der ISR einen Thread aufweckt. Der Thread toggelt dann einen anderen GPIO und die Zeit zwischen dem stimulierenden GPIO als Eingang und dem GPIO als Ausgang wird gemessen. Messungen an verschiedenen Systemen haben gezeigt, dass das Ergebnis nur sehr geringfügig von der Messung mit Zyclictest abweicht. Da diese Messung mehr Gerätschaften (Funktionsgenerator, Oszilloskop) erfordern, kann daher die Messung auch mit Zyclictest durchgeführt werden.

Referenzen: Pull-Request von Zyclictest (GitHub)

 (sg)

Dieser Beitrag stammt aus dem Tagungsband zum ESE-Kongress 2025

(ID:50915153)