How to use JTAG built-in debugger of the ESP32-S3 in PLATFORMIO

How to use JTAG built-in debugger of the ESP32-S3 in PLATFORMIO

Most of the internet examples are showing using the ESP32-S3 built-in debugger in ESP-IDF, but I´m going showing how to do it in VSC PLATFORMIO.

Uses the ESP32-S3’s own USB port to upload the firmware and debug the software on the PLATFORMIO. Allows you to use the standard serial port on the ESP card/recorder for normal serial communication at the same time.

The video below is very complete and explains how to configure the ESP32-S3’s Embedded Debuger on PLATFORMIO. There are a lot of things on the internet, but this is the only way it worked for me in PLATFORMIO.
https://www.youtube.com/watch?v=HGB9PI3IDL0

It is possible to program and debug directly via the ESP32-S3’s NATIVE USB, without the need to connect the ESP32 via the main USB connector. However, it is interesting to have the main USB connection in order to receive serial communication from the ESP32 on the Platformio Terminal. Thus, we will have information from ESP32-S3 JTAG and via the serial directly in the terminal.

STEPS:
00-Download the Zadig 2.8 program here: https://zadig.akeo.ie

0-Connect the cable to the native USB of the ESP32-S3, it is through this port that the ESP recording and debugging will be done.

1-Download and open ZADIG, Options, List All Devices, Select “USB Jtag/serial debug unit (interface 0)”, change the current driver to “USB Serial (CDC)” and install by clicking the “Update Driver” button on the Zadig.

2-Still in ZADIG, select “USB Jtag/serial debug unit (interface 2)”, change the current driver to “WinUSB” and install by clicking the “Update Driver” button in Zadig.

3-Open the Windows device manager to find out which ports to configure, in my case COM14 is JTAG(“USB-JTAG/serial debug unit(Interface 0)”) and COM10 is the standard serial of the ESP32 board- S3(“USB-Enhanced-SERIAL CH323”)

4-In Platformio, configure the Platformio.ini file. In the attached file, there is the port COM14(or the same port that appears in the Windows device manager as “USB-JTAG/serial debug unit(Interface 0)” for the JTAG Debugger, and COM10(or the same port that in Windows device manager appears as “USB-Enhanced-SERIAL CH323”) for the serial monitor. It is through the debugger that the code is also uploaded. This way, the Platformio.ini file would be configured as follows:

[env:esp32-s3-devkitc-1]
platform = https://github.com/platformio/platform-espressif32.git   ;Fech lastest support for ESP32
;platform = espressif32
board = esp32-s3-devkitc-1    ;ESP32-S3
framework = arduino
upload_speed = 2000000     ;ESP32S3 USB-Serial Converter maximum 2000000bps
upload_port = COM14
monitor_speed = 115200
monitor_port = COM10
debug_tool = esp-builtin
debug_init_break = break setup
build_type = debug      ;build in debug mode instead of release mode

IMPORTANT:
-HOW TO CHANGE VARIABLES DURING DEBUG. In the Watch_Window it is only possible to view variables. However, if you type the variable name = value, it is changed as soon as you run the code during debug.
-Example changing String variable to “Eduardo ok”:
tchar={‘E’,‘d’,‘u’,‘a’,‘r’,‘d’,‘o’,’ ‘,‘o’,’ k’} : changes string value to “Eduardo ok”

-Before using ESP with the JTAG debugger, it is necessary to connect via normal USB and perform an ERASE FLASH. In PlatformIO itself there is the “Erase Flash” option. Otherwise, ESP can not work with JTAG, as the JTAG pins may be configured for something else.
-By clicking on the left side of the line number, Breakpoints are added. In watch we can view the variables, but to change their value, we need to locate them in the “VARIABLES” window. This is the worst part, as they are ordered in a confusing way and it is not possible to search, that is, changing the value of a variable in the PLATFORMIO debugger is rubbish, but the rest is very good, it is even possible to add a breakpoint on- the-go.
-In the Watch window, by typing (void )variable_name it is possible to view its value in HEX.
$pc : default decimal integer format
0x10012000 : an address, default decimal integer format
(void
)$pc : $pc register, hexadecimal format
(void
)0x10012000 : an address, hexadecimal format
&variable : shows variable pointing address
-It is possible to adjust variable format through DEBUG_CONSOLE:
set output-radix 16 : adjusts in HEX
set output-radix 10 : sets to decimal
set output-radix 8 : adjusts in octal
-It is possible to make calculations in the watch window. Ex:
var1*var2+4 : (the result appears)

Below the source file (main.c) of blink example program for debugging testing:

#include <Arduino.h>
#define LED_BUILTIN 2

long tdelay=1000;
char tchar[40];

// the setup function runs once when you press reset or power the board
void setup() {
    Serial.begin(115200);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  
  sprintf(tchar, "Teste");    //tchar[0]="Teste";
}


int i=0;
// the loop function runs over and over again forever
void loop() {
  i++;
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  Serial.println("Led ON");
  delay(tdelay);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  Serial.println("Led OFF");
  delay(tdelay);                      // wait for a second
}

Below some examples on using VSC PLATFORMIO debugger:
Watch Window and Serial Terminal:

How to add conditional breakpoints:
Platformio1
Platformio2

Show RTOS running tasks:

Changing variable values using watch window:


Debugger compiles, upload and runs F5 key (same as clicking Menu, Start debugging). I dig this image from another youtube video.

I hope it helps anyone that was struggling to debug ESP32-S3 in PLATFORMIO :slightly_smiling_face: :upside_down_face: :heart_eyes: :grin: :slightly_smiling_face: :slightly_smiling_face: :slightly_smiling_face: :slightly_smiling_face: :slightly_smiling_face:

12 Likes

Thanks a lot! I have been troubled all the day before saw the post!

1 Like

Thanks a lot! I have been troubled all the day before saw the post!

1 Like

Thank you for the detailed guideline!
I’m a bit stuck at the step 4: It seems you have there 2 COM ports - one for JTAG, second “USB-Enhanced-SERIAL CH323” and those you then use in the configuration for upload_port and monitor_port.
But on my end I see just the first one. (There are 2 others, but they are irrelevant to the microcontroller, they exist even with the microcontroller disconnected) It looks like this:


Do you happen to know what I could be doing wrong?

Hi there, @ vladimir.nejedly ,
What Probe are you using?
Did you run the “ZADIG” usb driver utility?
That’s the push that makes the whole thing GO! so , check that.
Great Post though, shows allot of cool tricks.
HTH
GL :slight_smile: PJ

Hey, thanks for the message! I’m using a built-in probe. And actually in the meantime I figured the problem out (just forgotten to report it here). I written whole tutorial about it on my page here: Debugging Dice Device – Dice Device
In short, I really had to run Zadig as you say, but only on the second device above (with ‘JTAG’ in name) and mainly had to be careful to select libusbK and especially not libusb0 (that realization cost quite some hours of my life… ;-)).

