On chip debugging on ESP32 with Eclipse and OpenOCD

With the help of a JTAG adapter, OpenOCD and Eclipse it’s possible to do on chip debugging on an ESP32. In the following chapters I’ll describe how to do that with the following hard- and software.

Used hardware:

  • ESP-WROOM-32 board
  • FTDI232 USB to Serial adapter
  • Olimex ARM-USB-OCD-H JTAG adapter

In theory it’s possible to program the flash memory also over JTAG but currently that’s not supported by the ESP32 OpenOCD driver. See also So we need an extra USB to Serial adapter. The Olimex ARM-USB-OCD-H JTAG adapter has also an extra RS232 port, but this port doesn’t provide 3.3 volt signals.

Used software:

  • Virtual Box 5.1.14 on Windows 10
  • VirtualBox 5.1.14 Oracle VM VirtualBox Extension Pack
  • Linux OS: Ubuntu 16.10 Desktop 64-bit running as guest on Virtual Box
  • Virtual Box Guest Additions
  • Putty
  • xtensa-esp32-elf toolchain
  • ESP32 IDF
  • OpenOCD; special version for ESP32
  • libftdi
  • Eclipse IDE for C++ Developers
  • GNU ARM Eclipse Plug-ins

I’ve prepare a ready to use Virtual Box appliance for download. If you wouldn’t install all the software by yourself you can download the appliance. But be warned that’s a 3.23 GB download.

You can easily import this appliance into Virtual Box. The user account is esp32 with password esp32.

Installing the software:

If you like installing all software by yourself you can follow these steps

Operating system

sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER
sudo reboot

Putty

Displaying the output from the ESP32 UART is easy with the Putty tool. So I’ve installed it via

sudo apt-get install putty

ESP32 Toolchain

  • For getting the ESP32  toolchain ready I followed the documentation at https://esp-idf.readthedocs.io/en/latest/linux-setup.html
  • I downloaded the 64-bit binary toolchain and extracted it to ~/esp/xtensa-esp32-elf/
  • Anomalous to the documentation I’ve added the path to the xtensa tools to ~/.profile. Not to ~/.bash_profile
  • The IDF_PATH variable I’d also set in the ~/.profile
  • I added the following lines at the end of the ~./profile and did a source ~/.profile
  • # exports for ESP32
    export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin
    export IDF_PATH=~/esp/esp-idf
  • After that I could do the make menuconfig from step 4.
  • I left all settings untouched, saved the configuration, exited menuconfig and executed the make command.
  • That brought me to the point where the ESP32 toolchain was ready for compiling

OpenOCD with libftdi

  • For debugging with OpenOCD and the Olimex ARM-USB-OCD-H JTAG adapter I did the following steps:

cd ~ sudo apt-get install build-essential git-core cmake doxygen libusb-1.0 make libtool pkg-config autoconf automake texinfo
git clone –recursive https://github.com/espressif/openocd-esp32.git

  • Download the sources for libftdi from https://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.3.tar.bz2 and extracted it into the openocd-esp32 directory
  • Then I’ve build the libftdi with the following commands

cd ~/openocd-esp32/libftdi1-1.3
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=“/usr“ ../
make
sudo make install

  • Now I was ready to build OpenOCD for EPS32 with the following commands

cd ~/openocd-esp32
./bootstrap
./configure
make
sudo make install

source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg]
adapter_khz 2000
esp108 flashbootstrap 3.3
  • The I saved this file to ~/openocd-esp32/esp32.cfg
  • I also copied the file ~/openocd-esp32/contrib/99-openocd.rules into the /etc/udev/rules.d directory.

Eclipse IDE

For running Eclipse I’ve installed the OpenJDK 8 via

sudo apt-get install openjdk-8-jre
  • Then I’ve downloaded Eclipse Neon installer from https://www.eclipse.org/downloads/
  • After unpacking the Eclipse installer package into ~/eclipse-installer I’ve started the eclipse-inst and installed the Eclipse IDE for C++ Developers into the default directory.
  • Then start Eclipse
  • Open a browser goto http://gnuarmeclipse.github.io/plugins/install/ and drag and drop the Install button to the running Eclipse
  • Check the following features of the GNU ARM Eclipse Plug-ins
    • GNU ARM C/C++ Cross Compiler
    • GNU ARM C/C++ OpenOCD Debugging
  • Click Confirm, accept the license agreement and click finish

