ESP32 Debuggen mit Espressif ESP-Prog und PlatformIO – Anleitung

Egal in welchem Bereich der Programmierung du arbeitest, um das Debuggen kommst du einfach nicht herum. Beim Debuggen hast du die Möglichkeit, deinen Programmcode live, Zeile für Zeile, im laufenden Betrieb zu beobachten oder Variablen zu prüfen. Das hilft dir nicht nur dabei, Fehler – sogenannte Bugs – zu beheben, sondern auch Anpassungen vorzunehmen oder einfach nur den Code besser zu verstehen.

Mit dem Espressif ESP-Prog und PlatformIO gibt es eine einfache Möglichkeit, ESP32-MicroController zu programmieren und den Programmiercode im laufenden Betrieb zu debuggen. Wie genau das funktioniert und was du dafür brauchst, zeigt dir dieser Blogbeitrag.

Vorbereitung

Damit du diesen Beitrag Schritt für Schritt nachmachen kannst, benötigst du einige Bauteile. Schau dir dazu Tabelle 1 an. Je nachdem, wie du den ESP32 einsetzen möchtest, brauchst du entweder Jumper Male-Male oder Male-Female.

Hier ist die Tabelle, die die benötigte Hardware für den Aufbau auflistet:

PosMengeKomponente
11ESP32 NodeMCU Development Board
21BlackCotton Micro USB 2.0 Kabel, schwarz, 1,0m
31Espressif ESP-Prog, Programmiergerät für SoC-Systeme
4140pin Jumper

Tabelle 1: Benötigte Hardware für den Aufbau

Um dir das lange Suchen im Shop zu ersparen, habe ich einen entsprechenden Warenkorb für dich angelegt: Warenkorb auf Berrybase

Zusätzlich benötigst du eine lauffähige Programmierumgebung wie Visual Studio Code mit installierter PlatformIO-Erweiterung. Auch die Treiber für den ESP-Prog sind erforderlich, dazu erfährst du später mehr bei der Einrichtung von ESP-Prog und PlatformIO.

Anmerkung zum Debuggen und Warnung

Anders als bei gewöhnlicher Computersoftware programmierst du hier einen MicroController. Dafür wird ein externer Programmer – der Espressif ESP-Prog – verwendet, der eine physikalische Verbindung zum MicroController braucht. Beim ESP32 sind dies die vier GPIOs:

Zusätzlich muss auch die Stromversorgung mit 3,3V/5V und GND hergestellt werden. Achte darauf, dass der Jumper auf der richtigen Position steht, wie in Abbildung 1 gezeigt.

Abbildung 1: Den Jumper auf die richtige Spannung stellen

Die Beschriftung an der Seite hilft dir ein wenig weiter, wie der Jumper gesetzt werden muss.

Eine ausführliche Liste zu den Anschlüssen findest du direkt in der Dokumentation von PlatformIO, siehe Tabelle 2.

Natürlich, hier ist die Tabelle in einem textbasierten Format für Ihre Übersicht:

JTAG-Anschlussdetails für verschiedene ESP32-Varianten

ESP-Prog JTAG 10-Pin ConnectorJTAG SignalESP32 PinESP32-S2 und ESP32-S3 PinESP32-C2, ESP32-C3, ESP32-C6, und ESP32-P4 PinESP32-H2 PinBeschreibung
1VDDVDDVDDVDDVDDPositive Supply Voltage — Power supply for JTAG interface drivers
3GNDGNDGNDGNDGNDDigital ground
2TMSGPIO14GPIO42GPIO4GPIO2Test Mode State
4TCKGPIO13GPIO39GPIO6GPIO4JTAG Return Test Clock
6TDOGPIO15GPIO40GPIO7GPIO3Test Data Out
8TDIGPIO12GPIO41GPIO5GPIO5Test Data In
Tabelle 2: Anschluss ESP-Prog zu ESP32-Microcontrollern (Quelle: PlatformIO-Dokumentation)

