Codeanalyse

Ohne Durchblick kein Debugging

5. August 2024, 6:00 Uhr | Von Bill Lamie
© Kanisorn|stock.adobe.com

Die Integration von Tracealyzer in das PX5-RTOS bietet Fähigkeiten zur Analyse, Fehlersuche und Optimierung von Embedded-Echtzeitsystemen. Der umfassende Überblick über das Systemverhalten unterstützt aber auch bei der Entwicklung effizienter, zuverlässiger und vorhersehbarer Embedded-Anwendungen.

Diesen Artikel anhören

Wer beim Debugging im Dunkeln tasten muss, hat es schwer! Softwareentwickler kennen das: Stunden vor einer wichtigen Firmware-Veröffentlichung stürzt das System ab und man versucht fieberhaft, den fehlerhaften Code zu identifizieren und zu korrigieren. Häufig können Entwickler die Anweisung, die den Absturz verursacht hat, sowie die Registerinhalte zum Zeitpunkt des Absturzes ermitteln. Erfahrene Entwickler können den Speicher durchforsten, den aktuell ausgeführten Thread und vielleicht auch Teile des C-Aufrufstapels eruieren. Manchmal reichen diese Informationen aus, aber oft ist die Absturzursache komplizierter – etwa das Ergebnis einer seltenen zeitlichen Bedingung von Thread-Ausführung und Interrupt-Ereignissen.

passend zum Thema

Visualisierung und Analyse

Vor Kurzem kündigte PX5 die Integration mit Percepio Tracealyzer an. Tracealyzer ist ein leistungsfähiges Softwaretool zur Visualisierung und Analyse von Embedded-Echtzeitsystemen. In Verbindung mit einem Echtzeit-Betriebssystem (Real-Time Operating System, RTOS) wie dem PX5 RTOS bietet es zahlreiche Vorteile. Die zehn wichtigsten sind:

  • Visualisierung des Echtzeitverhaltens:
    Tracealyzer bietet eine grafische Darstellung des Systemverhaltens, die es Entwicklern ermöglicht, den Ausführungsfluss, die Thread-Planung, Unterbrechungen und Interaktionen zwischen verschiedenen Komponenten in Echtzeit zu visualisieren. Diese Visualisierung erleichtert das Verständnis von Systemverhalten und -leistung.
  • Debugging und Leistungsanalyse:
    Mit Tracealyzer können Entwickler unter anderem Timing-Probleme, Deadlocks, Prioritätsumkehrungen und Ressourcenkonflikte in Echtzeitsystemen unter PX5-RTOS identifizieren und beheben. Das Tool ermöglicht eine tiefgreifende Analyse durch präzise Bestimmung von Zeitpunkt und Stelle im Code, an denen der Fehler auftritt.
  • Thread-Analyse:
    Tracealyzer bietet Einblicke in Thread-Ausführung, Kontextwechsel und Thread-Interaktionen. Es unterstützt die Optimierung der Thread-Planung, Identifizierung von Prioritätsumkehrungsproblemen und gewährleistet eine effiziente Nutzung der Systemressourcen.
  • Interrupt-Handling-Analyse:
    Tracealyzer ermöglicht Entwicklern das Verfolgen und Analysieren von Interrupts, um Interrupt-Latenzzeit, Ausführungszeiten der Handler sowie Interaktionen zwischen Interrupts und Threads zu verstehen.
  • Überwachung der Ressourcenauslastung:
    Tracealyzer bietet Einblicke in die Ressourcennutzung, einschließlich CPU-Auslastung, Speicherzuweisung und systemweiter Leistungsmetriken. Diese Informationen unterstützen die Optimierung von Ressourcenzuweisung und Systemleistung.
  • Timing-Analyse und Latenzmessung:
    Tracealyzer ermöglicht eine präzise Messung und Analyse des Timing-Verhaltens, einschließlich Thread-Antwortzeiten, Kommunikationsverzögerungen und der gesamten Systemlatenz. Dies ist entscheidend für die Einhaltung von Echtzeitvorgaben.
  • Visualisierung von Kommunikation und Synchronisation:
    Entwickler können Kommunikationsmechanismen wie Nachrichtenübergabe, Semaphornutzung und Synchronisationsprimitive visualisieren, was ein besseres Verständnis sowie die Optimierung der Inter-Thread-Kommunikation ermöglicht.
  • Verifizierung des Systemverhaltens:
    Tracealyzer hilft bei der Validierung des Systemverhaltens anhand der gegebenen Spezifikationen und zeitlichen Anforderungen. Das Tool trägt dazu bei, sicherzustellen, dass das System unter verschiedenen Bedingungen wie vorgesehen funktioniert.
  • Verbesserter Entwicklungs-Workflow:
    Durch die visuelle Darstellung von Systemverhalten und -leistung rationalisiert Tracealyzer den Entwicklungs-Workflow, indem es schnellere Debugging-, Optimierungs- und Validierungszyklen ermöglicht.
  • Schulung und Dokumentation:
    Die visuellen Darstellungen von Tracealyzer können zu Schulungszwecken und zur Dokumentation des Systemverhaltens für spätere Referenzzwecke oder den Austausch von Erkenntnissen zwischen Teammitgliedern wertvoll sein.