Building the template app with Eclipse

For getting the template app (an blinky example) compiling in Eclipse I followed the documentation at: https://esp-idf.readthedocs.io/en/latest/eclipse-setup.html Additionally to the steps described I did the following:

  • Added the targets „all“ and „flash“ via right click at the project => Build Targets => Create…
  • After building the target „all“ I rebuild the index via right click at the project => Index => Rebuild

Creating the debugger configuration

For configuring the debugger in Eclipse I followed in general this documentation: http://gnuarmeclipse.github.io/debug/openocd/#create-the-debugger-configuration but with the following changes:

  • Debugger tab:
    • Options: -s /home/esp32/openocd-esp32/tcl -f /home/esp32/openocd-esp32/esp32.cfg
    • Executable: xtensa-esp32-elf-gdb
  • Startup tab:
    • Uncheck „Enable ARM semihosting“
    • Uncheck „Load executable“
    • Set breakpoint at: „app_main“; not „main“

With this configuration you will always break at the first available instruction.

Connecting the hardware

Connecting the FTDI232 USB to Serial adapter to the ESP-WROOM-32

For flashing via this adapter I’ve connected the adapter to the ESP-WROOM-32 board. I found the ESP-WROOM-32 pinout here: https://espressif.com/sites/default/files/documentation/esp-wroom-32_datasheet_en.pdf

  • GND => GND
  • 3.3V => 3.3V
  • ChipPU via 1.5kΩ resistor to 3.3V and via button to GND; that’s the reset button
  • GPIO0 via button to GND; holding this button down during reset will the the UART download mode
  • GPIO4 via 330Ω resistor to the anode of a LED; cathode of the LED to GND
  • U0RXD => TX of the FTDI232 adapter
  • U0TXD => RX of the FTDI232 adapter

Connecting the Olimex ARM-USB-OCD-H to the ESP-WROOM-32

I’ve connected the following 7 pins of the 20 pin JTAG adapter to the ESP-WROOM-32 board:

  • ESP32 3.3V => JTAG Pin 1 – VREF
  • ESP32 ChipPU => JTAG Pin 3 – TTRST_N
  • ESP32 GND => JTAG Pin 4 – GND
  • ESP32 MTDI => JTAG Pin 5 – TTDI
  • ESP32 MTMS => JTAG Pin 7 – TTMS
  • ESP32 MTCK => JTAG Pin 9 – TTCK
  • ESP32 MTDO => JTAG Pin 13 – TTDO

Connect the adapters to the Linux guest and establish a serial connection with putty

Connect both adapters (serial and JTAG) to the USB interfaces of the host computer and then connect both adapters to the Linux guest via Virtual Box menu Devices => USB => FTDI FT232R USB UART and Devices => USB => Olimex OpenOCD JTAG ARM-USB-OCD-H

Then I did a serial connection with putty and the following settings:

  • Connection type: Serial
  • Serial line: /dev/ttyUSB0
  • Speed: 115200

During power on of the ESP-WROOM-32 module I hold down the button on GPIO0 pin. In putty I found the following message:

rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download

After that test I disconnected putty.

Flashing the template app with Eclipse

If the ESP-WROOM-32 is in download mode you simply build the „flash“ target in Eclipse and wait until the download of the template app into the ESP32 flash is done. After that you can reset the ESP32 and see that you LED is blinking.

Start debugging

In Eclipse you can choose now Run => Debug Configurations…, select under GDB OpenOCD Debugging the app-template configuration and click Debug. If all is working fine you LED stops blinking and you will break in ipc.c:ipc_task. That’s the fist code that’s executed after booting. Now you can press F8 and stop in app_main.

Now you can debug the template app step-by-step, inspect variables, set breakpoints and so on…

Happy debugging!

 