Beachte dabei, dass diese GPIOs später für den Programmcode nicht mehr zur Verfügung stehen. Andernfalls riskierst du, dass entweder der ESP32 oder der ESP-Prog beschädigt werden. Im schlimmsten Fall könnte es sogar zu einem Kurzschluss kommen, der über die USB-Buchse an deinen PC weitergeleitet wird.

Ein weiterer wichtiger Hinweis: Verwende niemals beide USB-Anschlüsse (vom ESP32 und ESP-Prog) gleichzeitig! Dies könnte zu einem Defekt des ESP32 und/oder ESP-Prog führen. Halte immer nur eine Verbindung aufrecht und prüfe sorgfältig, dass alles korrekt angeschlossen ist. Der Upload beim Debuggen erfolgt ausschließlich über den ESP-Prog und nicht über den COM-Port des ESP32.

Den ESP-Prog vorbereiten

Bevor du den ESP-Prog mit PlatformIO nutzen kannst, musst du ihn noch umprogrammieren und Treiber für Windows nachinstallieren. Ich gehe hier nur auf Windows ein, weil die meisten wahrscheinlich Windows als Standardbetriebssystem verwenden.

Zunächst brauchst du den sogenannten VCP-Treiber, den du hier herunterladen kannst: VCP-Treiber. Wichtig ist, dass du den „Windows (Desktop)“-Treiber auswählst, siehe Abbildung 2.

Abbildung 2: Den VCP-Treiber herunterladen und installieren

Diesen Treiber musst du dann unter Windows installieren. Dafür brauchst du Administratorrechte, aber es dauert nur ein paar Minuten.

Anschließend muss der ESP-Prog „umprogrammiert“ werden. Dafür brauchst du das Tool Zadig, das du unter Zadig Download findest. Zum Zeitpunkt dieses Beitrags ist die Version 2.9 aktuell.

Nachdem du Zadig heruntergeladen hast, starte es und wähle den Treiber „Dual RS232-HS (Interface 0)“ aus. Damit das funktioniert, musst du unter „Options“ die Option „List all devices“ aktivieren. Danach wählst du „WinUSB (vXXXXX)“ und klickst auf „Replace Driver“, um den ESP-Prog umzuprogrammieren. Die Schritte sind noch einmal in Abbildung 3 erklärt.

Abbildung 3: Den Treiber des ESP-Prog ersetzen

Wenn der Treiber bereits ersetzt wurde, heißt der Button „Reinstall Driver“ anstatt „Replace Driver“.

Nach der Installation muss der ESP-Prog einmal vom PC getrennt und anschließend wieder verbunden werden, damit die korrekten Treiber geladen werden. Zadig sollte jetzt den WinUSB-Treiber anzeigen, nicht mehr FTDIBUS.

Damit sind die Vorbereitungen für den ESP-Prog abgeschlossen. Sollte es später Fehlermeldungen in PlatformIO geben, die zum Beispiel anzeigen, dass libusb_open() fehlschlägt oder esp32.flash kein free_driver_priv() unterstützt, führe diese Vorbereitung erneut durch. Die Fehlermeldungen werden in der PlatformIO-Konsole angezeigt.

Die Verkabelung

Damit der Espressif ESP-Prog mit dem ESP32 funktioniert und später mit PlatformIO kommunizieren kann, muss er korrekt verkabelt werden. Sieh dir dazu Abbildung 4 an.

Abbildung 4: Die schematische Verkabelung zu einem ESP32 NodeMCU

Abbildung 5: Pinout JTAG ESP-Prog (Quelle: PlatformIO-Dokumentation)

Wichtig ist hier der korrekte Anschluss, der bereits in der „Anmerkung zum Debuggen und Warnung“ beschrieben wurde. Zum besseren Verständnis zeigt Abbildung 5 das Pinout des JTAG des ESP-Prog.