2 Likes

Yes, I use the Zadig. Take a look at the Tutorial.

I realized that when debugging I can use the JTAG Interface for programming and this same debuuger port for sending things over the serial. But sometimes it is not good, as when you reset the ESP32, it resets also the JTAG serial port, while the FTDI Serial works seamsly even when you reset the ESP32 as it is a separate chip.

Very interesting. For me it worked as I described on Windows10

Can I ask if debugging will work on either an ESP32-S2 Mini or an ESP32-S3-Zero, considering they only have a single USB port?

Yes, because that USB port is directly connected to the ESP32, there is no USB-to-UART converter on these boards which would create a second USB port.

Can the single serial port act as a serial and HID output at the same time as debugging over USB?

I have a sketch that uses both serial and HID keyboard.

I believe this guide is outdated. Yesterday, I spent about an hour following those parameters for my ESP32S3 Freenove WROOM board, but I later discovered that if you don’t include any special parameters in the INI configuration, the debugger works fine.

With the latest version of PlatformIO, you only need a basic S3 configuration for debugging using the native USB-C JTAG interface—nothing more. For example:

[env:esp32s3]
framework = arduino
platform = espressif32
board = esp32-s3-devkitc-1
monitor_speed = 115200
upload_speed = 1500000
monitor_filters = 
  esp32_exception_decoder
build_type = debug
build_flags =
  -D CORE_DEBUG_LEVEL=5
  -D ARDUINO_USB_CDC_ON_BOOT=1
2 Likes

I confirm this. After reading ESP32-S3 Technical Reference Manual about “USB Serial/JTAG Controller”, I realized that JTAG pins for ESP-S3 (GPIO39,40,41, 42) are not to these GPIO pins by default and you cannot attach an external debugger. By default, the ESP32-S3 JTAG controller is tied to its internal USB PHY on pins GPIO19 and 20. If your board has a USB connecter to these pins, then by default you MUST use this interface for debugging. If you want to connect an external JTAG debugger, you first need to configure (i don’t know what) on ESP32-S3 to derive the JTAG signals to GPIO pads on the ESP32-S3. I highly recommend to read Chapter 33 to anyone who is trying to debug it. I also spent a day and a half previous to be aware of that.

I think this is the “don’t know what” for @jmstantal’s comment:

There is an efuse you can blow to use those pins over the USB interface.
https://docs.espressif.com/projects/esp-idf/zh_CN/v5.5-beta1/esp32s3/api-guides/jtag-debugging/configure-other-jtag.html

Why an eFuse? You might want to single-step through boot code, or you might otherwise have hardware attached to those pins. If you have a device that really, really has JTAG pins on 39-42, blowing a fuse is less stressful than it is on your $5 dev board. I have heard rumors that dedicated probes are faster, as the USB implementation is presumably filling the 12 Mbps limit of USB Full Speed. Most of the super-cheap probes are going to share that limit. Maybe a Blackhawk or Lauterbach, etc., will be noticeably different. The Sipeed probe has the right specs to be awesome at a good price, but their software doesn’t actually work on my chosen OS, so mine sits unused. :frowning:

I send a lot of people to this page. Thank you, @eduardogb