{"id":4846,"date":"2019-06-10T21:36:37","date_gmt":"2019-06-11T04:36:37","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=4846"},"modified":"2025-09-09T19:29:10","modified_gmt":"2025-09-10T02:29:10","slug":"debugging-the-esp32-lyrat-board-via-jtag","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/esp32\/lyrat\/","title":{"rendered":"Debugging the ESP32-LyraT board via JTAG"},"content":{"rendered":"<p>This tutorial shows how to debug the ESP32-LyraT board using a JTAG debugger with VisualGDB.<\/p>\n<p>We will clone the <strong>play_mp3_control<\/strong> sample, program it into the FLASH memory via JTAG and use the debugger to understand the relations between different parts of the example and the ESP-ADF framework.<\/p>\n<p>Before you begin, install VisualGDB 5.4 or later, get a compatible JTAG debugger (e.g. Olimex ARM-USB-OCD-H or Segger J-Link), enable the JTAG via the on-board jumpers and connect the JTAG-related pins to a JTAG20 cable as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/board_big.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4855\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/board_big.jpg\" alt=\"\" width=\"1280\" height=\"748\" \/><\/a>The final setup including the board and the JTAG programmer should look similar to this:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/wiring-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4856\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/wiring-1.jpg\" alt=\"\" width=\"1280\" height=\"711\" \/><\/a>Now we are ready to create a basic project and begin debugging it:<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB ESP-IDF\/ESP-ADF project wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-newprj-7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4847\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-newprj-7.png\" alt=\"\" width=\"891\" height=\"639\" \/><\/a><\/li>\n<li>On the first page of the wizard select the GNU Make build subsystem, as it is the only build subsystem supported by the ESP-ADF framework:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/02-make.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4848\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/02-make.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>On the next page select your ESP32 toolchain and the ESP-ADF checkout. If you have not created ESP-ADF projects before, follow our <a href=\"https:\/\/visualgdb.com\/tutorials\/esp32\/esp-adf\">ESP-ADF tutorial<\/a> to import the ESP-ADF framework into VisualGDB:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/03-adf.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4849\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/03-adf.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><strong>Update:<\/strong> For better compatibility with the latest ESP32 tools, we recommend selecting the <a href=\"https:\/\/visualgdb.com\/documentation\/espidf\/consolidated\/\">consolidated toolchain<\/a> instead.<\/li>\n<li>On the next page of the wizard select the <strong>play_mp3<\/strong> example under <strong>get-started<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/06-play.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4832\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/06-play.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><strong>Warning: do not select the play_mp3_control example, as it uses GPIO pins that make JTAG debugging impossible.<\/strong><\/li>\n<li>Ensure both the board and the JTAG debugger are plugged into USB and select your debugger on the Debug Method page of the VisualGDB&#8217;s project wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/05-debug-5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4851\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/05-debug-5.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Press the &#8220;Test&#8221; button to test the wiring and ensure that the JTAG programmer can communicate to the ESP32 chip: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/06-test.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4852\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/06-test.png\" alt=\"\" width=\"786\" height=\"593\" \/><\/a><\/li>\n<li>Finally, press &#8220;Finish&#8221; to create the project and build it via Build-&gt;Build Solution:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4863\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-built.png\" alt=\"\" width=\"1131\" height=\"807\" \/><\/a><\/li>\n<li>Once the build succeeds, set a breakpoint in <strong>app_main()<\/strong> and start debugging by pressing F5. Note that the previous firmware programmed into the FLASH memory might trigger an internal error in the Espressif&#8217;s port of GDB:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/08-assert.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4858\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/08-assert.png\" alt=\"\" width=\"602\" height=\"443\" \/><\/a><\/li>\n<li>If this happens, try programming the FLASH memory using the COM port. First, select it via VisualGDB Project Properties -&gt; ESP-IDF Project -&gt; ESP-IDF configuration -&gt; Default serial port:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/09-port.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4859\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/09-port.png\" alt=\"\" width=\"1131\" height=\"807\" \/><\/a><\/li>\n<li>Then right-click in Solution Explorer and select &#8220;Program FLASH memory&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/programmed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4864\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/programmed.png\" alt=\"\" width=\"1131\" height=\"807\" \/><\/a>Once the new firmware is programmed, reset the board by pressing the RST button and the further FLASH programming via JTAG should work as expected.<\/li>\n<li>Set a breakpoint inside the app_main() function and hit F5 to begin debugging. Once VisualGDB finishes programming the FLASH memory and the breakpoint hits, step through the <strong>app_main()<\/strong> function to see the main tasks performed in it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4865\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-bkpt.png\" alt=\"\" width=\"1131\" height=\"807\" \/><\/a>The <strong>app_main()<\/strong> function in the <strong>play_mp3<\/strong> example performs the following tasks:\n<ol>\n<li>Creates a new audio pipeline by calling <strong>audio_pipeline_init()<\/strong>.<\/li>\n<li>Creates an mp3 decoder with a custom callback function to the pipeline (<strong>mp3_decoder_init()<\/strong>).<\/li>\n<li>Creates an I2S stream writer (<strong>is2_stream_init()<\/strong>) that will output the decoded waveforms to an I2S codec.<\/li>\n<li>Adds the created objects to the pipeline and links them together (<strong>audio_pipeline_register()<\/strong> and <strong>audio_pipeline_link()<\/strong>).<\/li>\n<li>Starts the pipeline by calling <strong>audio_pipeline_run()<\/strong>.<\/li>\n<\/ol>\n<\/li>\n<li>Set a breakpoint in the <strong>mp3_music_read_cb()<\/strong> function that is called by the mp3 decoder to read the mp3 stream, then resume the program and wait for the breakpoint to hit:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/03-copy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4866\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/03-copy.png\" alt=\"\" width=\"1131\" height=\"807\" \/><\/a>Note how the <strong>mp3_music_read_cb()<\/strong> function simply copies the data from the mp3 file in the FLASH memory to the buffer provided by the caller (<strong>audio_element_input()<\/strong>) .<\/li>\n<li>Set a breakpoint in <strong>app_main()<\/strong> after the call to audio_element_getinfo() and wait for it to trigger:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/04-info.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4867\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/04-info.png\" alt=\"\" width=\"1131\" height=\"807\" \/><\/a>Note how the mp3 decoder has sent an <strong>AEL_MSG_CMD_REPORT_MUSIC_INFO<\/strong> message with the details on the decoded mp3 stream and the app_main() function received it by calling\u00a0<strong>audio_event_iface_listen()<\/strong>.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to debug the ESP32-LyraT board using a JTAG debugger with VisualGDB. We will clone the play_mp3_control<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[142],"tags":[182,138],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4846"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=4846"}],"version-history":[{"count":3,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4846\/revisions"}],"predecessor-version":[{"id":9042,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4846\/revisions\/9042"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=4846"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=4846"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=4846"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}