Systemvisualisierung schafft Transparenz

Ausschnitt aus dem Beispielcode »child thread«.
Listing 1. Ausschnitt aus dem Beispielcode »child thread«.
© PX5

Um auf das eingangs erwähnte Absturzszenario zurückzukommen: Stellen Sie sich vor, wie vorteilhaft es wäre, einen vollständigen Überblick über die Vorgänge im System vor dem Absturz zu haben. Anstatt nur grundlegende Informationen wie den Zeitpunkt der fehlerhaften Anweisung und den Inhalt der Register zu erhalten,

Code für »main thread«, der nach zehn Timer-Aufrufen einen Fehler verursacht
Listing 2. Code für »main thread«, der nach zehn Timer-Aufrufen einen Fehler verursacht.
© PX5

ermöglicht die Integration von PX5 RTOS mit Tracealyzer detaillierte Einblicke in die Abläufe des Systems vor dem Absturz. Zur weiteren Veranschaulichung zeigt Listing 1 ein Codeausschnitt des Beispiels »child thread«.

Listing 2 zeigt den »main thread«, der nach zehn Timer-Interrupts einen Absturz verursacht.

Ohne Visualisierung hätte ein Softwareentwickler nur die Befehlsadresse innerhalb von »cause_crash« und eventuell den Registerinhalt des Prozessors.

In der grafischen Darstellung von Tracealyzer kann der Softwareentwickler sehen, dass der »main thread« (Listing 2) zum Zeitpunkt des Absturzes lief und der Absturz direkt nach dem Aufruf von »px5_pthread_ticks_get()« auftrat
Bild 1. In der grafischen Darstellung von Tracealyzer kann der Software-entwickler sehen, dass der »main thread« (Listing 2) zum Zeitpunkt des Absturzes lief und der Absturz direkt nach dem Aufruf von »px5_pthread_ticks_get()« auftrat
© PX5

Mit Visualisierung kann er den vollständigen Verlauf der Systemereignisse unmittelbar vor dem Absturz sehen. Insbesondere kann er erkennen, dass der »main thread« zum Zeitpunkt des Absturzes lief und der Absturz direkt nach dem Aufruf von »px5_pthread_ticks_get()« auftrat, wie in Bild 1 gezeigt.

In Bild 1 ist auch zu sehen, dass der »child thread« (gelbe Balken) lief, bis er durch den Aufruf von »sem_wait()« angehalten wurde. Bei weiterem Zurückgehen wird ersichtlich, dass der SysTick-Interrupt (rot) während der Verarbeitung des »child thread« auftrat. Die Menge an historischen Informationen, die Tracealyzer visualisiert, wird nur durch die Größe des von der Anwendung bereitgestellten Trace-Buffers begrenzt.

