Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Developing IoT Projects with ESP32

You're reading from   Developing IoT Projects with ESP32 Unlock the full Potential of ESP32 in IoT development to create production-grade smart devices

Arrow left icon
Product type Paperback
Published in Nov 2023
Publisher Packt
ISBN-13 9781803237688
Length 578 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Vedat Ozan Oner Vedat Ozan Oner
Author Profile Icon Vedat Ozan Oner
Vedat Ozan Oner
Arrow right icon
View More author details
Toc

Table of Contents (15) Chapters Close

Preface 1. Introduction to IoT development and the ESP32 platform 2. Understanding the Development Tools FREE CHAPTER 3. Using ESP32 Peripherals 4. Employing Third-Party Libraries in ESP32 Projects 5. Project – Audio Player 6. Using Wi-Fi Communication for Connectivity 7. ESP32 Security Features for Production-Grade Devices 8. Connecting to Cloud Platforms and Using Services 9. Project – Smart Home 10. Machine Learning with ESP32 11. Developing on Edge Impulse 12. Project – Baby Monitor 13. Other Books You May Enjoy
14. Index

Debugging

All families of ESP32 MCUs support Joint Test Action Group (JTAG) debugging. ESP-IDF makes use of OpenOCD, an open-source software, to interface with the JTAG probe/adapter, such as an ESP-Prog debugger. To debug our applications, we use an Espressif version of gdb (the GNU debugger), depending on the architecture of ESP32 that we have in a particular project. The next figure shows a general ESP32 debug setup:

Figure 2.24: JTAG debugging

When we develop our own custom ESP32 devices, we can connect to the standard JTAG interface of ESP32 to debug the application. With this option, we need to use a JTAG probe between the development machine and the custom ESP32 device. The JTAG pins are listed on the official documentation for each family of ESP32 (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/configure-other-jtag.html).

The issue with JTAG debugging is that it requires at least 4 GPIO pins to carry the JTAG signals, which means 4 GPIO pins less available to your application. This might be a problem in some projects where you need more GPIO pins. To address this issue, Espressif introduces direct USB debugging (built-in JTAG) without a JTAG probe. In the preceding figure, the JTAG probe in the middle is not needed for debugging and OpenOCD running on the development machine talks directly to the MCU over USB. The built-in JTAG debugging requires only two pins on ESP32, which saves two pins compared to the ordinary JTAG debugging with a probe. This feature is not available in all ESP32 families but ESP32-C3 and ESP32-S3 do have it; thus, we will prefer this method in this example with our ESP32-S3-BOX-Lite devkit. We don’t need a JTAG probe but we still need a USB cable with the pins exposed outside to be able to connect them to the corresponding pins of the devkit. The connections are:

ESP32-S3 Pin    USB Signal
GPIO19            D-
GPIO20            D+
5V                V_BUS
GND            Ground

We can find a USB cable on many online shops with all lines exposed but it is perfectly fine to cut a USB cable and solder a 4-pin header to use its pins. You can see my simple setup below:

Figure 2.25: Built-in JTAG

