Rasch aufgebaut: Software-Testumgebung für Mikrocontroller

Autor / Redakteur: Rich Miron * / Margit Kuther

Oft entfallen Tests von Mikrocontroller-Software, da es schwierig ist, moderne Testmethoden für Prozessoren auf Geräten mit eingeschränkten Ressourcen anzuwenden. Doch neues Debugging schafft Abhilfe.

Firmen zum Thema

Nucleo STM32L476RGT6: Das Board kann zur Überwachung der Pins des Mikrocontrollers STM32L4
Nucleo STM32L476RGT6: Das Board kann zur Überwachung der Pins des Mikrocontrollers STM32L4
(Bild: Digi-Key)

Einige neue fortschrittliche Debugging-Technologien in Verbindung mit traditionellen Designtechniken für Testumgebungen ermöglichen es Entwicklern von Embedded-Systemen jetzt, ihre Systemsoftware effektiver zu testen.

Eine moderne Testumgebung für Embedded-Systeme erfordert für einen vollständigen Test des Systems vier primäre Komponenten

  • Einen Trace-fähigen Debugger
  • Einen Kommunikationsadapter/Sniffer
  • Einen Logikanalysator
  • Einen Analog/Digital-Wandler (ADC)

Auf den ersten Blick sieht diese Abbildung wie eine herkömmliche Testumgebung für Embedded-Systeme aus. Aber die neuen Fähigkeiten sind einer neuen Form der Analyse der Vorgänge in einem Mikrocontroller zu verdanken, der sogenannten Tiefenanalyse (Deep Insight Analysis).

Software mittels Tiefenanalyse testen

Mittels Tiefenanalyse (Deep Insight Analysis) können Entwickler ihr System zur Laufzeit analysieren. Sie besteht aus drei Komponenten:

  • Debuggen in Echtzeit-Betriebssystemen (RTOS)
  • Laufzeitanalyse
  • Profiling und Analyse der Code-Abdeckung

Entwickler setzen bei der Entwicklung ihrer Anwendungen grundlegende Debug-Techniken wie Haltepunkte ein. Doch das Testen nur mit Haltepunkten ist oberflächlich und macht die Vorgänge innerhalb des Mikrocontrollers nicht wirklich sichtbar. Die Tiefenanalyse geht über dieses einfache Testen und Debuggen hinaus, indem es tiefer in das Echtzeit-Betriebssystem, das Laufzeitverhalten, das Ausführungsprofil und die Code-Abdeckung eintaucht.

Ein Entwickler, der in einer Testumgebung die Tiefenanalyse nutzen möchte, benötigt professionelle Debug-Tools wie J-Trace von Segger Microcontroller Systems oder J-Link Ultra+. Bei J-Link Ultra+ werden Trace-Daten vom Debug-Modul über eine Standard-JTAG- oder -SWD-Schnittstelle abgerufen. Mithilfe dieser Informationen können dann verschiedene Analysen, z. B. Debuggen in Echtzeit-Betriebssystemen, durchgeführt werden.

Das Debuggen in Echtzeit-Betriebssystemen ermöglicht den Entwicklern, die Performance ihrer Tasks während der Ausführung der Testfälle zu überwachen. Der Entwickler erhält z. B. folgende Informationen:

  • Maximale Stackbelegung
  • Anzahl der ausgeführten Tasks
  • Task-Status

Die Testumgebung kann durch die Verwendung des kostenlosen Hilfsprogramms SystemView von Segger oder des Tracealyzer von Percepio erweitert werden. Diese Tools ermöglichen den Entwicklern eine Laufzeitanalyse. So können sie visuell beobachten und analysieren, wie sich die Anwendung während der Ausführung der Testsuite verhält.