Wenn du den Jumper auf dem ESP-Prog auf 3,3V oder 5V eingestellt hast, musst du sicherstellen, dass du auch den entsprechenden VIN-Pin am ESP32 verwendest. Andernfalls kann es zu Schäden am ESP32 kommen.

Einfacher Code und Debugging

In diesem Abschnitt erkläre ich dir anhand eines einfachen Codes, wie das Debuggen funktioniert. Das Projekt findest du im Repository von Berrybase. Der Quellcode belegt zwei Variablen mit zufälligen Zahlen, und eine Funktion summiert diese auf und gibt das Ergebnis zurück.

Hier ist der komplette Quellcode:

#include <Arduino.h>

// Function declarations:
int myFunction(int, int);

void setup() {
  Serial.begin(DEBUG_BAUDRATE);
}

void loop() {
  static int x, y = 0;
  x = random(20);
  y = random(50);
  int result = myFunction(x, y);
  Serial.println("Result: " + String(result));
  delay(500);
}

// put function definitions here:
int myFunction(int x, int y) {
  return x + y;
}

Code 1: Quellcode fürs Debuggen

Um das Debugging zu konfigurieren, müssen in der platformio.ini Datei einige Einträge gemacht werden:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
upload_port = COM6
build_flags = 
  -DDEBUG_BAUDRATE=115200

debug_build_flags =
  -O0
  -g
  -ggdb

debug_tool = esp-prog
debug_init_break = tbreak setup

Tabelle 3 erklärt im groben, was die Debugging Optionen machen, wobei in erster Linie die Debugging Option debug_tool wichtig ist. Dadurch wird der richtige Debugger und die Verbindung festgelegt, in diesem Fall der ESP-Prog. Allein mit dieser Option kann nun mit PlatformIO der Quellcode vom MicroController live debuggt werden.

OptionBeschreibung
debug_toolLegt fest, welcher Debugger und welches Tool für das Debugging verwendet wird.
debug_init_breakErmöglicht das Setzen von Breakpoints in der Setup-Funktion, was besonders nützlich ist, um in der Initialisierungsphase zu debuggen.
debug_build_flagsEnthält Einstellungen für den Build-Prozess während des Debuggens, wie z.B. O0 und ggdb, um die Sichtbarkeit aller Variablen zu gewährleisten.
Tabelle 3: Beschreibung der debug-options


Als nächstes, damit man auch etwas während dem Debuggen sieht, müssen sogenannte Breakpoints im Quellcode gesetzt werden, siehe Abbildung 6. Das sind die kleinen roten Punkte, die neben der Zeilennummer im Quellcode angezeigt werden.

Vereinfacht gesagt, stoppt beim Debuggen der Quellcode an der Stelle und zeigt, sofern alles richtige konfiguriert wurde, alle Variablen und deren Inhalt. Ferner ist es möglich ab dem Breakpoint entweder in Einzelschritten, also Schritt für Schritt den Quellcode zu debuggen, also so wie der MicroController den Code abarbeiten würde oder direkt zum nächsten Breakpoint zu springen.

Das Ganze geht aber auf Kosten der Zeit, weil die interne Uhr vom MicroController nicht angehalten wird.

Nun soll der Quellcode auf den MicroController geladen und der Debugger gestartet werden. Ersteres würde man jetzt vermuten wird über den üblichen Upload-Button in der Fußzeile vermuten, siehe Abbildung 7.

Abbildung 7: Code auf den MicroController uploaden

Da jedoch der Debugger mitlaufen soll, bzw. der Quellcode an den Breakpoints halten soll, muss über das Menü Ausführen -> Debuggen starten bzw. F5, siehe Abbildung 8, der Code kompiliert und auf den MicroController geladen werden.

Abbildung 8: Debuggen starten

Direkt nach dem Start des Debuggings passieren gleich mehrere Sachen, siehe Abbildung 9. Zunächst sieht im Terminal alles danach aus, dass der Code normal kompiliert wird, wobei ein weiterer Reiter Debugging-Konsole aufgetaucht ist.

