Vorweg: UDE ist keine IDE, aber kompatibel zu einer solchen. C-Code kann zwar importiert aber nicht weiterverarbeitet werden. UDE leistet Debug&Trace einer mit kompatiblem Compilerhtml" href="https://www.elektroniknet.de/design-elektronik/embedded/universalwerkbank-fuer-mikrocontroller-157464-Seite-6.html">2 erstellten Binärdatei. Sie kann auf ein kompatibles Ziel geschrieben und dort zur Laufzeit bzw. schrittweise, zum Beispiel in Variablen, Speicher- und Registerinhalten analysiert werden. Zur Verhaltensanalyse der Codeimplementierung auf dem Ziel können Variablen, Speicher- und Registerinhalte vor einer Ausführung modifiziert werden. Auch ist die direkte Veränderung einer Assemblercodezeile möglich.
Die Vorarbeiten zur Analyse der Codeimplementierung befinden sich im Menü »Debug« (Bild 7). Dort wird die Codeausführung auf dem Ziel gesteuert, Startpunkt und Stopbedingung gesetzt. Insbesondere ist die schrittweise Ausführung (Single-Step-Debugging) möglich. Dabei wird jeweils die nächste
Codezeile ausgeführt. Bis zu fünf aufeinander ausgeführte Codezeilen erhalten eine Hinterleuchtung, ihre unterschiedliche Helligkeit zeigt die Chronologie. In der C-Codeanzeige wird jeweils die nächste C-Zeile ausgeführt, im Mixed-Mode die jeweils nächste Assemblerzeile. Dies ist besonders in der Umgebung einer Programmverzweigung interessant.
Die Analysedarstellungen sind im Menü Views (Bild 7) enthalten, sowohl instantane Information beim Erreichen einer Stopbedingung, als auch die fortgeschrittene Traceanalyse. Darstellungen wie Watch, Peripheral Registers und Charts können Werteänderungen auch zur Laufzeit anzeigen. Das Tools-Menü enthält ihre Konfiguration und weiterverarbeitende Methoden für gespeicherte Prozessdaten, also Daten aus dem Zielsystem (zum Beispiel Tracedaten, Datensequenzen) oder daraus abgeleitete Daten.
Das Config-Menü bezieht sich auf die UDE, dort können weitere Programme (Add-Ins) hinzugefügt, das Ziel konfiguriert oder fortgeschrittene Einstellungen für den Debug-Server erfolgen.
Macro führt Scripten innerhalb der UDE für die Prozessdaten aus.
Verbindung zum Zielsystem – Den Startpunkt bildet das Erstellen eines neuen Projektes und die Verbindung mit dem Mikrocontroller. Die Auswahl der Konfiguration erfolgt nach Controller und schließlich dem Boardhersteller. Ist keine Konfiguration vorhanden, kann der Controllertyp mit seiner individuellen Konfiguration parametriert werden. Nach erfolgreicher Verbindung erscheint das Ziel im linken Fenster (Bild 4).
Codeanzeige und Modifizierung – Im Hauptfenster rechts daneben wird dann der im jeweiligen Speicher abgelegte Maschinencode (Disassembly View Mode) angezeigt, den ein Anwender natürlich sofort herunterladen und in lesbarem Code sehen möchte. Dieser Weg ist versperrt. Debugger arbeiten unidirektional, vor dem Debugging sollten C/C++-Code, Binärcode und Debuginformationen im ELF vorliegen. Liegt bereits eine Binärdatei im Target, genügen zunächst die Debuginformationen.
Der typische Workflow schließt eine Umgebung zur zielgerechten C/C++-Entwicklung ein, Buildtools wie Compiler oder Linker zur Erzeugung der
Binärdatei, Tools für das Laden der Binaries in den Mikrocontroller und schließlich der Debugger um Fehler und Performanz an der Implementierung zu messen.
UDE vereint Flash- und Debugtool: Nach erfolgreicher Verbindung mit dem Ziel kann der Binärcode mit dem Menüpunkt File>Load Programm (Bild 7) importiert werden. Ist ein kompatibler Compiler konfiguriert,
wird die Binärdatei innerhalb der UDE als C/C++-Source, Funktionsliste und den durchgängig belegten Speicherbereichen dargestellthtml" href="https://www.elektroniknet.de/design-elektronik/embedded/universalwerkbank-fuer-mikrocontroller-157464-Seite-6.html">3. Sofern die C-Quelle in der ELF-Datei referenziert wird, erfolgt das automatisch.
Ein C/C++-Code kann mitRechtsklick im Mixed-Mode, also kommentiert durch den zugehörigen Assemblercode, dargestellt werden. Die Assemblerzeile ist mit dem Inline-Assembler per Rechtsklick editierbar (Bild 8).
Weiterhin öffnet sich ein Reiter mit der Möglichkeit das Programm auf das Ziel herunterzuladen (Bild 9). Am Randleiste der C/C++-Darstellung finden sich drei Symbole: kleine blaue Punkte markieren eine in Assembler übersetzte Zeile, der gelbe Pfeil ist der Befehlszeiger, die roten großen Punkte bedeuten einen Haltepunkt.
Sprung- und Haltepunkte – Das DebugMenü (Bild 7) enthält die Sprungbefehle für Unterprogramme und die Festlegung von Haltepunkten. Haltepunkte können dabei absolut, bedingungsabhängig und an Operationen oder Daten gesetzt werden. Softwarehaltepunkte sind im allgemeinen Befehle die einen Interrupt auslösen. Dafür muss das Programm verändert werden. In vielen Architekturen sind auch direkt eine endliche Anzahl an Hardwarehaltepunkten nutzbar. Weiterhin sind Datenhaltepunkt setzbar. Sie finden sich im View-Menü unter dem Watches-Dialog. An eine angezeigte Assemblerzeile wird ein Haltepunkt einfach per Klick auf den blauen Punkt gesetzt oder wieder entfernt. Das Programm läuft nach dem Start bis zum nächsten Haltepunkt, von dort aus wird es mit dem nächsten Startbefehl bis zum darauffolgenden Haltepunkt laufen. Im
Single-Step-Modus wird, wie oben beschrieben, nur die jeweils nächste Codezeile ausgeführt. Nach dem Anhalten wird der Systemzustand ausgewertet und gegebenenfalls für das Debugging Variablen, Registerwerte oder Assemblerbefehle modifiziert.
Aufrufstapel – Das Call-Stack-Fenster zeigt den Programmverlauf (Bild 6 unten links). An oberster Stelle wird das aktuelle Register und seine Funktionsausführung gelistet. An unterster Stelle das Zielregister nach der Durchführung. Die dazwischen liegenden Zeilen zeigen die Aufrufhistorie.
Register lesen und schreiben – Das View-Menü (Bild 7) beinhaltet die Maske zur Einsicht in CPU-Register oder Peripherieregister. Per direktem Doppelklick auf das jeweilige Feld (Bild 4 rechts) kann der Inhalt modifiziert werden. Diese Werte sind farbcodiert: Rot für Veränderung durch das Programm im letzten Schritt, Blau für Veränderung durch den Anwender imletzten Schritt, Schwarz für unveränderte Werte. Die Liste der zu untersuchenden Peripherieregister wird vom Anwender zusammengestellt.
Memory-Window - Mit dem Memory-Window (Bild 5) lassen sich Inhalte ganzer Speicherbereiche des Zielsystems darstellen. Änderungen werden farblich (rot) hervorgehoben, was entweder am Breakpoint erfolgt, oder auch wahlweise während der Laufzeit. Manipulation der Speicherinhalte (auch ganzer Bereiche) durch den Anwender ist ebenso möglich, wie das Setzen von Daten-Breakpoints. Mit der Speicheranzeige kann ein Entwickler ein Gefühl dafür entwickeln, wie seine Werkzeugkette insbesondere komplexen Code auf dem Zielsystem umsetzt.
C/C++-Variablen verfolgen – Die Implementierung der Variablen im Programmiermodell kann mit dem Watches-Fenster aus dem View-Menü verfolgt werden. Dies ist insbesondere auch zur Laufzeit möglich. Der Inhalt wird vom Anwender konfiguriert. Per Rechtsklick auf das Feld wird aus dem Variablenvorrat des gelesenen Programms gewählt oder ein ganzer Ausdruck eingefügt. Zeiger wie Felder werden dabei mit ± gekennzeichnet.