Im Allgemeinen resultieren seltene Absturzbedingungen aus einer ungewöhnlichen Thread-Ausführung, die ohne ein Visualisierungs-Tool wie Tracealyzer schwer oder gar nicht zu verstehen ist. Ohne eine solche Visualisierung erfordert das Debuggen von Abstürzen erheblich mehr Zeit und Entwicklungszyklen, was eine Firmware-Veröffentlichung stark verzögern kann.

Mehr Verständnis führt zu mehr Optimierung

Code für »main thread«, der nach zehn Timer-Aufrufen einen Fehler verursacht
Listing 2. Code für »main thread«, der nach zehn Timer-Aufrufen einen Fehler verursacht.
© PX5

Es ist zudem schwierig, auf Systemebene zu optimieren, wenn die Verarbeitung auf Systemebene nicht verstanden wird. Die Visualisierung ermöglicht das Verständnis des Verhaltens auf Systemebene, sodass es optimiert werden kann. Als Beispiel dient nochmals der Code aus Listing 2, wobei der »main thread« das Semaphor nun dreimal statt nur einmal postet – Listing 3.

Der aktualisierte Code für »main thread« postet semaphore dreimal
Listing 3. Der aktualisierte Code für »main thread« postet semaphore dreimal.
© PX5

Wenn der »child thread« eine höhere Priorität als der »main thread« hat, kommt es nach jedem Semaphor-Posting des »main thread« zu einer Präemption (Kontextwechsel), wie in Bild 2 dargestellt.

Wenn es nötig ist, die Verarbeitung im »child thread« für jedes gepostete Semaphor sofort zu starten, ist dieses Verhalten akzeptabel.

Hat der »child thread« eine höhere Priorität als der »main thread«, erfolgt nach jedem Semaphor-Posting des »main thread« eine Präemption
Bild 2. Hat der »child thread« eine höhere Priorität als der »main thread«, erfolgt nach jedem Semaphor-Posting des »main thread« eine Präemption
© PX5

Kann die Verarbeitung im »child thread« aufgeschoben werden, bis alle Semaphore gepostet wurden, lassen sich zwei Kontextwechsel vermeiden, wie Bild 3 zeigt.

Indem die Prioritäten des »child thread« und des »main thread« gleichgesetzt werden, lässt sich der Kontextwechsel nach jedem »sem_post()«-API-Aufruf eliminieren, der die Verarbeitungszyklen für zwei unnötige

Wird die Verarbeitung im »child thread« aufgeschoben, bis alle Semaphore im »main thread« gepostet wurden, lassen sich zwei Präemptions vermeiden
Bild 3. Wird die Verarbeitung im »child thread« aufgeschoben, bis alle Semaphore im »main thread« gepostet wurden, lassen sich zwei Präemptions vermeiden.
© PX5

Kontextwechsel an die Anwendung zurückgibt.
Durch diese Optimierung auf Systemebene läuft nur noch der »child thread« nach dem API-Aufruf »sched_yield()«. Dies ist ein einfaches Beispiel dafür, wie Visualisierung zur Codeoptimierung eingesetzt werden kann.

 

 

Der Autor

 

Bill Lamie von PX5
Bill Lamie von PX5.
© PX5

Bill Lamie

ist President und CEO von PX5. Er hat über 30 Jahre Erfahrung in der Entwicklung kommerzieller Echtzeitbetriebssysteme. Seine Karriere begann Lamie bei Accelerated Technology, später von Siemens übernommen, und setzte sich bei Express Logic, später von Microsoft übernommen, fort. Er schuf als alleiniger Autor die Betriebssysteme Nucleus und ThreadX. Sein aktuelles Projekt, PX5, hat als Kernstück das PX5-Echtzeitbetriebssystem.

blamie@px5rtos.com


Lesen Sie mehr zum Thema


Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu Percepio AB

Weitere Artikel zu Echtzeit-/Embedded Software

Weitere Artikel zu Embedded-Systeme