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.
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.
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:
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,
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.
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.
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.
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.
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
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
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