Abbildung 9: Compilieren vom Code und geöffnete Debugging-Konsole

In diesem Fall wird der Code im sogenannten Debug-Modus kompiliert und dann über den ESP-Prog auf den MicroController übertragen. Direkt im Anschluss versucht sich der Debugger mit dem MicroController so zu verbinden, dass er auf den MicroController so Zugriff erlangt, um mitzuverfolgen, was gerade passiert. Die Meldungen in der Debugging-Konsole können an der Stelle erst einmal ignoriert werden, siehe Abbildung 10, da dieser erst einmal dazu dienen zu sehen, was aktuell gerade passiert.

Abbildung 10: Ausgaben der Debugging-Konsole

Teilweise, kann es auch vorkommen, dass ein weiterer Dialog im Bereich der Debugging-Konsole erscheint, siehe Abbildung 11, was insofern nur bedeutet, dass PlatformIO gerade am Arbeiten ist, um Quellcode auf den MicroController zu laden und den ESP-Prog fürs Debugging zu starten.

Abbildung 11: Warten auf den Debugger

Das ist alles nicht weiter schlimm und am Ende sollte der erste Breakpoint gelb hinterlegt sein, siehe Abbildung 12, da dieser erreicht wurde.

Abbildung 12: Breakpoint erreicht

Abbildung 13: Debuggingreiter

An der Stelle ist es nun möglich sich alle gespeicherten Werte in Variablen anzusehen, sofern diese schon angelegt oder global verfügbar sind, aber auch über Debuggingreiter, siehe Abbildung 13, auszuwählen, wie es weitergehen soll, wobei ich nicht auf alle Optionen eingehen werde. Wer schon mal Visual Studio oder ähnliche Programmierumgebungen verwendet hat, wird dies schon kennen.

Über den grünen Pfeil (F5) wird zum nächsten Breakpoint gesprungen, sobald diese Stelle aufgerufen wird. Über den blauen Pfeil der im Uhrzeigersinn zeigt (F10) wird ein sogenannter Prozedurschritt ausgeführt. Dabei wird nicht betrachtet was eine Anweisung im einzelnen macht, sondern im Fall vom ersten Breakpoint, wird zur nächsten Anweisung für die Variable „y“ übergegangen.

Mit dem blauen Pfeil der nach unten auf den Punkt zeigt (F11) wird ein sogenannter Einzelsprung durchgeführt. Hierbei wird jeder weitere einzelne Schritt gezeigt. Sollte dabei eine Funktion in unserem Fall der Variable „x“ einen Wert übergeben, wird in die Funktion gesprungen, um dort zu zeigen, was passiert.

Zuletzt möchte ich das rote Rechteck erwähnen (Umschalten + F5), welches das Debugging beendet.

Abschließende Worte

Für kleinere Programme ist das Debuggen oft nicht notwendig. Je komplexer ein Programm wird, desto eher treten jedoch Fehler auf, die gefunden werden müssen. Erster Anlaufpunkt ist natürlich die Auswertung von Kommentaren, die über den seriellen Monitor ausgegeben werden. Oft führt das allerdings nur bedingt zur Lösung.

Mit dem ESP-Prog und PlatformIO hast du eine hervorragende Möglichkeit, direkt in den Quellcode zu schauen und den Programmablauf Schritt für Schritt zu überwachen. So wirst du gezielt Fehler finden und beheben können.

Ob der ESP-Prog für dein Projekt wichtig ist, musst du selbst entscheiden – aber es bietet definitiv Vorteile bei der Fehlersuche. Bei größeren Projekten mit hunderten oder tausenden Zeilen Code nutze ich den ESP-Prog gerne, um zu überprüfen, ob alles so funktioniert, wie es soll.

Solltest du noch Fragen haben, hinterlasse mir einfach einen Kommentar!

Die mobile Version verlassen