ESP32 - DEBUGGING your ESP-IDF code using JTAG [VS CODE]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi there in this video i will show you how to debug your esp32 idf application inside visual studio code we go through the steps to set up and configure an external debugger and how to make it work reliably let's get started hi i'm yurijar and this is my second video of my esp32 series in my last one we have learned how to use the esp idea framework on visual studio code by the way thanks to everyone who watching and for all the positive feedback i really appreciate it today you are going to learn how to debug your esp idf application debugging is an essential skill for any professional firmware developer it allows us to find problems and have an insight of what's happening during and after consecution there are many different methods of debugging a microcontroller let's first take a look in the most common and simple one which is using the serial terminal basically this method involves adding the bug message that will be displaying the terminal this is the most simple way to gather information about execution of our code and it's useful if you don't have an external debugger too the esp-idf has a wonderful capability of catching exceptions and misconfigurations and integrates itself with visual studio code without any extra line of code let's take a quick look on how that works through the idf.bymonitor command we can see on the terminal some information regarding the esp32's initialization and partitions also when there is an exception the serial terminal shows a very complete report with the reason the line where the problem happened and even the call stack with a history of our function calls for example here this bug was a division by zero on line 44 of my blink.c file by holding the ctrl key and clicking on the printed line we can make visual studio code jump to the line where the exception happened as you can see this method is pretty straightforward however it has some limitations for example what if you cannot use prints at all like inside of interruption callback how do we get any information for that it's better to use an external tool external debugging device use a common debug interface to communicate to my controller and trust me they are extremely useful for developing there are many different debugging interfaces in the industry such as swd ice and jtag today we are going to work with jtag since it's natively supported by the esp32 and it's very popular and here are some cool things that we can do with the debugger we can define the so called breakpoints which will stop the execution of our code we need to reach that point we can manually control the execution of our code by stepping in out and over functions we have access to a variable list where you can see the values for all variables and pointers at that time we can even set a conditional breakpoint which will stop the code if only a certain value is true like a variable reaching a certain value for example and one of the most useful features the trace breakpoint trap which will automatically force a break point when a crash occurs giving us a lot of useful information so in the next steps i will show you which debugger to buy how to connect your debugger how to configure opencd how to configure gdb and how to configure visual studio code so which debugger tool should i get where can i get one there are many different debugging tools in the market expensive and powerful ones such as this sega j-link pro which is aimed more towards professional applications and also simpler and cheaper ones like these guys using the ftdi2232a chip this is a high-speed usb to jtag ic that provides the debug interface for us you can buy a debugger with this chip for less than 25 bucks on the internet there are many different board versions available but to get started i highly recommend getting this one called esp proc i will leave the links in the description below alright let's set up our debugger today i'm going to show the connections for the esp prog since it's easy to buy one and it's the official debugger from expressive it doesn't matter which device you use in the end as long as it supports jtag the ping connection for the interface should be the same the connection with our pc looks like this the esp32 is connected to the jtag debugger through the i o pins the debugger is then connected to our computer using a usb port this port is controlled by the jtag windows driver this jtag connection is then managed by a background software called openocd and then controlled by visual studio code through another software called gdp debugger and we also connect our esp32 to the computer using a second usb port so we can use the serial monitor don't worry i will explain each of these steps in more detail in a few minutes the first step is to connect it to the esp32 the esp proc has two connectors this first one is used for the jtag and the second one for the serial interface both can be connected to the esp32 and used through just one usb cable but in our example we are going to connect just the jtag and use the zero through the usb 32s usb interface to keep it simple [Music] for the asp proc we should connect it like this connect ground to ground 3v3 to 3v3 tck to io13 tdi to io12 tdo to io15 and tms2io14 [Music] in case you have a generic ftdi breakout board like these ones the connection should be like this after that we'll need to connect the esp32 and the debugger to our pc using two different usb ports one for the serial interface and the other one for the debugger's jtag interface but first in order for windows to properly recognize the debugger 2 and work as a jtag interface we need to store its driver in our case the ftdi ftdi2232h usb jtag driver let's take a look since the windows libraries already have a generic version of this ftdi driver with only the uart interface enabled we have to update it to add support for the jtag interface we are going to use a driver updater called zdeck you can download it through their official website let's open it go to options and then select list all devices then select duo rs232 interface 0 and click on replace driver this will update the driver for the ftdi giving us the ability to use the jtag interface on the ft 2232 chip to refresh the driver connection unplug and plug the usb back in the computer keep in mind that if you plug it in a different usb port you might need to install the driver again now that we have all the physical connections ready the next step is connecting the jtag to opencd openocd stands for open on-chip debugger and is responsible for managing the communication with the debugger driver in our case the ftdi driver let's open a new terminal on visual studio code make sure your environment is already configured for the esp-idf if you don't know how to do this check my previous video here by the way as many of you pointed out in my last video visual studio had an update and now we need to configure the idf terminal in a different way i will leave a link with the new instructions in the description in this example we are going to use the same blink project as before to keep things simple in the new terminal type the following command open ocd f board esp32 rover kit 3.3 v dot config this configuration file depends on the esp32 module being used you may need to provide a different file if you use a different one you can find more details on the idf documentation if you have connected your esp32 properly and your driver installed correctly you should see this output this means our debugger is wired properly and is up and running by the way in case your debugger is not connected properly you may see something like this and if your driver is not correct you may see something like this the next step is configuring gdb inside visual studio code gdb is the gnu debugger an open source debugging software used by visual studio code to communicate with opencd to do this let's click on the debug button on the vs code menu and click on run and debug and then on the c plus plus gdb option this will create a file called launch.json inside of the dot vs code directory in our project which we use to set the debugger parameters let's start by removing these lines that you are not going to need now let's add the parameters that are going to use name which is how you call this debug configuration type which is the debug type in our case cppdbg request which is launch cwd which is your workspace slash build program which is your elf file in our case workspace slash build slash blink.elf meet debugger path which is the path where your esp32 gdb is a critical use if you have followed my previous video you should have a folder structure similar to this one don't forget to correct the backslashes to forward slashes otherwise it's not going to work set up commands this is a list of gdp commands that will be executed by the debugger at startup the first command is going to tell gdb how the connection to opencd is going to be established in this case through localhost and the default port the next command specifies how many hardware breakpoints this microcontroller supports checking the idf documentation we know that esp32 supports only two the next command is monitor reset halt that command resets the esp32 and keeps it halted and finally flash reds this command forces gdb to flush its internal register cache and now let's save the file before we move on to the next configuration steps we can give a quick test to our debugger for the first time we first need to make sure that we have loaded the latest firmware build in our esp32 and also that opencd is running the terminal connected to our board finally we can try the plugin by clicking on the debug icon and then on the play button next to the esp32 openocd if everything was set up correctly the debug buttons will show up on the top now we can add breakpoints and play with all those functionalities that we've seen in the beginning of this video however since we need to be opening opencd manually all the time and also loading the firmware before we start debugging would be really nice if you could automate everything in order to make our life easier this is a very important step that i highly recommend you to do let's do this now first let's make opencd run automatically when we start debugging let's create a file called task.json inside of that.vs code folder to do this go to terminal configure tasks and see c plus build active file let's delete those lines now let's write the properties for this new task we start with label which is the name of this task then the type which is shell as you are running in windows we have to describe the command in windows session like this and finally the command which is clear and start opencd dash f board slash your config file and exit when you try the debugger for the first time you might have noticed that visual studio code doesn't always start debugging properly or it stops unexpectedly [Music] this is very annoying and make the debugging process very fragile and frustrating [Music] to solve this we need to add this flag here to tell opencd that you are not going to debug a much threaded application even if you are running freeartos this is a very important step the reason is that if you don't add that flag openocd is going to debug all tasks at same time and eventually visual studio code can lose track of one of the threads giving aero or not even start debugging even for our application smooth threaded most of the time we are interested in debugging only the task that hits the breakpoint so it's okay to have this flag set to have a better debugging experience but feel free to try yourself with and without the flag to see the difference in performance now in the launch.json file let's add this line pre-launch task column pre-run this will call our vs code task every time we start the debugging session now every time we start debugging it will open external terminal running opencd automatically for us let's now automate the loading of the firmware for us as well one of the cool things about using a debugger is that we can load the firmware straight from it that way you don't need to use this usb cable to load the firmware anymore first of all we need to tell the gdp debugger how the memory in our project is structured inside our esp32 so we can load the binaries in the proper memory positions for our simple blink example the memory structure looks like this the bootloader which is responsible for loading our application has 28 kilobytes reserved to itself and start at address 1000 followed by the partition table where the definition of our partitions are which starts at address 8000 and can go up to 4 kilobytes and finally our main application goes from here onwards since we haven't changed this project's configuration we have only 2 megabytes of free space to use we'll get into more details in the next video to find the addresses for our project we can just run the command idf dot pi build remember that huge command line from the first video it is there where we can see the name of our binaries and their memory addresses they can vary depending how you structure project the way we specify those addresses to gdb is by adding them to the end of the debugger configuration we need to add a new gdp command mount program esp with this command we can load a particular binary to a specific memory address for example to write the bootloader onto the memory address we have to type mount program esp the bootloader bing file the memory address 1000 and verify which is used to check if the file was written correctly and then we do the same for the other binaries partition table.bing at address 8000 and the main firmware blink blink.bin at address 10000 and then monitor reset halt and flash rights ok let's save now when you click on the bug everything is taken care of the firm is going to be loaded opencd is going to connect and we can't start debugging how good is that now let's take a quick look in a simple debugging example this is a very basic program just to illustrate how you can use an external debugger i have a button connected to my io pin 4 which you will generate an external interruption every time that i press it this program just basically doubles the last number shown you start with one one becomes 2 2 becomes 4 8 16 and so on look how strange it is it turns to 0 when it goes above 128 as you are using extend interruption we are not able to print some information at this point because this codes means a cute by interruption let's use our debugger to figure out what's wrong with our code let's add a breakpoint here and stop the execution of our code right when you double the counter when the breakpoint is hit inside this method we can see the value of the counter variable before we apply the double operation the counter variable holds one and pressing the step over button on the debug bar up here we can jump to the next line and check the counter variable again now we can see the variable holds 2. also we can even use step in if you want to see what harder instance milliseconds does and also step out if you want to see what's calling that callback function for a overview we can check here the call stack with the function history we can see the counter is performing the math operation properly and we know that our bug is a number after 128. so let's put a conditional breakpoint here to stop the program only with the counter is 128 like this so let's hit the button and there we go our breakpoint stopped only when our expression was satisfied let's jump over and see what the counter variable has it is correct but somehow when you return the counter value it's not returning the right information can you see why [Music] the function gap counter returns a uint8 it means that this function will return a 8-bit variable a byte but if you take a closer look at the counter variable it is a 32-bit variable four bytes every time we apply the double operation we shift the value one bit to the left when that happens for the eighth time our number will be bigger than eight bits and since the get counter can only return eight bit numbers it ends up returning zero we can fix it by changing the type of my method to return the same type as my variable after recompiling and load the fixed firmware version we can see now that when you press the button the program performs the calculation properly and shows the correct number in the display [Music] that was a simple but common mistake that many programmers do thanks to our debugger i was able to freeze the flow of my program inside an interruption and have an overview of all my variables going straight to the problem as you can see having an external debug is very useful and helpful for firmware developing before i go let me know in the comments if you like this type of content and what other topics you want to learn about don't forget to like and subscribe if you don't want to miss my next esp32 videos see you in the next one you
Info
Channel: Yuri R
Views: 3,185
Rating: undefined out of 5
Keywords: esp32, esp32 cam, ESP IDF, ESP-IDF, ESP32 IDF, Debugging, Debugger, JTAG, Arduino, OpenOCD, Visual Studio Code, ESP PROG, ESP-PROG, FT2232, FT2232h, GDB, firmware, esp32 platformio, platformio, espressif esp32 tutorial, esp32 visual studio code, embedded, programming, espressif, espressif esp32, C++, tutorial, STM32, RTOS, microcontroller, IOT, esp32 tutorial, debug, freertos, yuri r, espressif idf, embedded systems, how-to, embedded c++, embedded c, swd, mqtt, ble, bluetooth, wifi, blynk, esp32 arduino, ft232
Id: uq93H7T7cOQ
Channel Id: undefined
Length: 19min 53sec (1193 seconds)
Published: Mon Oct 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.