Die Laufzeitanalyse liefert eine Fülle von Informationen über das Verhalten einer Anwendung. Die Entwickler haben z. B. folgende Möglichkeiten:

  • Nachverfolgen des Timings und der Reihenfolge von Ereignissen
  • Ermitteln von maximalen, minimalen und durchschnittlichen Ausführungszeiten
  • Visueller Einblick in die Ausführung von Tasks und den Task-Wechsel
  • Überwachen der CPU-Last
  • Analyse von Task-Statistiken
  • Ermittlung von potenziellen Problemen wie Vertauschung von Prioritäten, Zeitverzögerungen und gegenseitige Blockierung von Tasks (Deadlock)

Doch das Debuggen in Echtzeit und eine Laufzeitanalyse sind möglicherweise nicht ausreichend. Oft verbergen sich Fehler in Code, der während eines Tests nie ausgeführt wird.

Nachverfolgen des ausgeführten Codes

Systemtest: Die Schnittstellen und Werkzeuge, die zum Testen eines eingebetteten Systems erforderlich sind, umfassen einen Debugger, einen Kommunikationskonverter, einen Logikanalysator und einen Analog/Digital-Wandler.
Systemtest: Die Schnittstellen und Werkzeuge, die zum Testen eines eingebetteten Systems erforderlich sind, umfassen einen Debugger, einen Kommunikationskonverter, einen Logikanalysator und einen Analog/Digital-Wandler.
(Bild: Beningo Embedded Group)

J-Trace verfolgt Anweisungen mithilfe des Embedded-Trace-Macrocell-Ports des Mikrocontrollers. Damit kann J-Trace jeden einzelnen im Prozessor ausgeführten Befehl und den exakten Pfad des Codes „sehen“.

Mithilfe dieser Analyse in der Testumgebung kann bestimmt werden, ob die Testfälle 100% des Codes abdecken. Wenn der Test weniger als 100% des Codes abdeckt, kann mithilfe eines kostenlosen Hilfsprogramms wie Ozone ermittelt werden, welche Codezeilen ausgeführt wurden und welche nicht. Basierend auf diesem Ergebnis können dann neue Testfälle hinzukommen, die dafür sorgen, dass die fehlenden Codezeilen ausgeführt werden.

Steuerung und Kontrolle des Embedded-Systems

Jedes Embedded-System hat unterschiedliche Anforderungen bezüglich der Interaktion mit seiner Umgebung. Manche Systeme kommunizieren möglicherweise über einen einfachen UART (Universal Asynchronous Receiver/Transmitter – Universeller asynchroner Empfänger/Sender), andere dagegen über CAN oder TCP/IP. Für eine erfolgreiche Testumgebung, die mit dem System kommuniziert und es auch steuern kann, ist zusätzliche Kommunikationshardware und -software erforderlich.

In Embedded-Systemen werden sehr viele Kommunikationsschnittstellen eingesetzt, aber ein UART wird sicher häufiger als andere verwendet. Entwickler von Embedded-Software setzen den UART häufig ein, und die Verwendung dieser Schnittstelle für die Testumgebung ist aus mehreren Gründen wichtig:

  • Für Debug-Informationen wie ausgegebene Meldungen
  • Steuerung des Geräts
  • Überwachung der internen Kommunikation zwischen mehreren Bausteinen
  • Benutzerfreundlichkeit

Ein gutes universelles UART-Werkzeug, das jeder Entwickler in der Werkstatt zur Hand haben sollte, ist das FT232R-USB-zu-UART-Entwicklungsboard BOB-12731 von SparkFun Electronics. Kostengünstige Boards wie diese können leicht an ein beliebiges Embedded-System angeschlossen werden. Sie werden vom PC als einfacher Kommunikationsanschluss erkannt und machen daher spezielle Treiber oder Software entbehrlich.

Überprüfung jedes einzelnen Logikzustands

Zum vollständigen Test eines Embedded-Systems muss ein Entwickler die interne Funktion des Mikrocontrollers und die von ihm generierte externe Logik verifizieren. Bei dieser Logik kann es sich um einfache Eingangs- und Ausgangszustände sowie um Kommunikation auf niedriger Ebene wie I²C oder SPI handeln.

