ESP32 Development Log 00: Environment Setup

ESP32 Development Log 00: Environment Setup

This is a continuation of the the blog series of ESP8266 development here, which at the end I concluded that I will be switching over to the ESP32 platform due to the lack of debugger support of ESP8266. Thus, this log series will be setup to track the development bugs and issues I encountered when using the ESP32, starting with the environment setup.

Basic Setup

You have to give Espressif a thumb-up on their documentation of ESP-IDF, which is very comprehensive on getting you start with ESP32. They even have an official Visual Studio Code extension to setup both the SDK and toolchain needed. If you haven't installed ESP-IDF before, you can just follow the instructions of the vscode extension to automatically download and install necessary tools. Beside vscode, they also have an Eclipse plugin as well if you prefer, though I haven't use that before.

Command Line Debugging Setup

After the initial setup, the next step is to enable debugging on ESP32. Luckily, the ESP-IDF documentation has a dedicated section discussing how to use JTAG adapter and OpenOCD to do the trick. One thing to note is that you cannot use the official OpenOCD for ESP32. Instead, you will need the Espressif's version of it, which should be installed as well when you install the ESP-IDF SDK. You can try openocd on your system (Linux/OSX) to see whether it have the similar message output like this:

Open On-Chip Debugger  v0.10.0-esp32-20200709 (2020-07-09-08:54)
Licensed under GNU GPL v2
For bug reports, read
embedded:startup.tcl:26: Error: Can't find openocd.cfg
in procedure 'script' 
at file "embedded:startup.tcl", line 26
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

If you do not get esp32 in your first line of output, it means that you are not using the ESP32 port of OpenOCD. You can download it here to install manually.

In addition, beside the OpenOCD, you will also need a JTAG adapter to communicate between the OpenOCD and your ESP32 board. If you happen to have a J-Link adapter, you can just setup the driver and specify the following command to run it with both the adapter and ESP32 board connected to your main computer:

openocd -f interface/jlink.cfg -f target/esp32.cfg

After you have your OpenOCD running, you now can use gdb to start debug your code! Detail setting of command line debugging can be found here.

  1. First you will need the driver for it, go to SEGGER site here, choose the J-Link Software and Documentation pack and install it on your machine
  2. To connect the EDU Mini with ESP32, you can refer to the wiring guide from ESP-IDF documentation here.
  3. After installation and connecting wires, you will need to run the JLinkExe once to setup the USB driver with the debugger, which should located at /opt/SEGGER/JLink/JLinkExe on Ubuntu and /Applications/SEGGER/JLink/JLinkExe on MacOS.
  4. Now you are good to go, just use the command to launch OpenOCD

Debugging with Visual Studio Code

If you don't want to use either command line debugging with gdb or via eclipse, you can try it out in Visual Studio Code! Though you will need the ESP-IDF extension and the C/C++ extension, which will be used to run Intelligense for code hints and debugging.

Although you can use the vscode configuration files generated by the IDF extension when creating a ESP32 application from template, I found that the debugger functionality of it is not working on my machine (Ubuntu 16.04 LTS, J-Link EDU Mini): it will hang once I press debug. If you also encounter this issue, you can use the following launch.json and task.json, which will use the C/C++ extension to run debugger:


    "version": "0.2.0",
    "configurations": [
        "name": "GDB",
        "type": "cppdbg",
        "request": "launch",
        "MIMode": "gdb",
        "cwd": "${workspaceFolder}",
        "miDebuggerPath": "${command:espIdf.getXtensaGdb}",
        // "miDebuggerServerAddress": "localhost:3333",
        "program": "${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
        "windows": {
          "program": "${workspaceFolder}\\build\\${command:espIdf.getProjectName}.elf"
        "environment": [{ "name": "PATH", "value": "${config:idf.customExtraPaths}:${env:PATH}" }],
        "setupCommands": [
          { "text": "source ${workspaceFolder}/gdbinit", "ignoreFailures": false },
        "launchCompleteCommand": "exec-continue",
        "externalConsole": false,
        "logging": {
          "engineLogging": false
        "preLaunchTask": "openocd",
        // "postDebugTask": "killopenocd"


    // See
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
            "label": "openocd",
            "type": "shell",
            "presentation": {
                "echo": true,
                "reveal": "never",
                "focus": false,
                "panel": "new"
            "command": "openocd -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
            "windows": {
                "command": "openocd.exe -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
                "options": {
                    "env": {
                        "PATH": "${env:PATH};${config:idf.customExtraPaths}"
            "options": {
                "env": {
                    "PATH": "${env:PATH}:${config:idf.customExtraPaths}"
            "problemMatcher": {
                "owner": "cpp",
                "fileLocation": "absolute",
                "pattern": {
                    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                    "file": 1,
                    "line": 2,
                    "column": 3,
                    "severity": 4,
                    "message": 5

Have fun coding!

Subscribe to TheXYZLab Blog

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.