We don’t need a driver for Linux or macOS to use the built-in JTAG debugging. The Windows driver comes with the ESP-IDF Tools Installer (https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/windows-setup.html#esp-idf-tools-installer).

Now, it is time to create the project and upload the firmware to see whether our setup works. In this example, we will see another way of creating an ESP-IDF project. We will work in the ESP-IDF environment from the command line and use the idf.py script to create the project and for other project tasks. Let’s do this in steps:

  1. If you are a Windows user, run the ESP-IDF Command Prompt shortcut from the Windows Start menu. It will open a command-line terminal with the ESP-IDF environment. If your development platform is Linux or macOS, start a terminal and run the export.sh or export.fish scripts respectively to have the ESP-IDF environment in the terminal:
    $ source ~/esp/esp-idf/export.sh 
    Detecting the Python interpreter
    Checking "python" ...
    Python 3.10.11
    "python" has been detected
    Adding ESP-IDF tools to PATH…
    <more logs>
    Done! You can now compile ESP-IDF projects.
    Go to the project directory and run:
    idf.py build
    
  2. Test the idf.py script by running it without any arguments. It will print the help message:
    $ idf.py
    Usage: idf.py [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
    ESP-IDF CLI build management tool. For commands that are not known to idf.py an attempt to execute it as a build system target will be made.
    <rest of the help message>
    
  3. Go to your project directory and run idf.py with a new project name. The script will create an ESP-IDF project with that name in a directory with the same name:
    $ idf.py create-project debugging_ex
    Executing action: create-project
    The project was created in <your project directory>/debugging_ex
    $ ls
    debugging_ex
    $ cd debugging_ex/
    $ tree
    .
    ├── CMakeLists.txt
    └── main
        ├──CMakeLists.txt
        └── debugging_ex.c
    1 directory, 3 files
    
  4. Download the sdkconfig file from the book repository into the project directory. It can be found here: https://github.com/PacktPublishing/Developing-IoT-Projects-with-ESP32-2nd-edition/blob/main/ch2/debugging_ex/sdkconfig.
  5. Run VSCode and open the debugging_ex directory.
  6. In the VSCode IDE, rename main/main.c to main/main.cpp and edit it to have the following code inside:
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    void my_func(void)
    {
        int j = 0;
        ++j;
    }
    extern "C" void app_main()
    {
        int i = 0;
        while (1)
        {
            vTaskDelay(pdMS_TO_TICKS(1000));
            ++i;
            my_func();
        }
    }
    
  7. Update the main/CMakeLists.txt file with the following content:
    idf_component_register(SRCS "debugging_ex.cpp" INCLUDE_DIRS ".")
    
  8. After these changes, we should have the following directory structure:
    $ tree
    .
    ├── CMakeLists.txt
    ├── main
    │   ├── CMakeLists.txt
    │   └── debugging_ex.cpp
    └── sdkconfig
    1 directory, 4 files
    
  9. We need to enable the debug options in the root CMakeLists.txt file. Edit it and set its content as the following:
    cmake_minimum_required(VERSION 3.16.0)
    include($ENV{IDF_PATH}/tools/cmake/project.cmake)
    project(debugging_ex)
    idf_build_set_property(COMPILE_OPTIONS "-O0" "-ggdb3" "-g3" APPEND)
    
  10. In the terminal, build the application by running idf.py:
    $ idf.py build
    Executing action: all (aliases: build)
    <more logs>
    Creating esp32s3 image...
    Merged 2 ELF sections
    Successfully created esp32s3 image.
    <more logs>
    
  11. See that the idf.py script has generated the application binary under the build directory:
    $ ls build/*.bin
    build/debugging_ex.bin
    
  12. Run the following command to see the basic size information of the application:
    $ idf.py size
    <some logs>
    Total sizes:
    Used static IRAM:   87430 bytes ( 274810 remain, 24.1% used)
          .text size:   86403 bytes
       .vectors size:    1027 bytes
    Used stat D/IRAM:   13941 bytes ( 158987 remain, 8.1% used)
          .data size:   11389 bytes
          .bss  size:    2552 bytes
    Used Flash size :  153979 bytes
          .text     :  113547 bytes
          .rodata   :   40176 bytes
    Total image size:  252798 bytes (.bin may be padded larger)
    
  13. Flash the application on the devkit (if flashing fails with a port error, just reverse the D+/D- connections of the devkit. This simple change will probably solve the problem):
    $ idf.py flash
    Executing action: flash
    Serial port /dev/ttyACM0
    Connecting...
    Detecting chip type... ESP32-S3
    <more logs>
    Leaving...
    Hard resetting via RTS pin...
    Done
    
  14. We now have an application running on the devkit, ready for debugging. Run a GDB server with the following command (idf.py will start an OpenOCD process for this):
    $ idf.py openocd --openocd-commands "-f board/esp32s3-builtin.cfg"
    Executing action: openocd
    OpenOCD started as a background task 477341
    Executing action: post_debug
    Open On-Chip Debugger v0.11.0-esp32-20221026 (2022-10-26-14:47)
    Licensed under GNU GPL v2
    <more logs> 
    
  15. Start another ESP-IDF command-line terminal as we did in step 1 and change the current directory to the project root directory.
  16. Run the following command to start a GDB client. It will open a web-based GUI in your default browser:
    $ idf.py gdbgui
    Executing action: gdbgui
    gdbgui started as a background task 476131
    

The idf.py script is the single point of contact to manage an ESP-IDF project. We can create, build, flash, and debug an application by only using this script. It has more features and we will have many chances to learn and practice those features throughout the book. The ESP-IDF build system documentation provides detailed information about the idf.py script and how it works with cmake to collect all the project components to compile them into an application. Here is the link for the documentation: https://docs.espressif.com/projects/esp-idf/en/v4.4.4/esp32s3/api-guides/build-system.html.

With a debugging session ready on the web GUI, we can now debug the application. The following screenshot shows this GUI.

Figure 2.26: Web-based debugger

The left panel shows the source code that is being debugged. We can set/remove breakpoints by clicking on the row numbers. The right panel shows the current status of the application, including threads, variables, memory, etc. On the top right, the buttons for the debug functions (restart, pause, continue, and step in/out/over) are placed. The debug functions also have keyboard shortcuts to ease the debugging process. Try the following debugging tasks on the GUI:

  • Click on line number 17 to set a breakpoint.
  • Press C (continue) on the keyboard and observe that the local variable i increases every time the execution hits the breakpoint.
  • Try pressing N (next) to run each of the lines consecutively.
  • When the execution comes to my_func, press S (step in) to enter the function. You can exit the function by pressing U (up).

This GUI is enough for an average debugging session and can be used to observe the behavior of the application when necessary. If you need to access other gdb commands, there is also another panel at the bottom where you can type these commands.

You have been reading a chapter from
Developing IoT Projects with ESP32 - Second Edition
Published in: Nov 2023
Publisher: Packt
ISBN-13: 9781803237688
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image