Die Überwachung von Eingangs- und Ausgangszuständen und der Kommunikation auf niedriger Ebene kann aufwendig sein, wenn dazu ADC- und DAC-Boards (ADC: Analog/Digital-Wandler, DAC: Digital/Analog-Wandler) verwendet werden. Aber es gibt einige Tricks, mit denen die Kosten für die Überwachung dieser Signale gesenkt und die Testmöglichkeiten verbessert werden können.

Der erste besteht darin, die Pins des Mikrocontrollers über ein Entwicklungsboard für den Mikrocontroller im System zu überwachen. Wenn beispielsweise ein Mikrocontroller STM32F767 oder STM32L4 von STMicroelectronics zum Einsatz kommt, wird zunächst ein Nucleo-Board STM32F767 oder ein Nucleo-Board STM32L476RGT6 beschafft.

Dann werden die einzelnen I/O-Pins mithilfe der Anschlussleisten direkt mit den entsprechenden Pins auf dem System verbunden. Da die Low-Level-Treiber für den Mikrocontroller bereits entwickelt sind, können diese leicht angepasst werden, sodass sie ihre Eingangs- und Ausgangszustände überwachen.

Dann könnte etwas Code hinzugefügt werden, z. B. ein USB-Treiber, sodass das Entwicklungsboard direkt in die zu testende Host-Maschine eingesteckt werden kann.

Anstelle eines Entwicklungsboards könnte für die Testumgebung auch ein Logiktester wie der Logic Pro 8 (ebenfalls von SparkFun) verwendet werden. Diese Logikanalysatoren sind multifunktional, indem jeder Eingang mittels Software in die überwachte Größe gewandelt werden kann.

Tipps und Tricks für den Aufbau einer Testumgebung

Beim Aufbau einer neuen Testumgebung oder auch beim Upgrade einer Testumgebung gibt es einige Tricks, mit denen eine möglichst effektive Testumgebung erzielt werden kann:

  • Verwenden Sie ein Entwicklungskit für den Prozessor der Hauptanwendung
  • Investieren Sie in einen Trace-fähigen Debugger und setzen Sie die verfügbaren kostenlosen Softwarepakete ein
  • Verwenden Sie beim Ausführen eines Software-Trace immer Tests für die schlimmsten Szenarien
  • Wenn das Budget nicht für eine vollständige Testumgebung ausreicht, beginnen Sie mit geringem Aufwand, und bauen Sie die Umgebung im Laufe der Zeit aus
  • Nehmen Sie sich die Zeit, die Verwendung der verschiedenen Tools und Komponenten zu erlernen
  • Fürchten Sie sich nicht davor, eigene Schnittstellen einzusetzen und vorhandene zu nutzen
  • Treffen Sie keinerlei Annahmen! Wenn Sie eine Ausgabe nicht überwachen oder einen Eingang nicht verwenden, dann könnte sich genau dort ein Fehler einschleichen

Fazit: Das Entwickeln einer Testumgebung für ein Embedded-System stellt eine kostengünstige Möglichkeit dar, die Zuverlässigkeit eines Embedded-Systems zu erhöhen. Eine sorgfältige Auswahl von Komponenten für die Testumgebung ermöglicht den Entwicklern häufig, das externe Verhalten von Software zu überwachen. Der kritischste und oft übersehene Aspekt des Testens besteht darin, die jetzt bequem verfügbaren Trace-Daten des Mikrocontrollers zu untersuchen. Mithilfe dieser Trace-Daten können die Entwickler während der Ausführung der Testfälle eine Tiefenanalyse durchführen und damit sicherstellen, dass sich die Software korrekt und genau wie erwartet verhält.

* Rich Miron ist Mitarbeiter von Digi-Key Electronics

Artikelfiles und Artikellinks

(ID:45070678)