{"id":7761,"date":"2022-01-12T16:25:12","date_gmt":"2022-01-13T00:25:12","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=7761"},"modified":"2025-09-09T19:27:29","modified_gmt":"2025-09-10T02:27:29","slug":"using-live-watch-with-esp32-c3-devices","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/esp32\/livewatch\/","title":{"rendered":"Using Live Watch on ESP32-C3 Devices"},"content":{"rendered":"<p>This tutorial shows how to use <a href=\"https:\/\/visualgdb.com\/documentation\/livevars\/\">Live Watch<\/a> with the ESP32-C3 devices. Unlike the regular ESP32 chip that uses the Xtensa core, ESP32-C3 is based on RISC-V, and hence allows accessing the device memory without stopping the CPU, allowing VisualGDB to inspect the values of the global variables without stopping the target.<\/p>\n<p>As of ESP-IDF 4.3.2, using Live Watch requires patching the <strong>components\/hal\/esp32c3\/include\/hal\/cpu_ll.h<\/strong> file to replicate <a href=\"https:\/\/github.com\/espressif\/esp-idf\/commit\/fcad8c7f4214d63819d07659b6781f2484f0b02a\">this commit<\/a>. We will show how to do it later in the tutorial.<\/p>\n<p>Before you begin, make sure you install VisualGDB 5.6 or later, and update the ESP32 Debug Package to the latest version.<\/p>\n<ol>\n<li>Start Visual Studio and open the <strong>New Project<\/strong> window. Then, locate the VisualGDB ESP32 Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/01-newprj-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7762\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/01-newprj-1.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Enter the name and location for your project, then press &#8220;Create&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/02-name.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7763\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/02-name.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Proceed with the default project type (new CMake-based project):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/03-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7764\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/03-cmake.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>On the next page of the wizard, select your ESP32 toolchain and pick the ESP32C3 device: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/04-toolchain.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7765\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/04-toolchain.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><strong>Note that Live Variables will NOT work on the regular ESP32 and ESP32S2\/S3 devices, as they utilize a different CPU.<br \/>\n<\/strong><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>Pick the project sample you would like to clone. In this tutorial, we will use the most basic &#8220;blink&#8221; sample:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/05-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7766\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/05-sample.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Connect your device to the USB port as shown in <a href=\"https:\/\/visualgdb.com\/tutorials\/esp32\/esp32-c3\/\">this tutorial<\/a> and let VisualGDB detect it. Then, select it in the &#8220;Debug Using&#8221; field and press &#8220;Test&#8221; to verify the connection:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/06-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7767\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/06-debug.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a>You can safely ignore the warning about all device registers being 0. It is normal for ESP32-C3 devices.<\/li>\n<li>Press &#8220;Finish&#8221; to generate the project. Before you build it, we would need to patch the ESP-IDF to prevent the CPU from entering the sleep mode while the debugger is connected (otherwise Live Watch will not work). To do that, locate the <strong>esp32c3\/include\/hal\/cpu_ll.h<\/strong> file and replace the <strong>cpu_ll_waiti()<\/strong> function with the one matching <a href=\"https:\/\/github.com\/espressif\/esp-idf\/commit\/fcad8c7f4214d63819d07659b6781f2484f0b02a\">this commit<\/a>:\n<pre class=\"\">#include &lt;soc\/dport_access.h&gt;\r\n#include &lt;soc\/system_reg.h&gt;\r\n\r\nstatic inline void cpu_ll_waiti(void)\r\n{\r\n    if (cpu_ll_is_debugger_attached() &amp;&amp;\r\n        DPORT_REG_GET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON) == 0)\r\n    {\r\n        return;\r\n    }\r\n\r\n    asm volatile(\"wfi\\n\");\r\n}<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/07-patch.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7768\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/07-patch.png\" alt=\"\" width=\"1246\" height=\"731\" \/><\/a><\/li>\n<li>Add a global <strong>g_Counter<\/strong> variable to the main source file and update the <strong>app_main()<\/strong> function to periodically increment it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/08-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7769\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/08-built.png\" alt=\"\" width=\"1246\" height=\"731\" \/><\/a><\/li>\n<li>Press F5 to build the project and start debugging it. As long as you have in-place display enabled in <a href=\"https:\/\/visualgdb.com\/documentation\/livevars\/\">Live Watch<\/a>, it will immediately display the value above the variable declaration: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/09-value-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7773\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/09-value-1.png\" alt=\"\" width=\"1246\" height=\"731\" \/><\/a>Note that if all values show the value of 0, double-check that you have patched the correct <strong>cpu_ll.h<\/strong> file, and rebuilt the project after doing so.<\/li>\n<li>Click on the live value to locate the variable in the Live Watch window. You can use the <strong>Globals<\/strong> view to quickly locate other variables or flag them as favorite:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/10-all.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7771\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/10-all.png\" alt=\"\" width=\"1246\" height=\"731\" \/><\/a>You can also use the <strong>Watch<\/strong> view to observe the values of specific variables.<\/li>\n<li>Click in the &#8220;Plot&#8221; column next to the <strong>g_Counter<\/strong> row. VisualGDB will display how the value of <strong>g_Counter<\/strong> changes over time:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/11-graph.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7772\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/11-graph.png\" alt=\"\" width=\"1246\" height=\"731\" \/><\/a><\/li>\n<li>You can use the plot view to conveniently measure various parameters (e.g. how fast the value changes over time):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/12-rate.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7774\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/01\/12-rate.png\" alt=\"\" width=\"1246\" height=\"731\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use Live Watch with the ESP32-C3 devices. Unlike the regular ESP32 chip that uses the<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[138,219,151],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7761"}],"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=7761"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7761\/revisions"}],"predecessor-version":[{"id":9033,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7761\/revisions\/9033"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=7761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=7761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=7761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}