16 Gedanken zu „On chip debugging on ESP32 with Eclipse and OpenOCD

    1. Hi Matthias. Greetings from the other side of the world 🙂

      Thanks for your time and effort.

      Hope you can help. Its about Eclipse /debugger/ESP32.

      My environment:
      OSX 10.11.6
      OpenOcd EspressIf
      Flyswatter2 Debugger

      Status:
      Blink app (example in Ep-idf) running fine without debugging.
      Debugging „directly“= openocd in one terminal and extensa-gdb in another, works great. App runs and blinks, can stop it, put a breakpoint, will stop at it, print a var, etc.

      When using Eclipse I get the following:
      1._ openOcd loads, from Eclipse or independently if necessary (disable Start OpenOcd locally)
      2._ extensa-gdb starts, message seen in the openocd terminal when connected
      3._ Eclipse gets a listing of all xtensa registers:

      Open On-Chip Debugger 0.10.0-dev-g90071eb (2017-04-20-17:09)
      Licensed under GNU GPL v2
      For bug reports, read
      http://openocd.org/doc/doxygen/bugs.html
      adapter speed: 8000 kHz
      force hard breakpoints
      Started by GNU ARM Eclipse
      Info : clock speed 8000 kHz (Ive lowered it to 200kHz with same result)
      Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
      Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
      Info : esp32.cpu0: Target halted, pc=0x400F1DBE
      Info : accepting ‚gdb‘ connection on tcp/3333
      Info : Auto-detected RTOS: FreeRTOS
      Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
      Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
      Info : esp32.cpu0: Core was reset (pwrstat=0x1F, after clear 0x0F).
      Info : esp32.cpu0: Target halted, pc=0x40000400
      esp32.cpu0: target state: halted
      Info : esp32.cpu1: Core was reset (pwrstat=0x1F, after clear 0x0F).
      Info : esp32.cpu1: Target halted, pc=0x40000400
      esp32.cpu1: target state: halted
      ===== Xtensa registers

      The Eclipse Debug perspective does not show the Resume (arrow icon) and have to Break (Pause icon) to get a listing of the app and its threads.
      I get this at the start(not blinking):
      DebugApp [GDB OpenOCD Debugging]
      debugapp.elf
      Thread #2 (Running : Container)
      Thread #3 (Running : Container)
      Thread #4 (Running : Container)
      Thread #5 (Running : Container)
      Thread #6 (Running : Container)
      openocd
      xtensa-esp32-elf-gdb

      I have to Pause it and I get this:

      DebugApp [GDB OpenOCD Debugging]
      debugapp.elf
      Thread #2 1073413048 (No Name) (Suspended : Container)
      prvIdleTask() at tasks.c:3,258 0x40084424
      0x40000000
      Thread #3 1073444328 (Svc) (Suspended : Container)
      Thread #4 1073411116 (No Name) (Suspended : Container)
      Thread #5 1073410672 (No Name) (Suspended : Container)
      Thread #6 1073408876 (No Name : Running) (Suspended : Signal : SIGINT:Interrupt)
      0x40000400
      Thread #7 1073413408 (No Name) (Suspended : Container)
      openocd
      xtensa-esp32-elf-gdb

      It seems to be in a loop at 0x40000000. I can choose a thread, list it, set breakpoint, BTW the app_main breakpoint is Set.

      Hope u can direct me to a solution. Vielen dank.

      Regards,

      Robert

  1. Hello Matthias,
    Thanks for sharing your experience in debugging ESP32 platform.
    I did quite similar to what you did with ESP32 dev.kit + Olimex AMR-UBS-OCD-H but when I get endless resets when running openocd:
    ./src/openocd -s ./tcl -f ./esp32_olimex_arm_usb_ocd_h.cfg
    Open On-Chip Debugger 0.10.0-dev-g90071eb-dirty (2017-03-08-15:11)
    Licensed under GNU GPL v2
    For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
    adapter speed: 2000 kHz
    srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst
    adapter_nsrst_delay: 1000
    force hard breakpoints
    Info : clock speed 2000 kHz
    Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
    Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x40, after clear 0x00).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0xE5, after clear 0x0F).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0x40, after clear 0x0F).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x40, after clear 0x00).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x72, after clear 0x00).
    Info : esp32.cpu1: Core was reset (pwrstat=0x72, after clear 0x00).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0x40, after clear 0x0F).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0xF9, after clear 0x00).
    Info : esp32.cpu1: Core was reset (pwrstat=0xF9, after clear 0x00).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0x40, after clear 0x0F).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0x40, after clear 0x0F).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x40, after clear 0x00).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0xE5, after clear 0x0F).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x40, after clear 0x00).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0xF9, after clear 0x00).
    Info : esp32.cpu1: Core was reset (pwrstat=0xF9, after clear 0x00).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0xF9, after clear 0x00).
    Info : esp32.cpu1: Core was reset (pwrstat=0xF9, after clear 0x00).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0xE5, after clear 0x0F).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x40, after clear 0x00).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x72, after clear 0x00).
    Info : esp32.cpu1: Core was reset (pwrstat=0x72, after clear 0x00).

    Did you encounter similar problem? If so, how did you solve it?

  2. Hello Matthias,

    Thank you for providing this plug and play image to us. You helped me saveing a lot of time. Do you maybe know a source for an ESP8266 -Toolchain Image too?

    Regards Robert!

  3. Hello Matthias,

    Thank you for yours sharing for ESP32, it great.
    I got some problem, and ask you about an advise ..
    So, I start xtensa-gdb from the command line, and it works OK.
    But when I start xtensa-gdb from Eclipse (Neon.3) I got the following messages:
    ./src/openocd-esp32/src/openocd -s ./src/openocd-esp32/tcl -f Pingzee-ESP32/esp32.cfg
    Open On-Chip Debugger 0.10.0-dev-g90071eb (2017-04-10-13:49)
    Licensed under GNU GPL v2
    For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
    none separate
    adapter speed: 200 kHz
    force hard breakpoints
    Info : clock speed 200 kHz
    Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
    Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
    Info : esp32.cpu0: Core was reset (pwrstat=0x5F, after clear 0x0F).
    Info : esp32.cpu0: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
    Info : esp32.cpu0: Core was reset (pwrstat=0x5F, after clear 0x0F).
    Info : esp32.cpu1: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
    Info : esp32.cpu1: Core was reset (pwrstat=0x5F, after clear 0x0F).
    Info : esp32.cpu0: Target halted, pc=0x40081168
    esp32.cpu0: target state: halted
    Info : accepting ‚gdb‘ connection on tcp/3333
    Error: esp32.cpu0: xtensa_write_memory (line 1024): DSR (8000CC13) indicates DIR instruction generated an exception!
    Warn : esp32.cpu0: Failed writing 4096 bytes at address 0x3F400010
    Error: esp32.cpu0: xtensa_write_memory (line 1024): DSR (8000CC13) indicates DIR instruction generated an exception!
    Warn : esp32.cpu0: Failed writing 4096 bytes at address 0x3F401010
    Info : dropped ‚gdb‘ connection

    The problem looks obvious – Eclipse try to write to the drom0_0_seg, and it read-only.
    But how I can avoid that?
    Thanks,
    Dmitriy

    1. Als Antwort auf Dmitriy Antonets.
      Hello Dmitriy,

      in the step „Creating the debugger configuration“ I’d to uncheck the „Load executable“ checkbox in the startup tab in the eclipse openocd debugger configuration.

      Hope that helps.
      Matthias

  4. Hallo Matthias,
    erstmal vielen Dank für die tolle Doku!
    Ich versuche, das gerade auf dem aktuellen ESP-Wrover-Kit zum Laufen zu bringen. Leider bekomme ich den Fehler „Error: timed out while waiting for target halted“. Ich denke mal, dass es inzwischen auch aktuellere Versionen gibt. Bin leider nicht ein Linux Experte, daher die Frage, ob es vielleicht irgendwo eine aktualisierte VM gibt.
    MfG
    Thomas

    1. Eine neuere VM habe ich nicht. Verwendest du auch den Olimex ARM-USB-OCD-H? Hast du ihn richtig angeschlossen? Gibt es vielleicht eine hilfreiche Log-Meldung?

      1. Ich benutze das ESP-Wrover-Kit mit dem On-Board FTDI-Chip. Der Prozessor wird auch erkannt, aber dann bleibt es mit der o.a. Meldung hängen…
        Dann werde ich es mal mit der Step-by-Step-Methode versuchen…

  5. Hi, how can I set se options to the debugger in order to upload automatically in the target the new application at the start of debug session?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert