{"id":7704,"date":"2021-11-29T14:48:20","date_gmt":"2021-11-29T22:48:20","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=7704"},"modified":"2021-11-29T14:48:20","modified_gmt":"2021-11-29T22:48:20","slug":"exploring-the-stm32wl55-examples-with-visualgdb","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/stm32\/stm32wl55\/","title":{"rendered":"Exploring the STM32WL55 Examples with VisualGDB"},"content":{"rendered":"<p>This tutorial shows how to use VisualGDB to build, debug and explore the sample projects for the wireless STM32WL55 microcontrollers. We will show how to clone the <strong>LocalNetwork<\/strong> sample included in the STM32WL55 SDK, adjust it to enable debugging, and fix an issue that causes it to crash out-of-the-box.<\/p>\n<p>The <strong>LocalNetwork<\/strong> sample consists of 2 projects: the <strong>concentrator<\/strong> that sends periodic beacon events, and the <strong>sensor<\/strong> that responds to them. In order to follow this tutorial, you will need two NUCLEO-WL55JC1 boards, as the STM32WL55 SDK 1.0 only includes samples for this type of board.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/01-newprj-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7705\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/01-newprj-2.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Pick a name and location for the first project. Note that since we are using two boards, we will need to create two separate projects: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/02-name.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7706\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/02-name.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>On the next page, select &#8220;Create a new project -&gt; Embedded Application -&gt; Advanced CMake&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/03-app.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7707\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/03-app.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Pick the ARM toolchain and select the <strong>STM32WL55JC<\/strong> device. Click &#8220;Install&#8221; to automatically download and install the STM32WL55 SDK:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/04-install.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7708\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/04-install.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Now that the SDK is installed, you can proceed with the default settings for the device: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/05-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7709\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/05-device.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>The STM32WL55 BSP includes numerous examples translated from the original SDK. You can view them by selecting &#8220;STM32CubeMX Samples&#8221; on the top part of the next page. As we are first creating the concentrator project, pick <strong>LocalNetwork_Concentrator<\/strong> and press &#8220;Next&#8221; to continue:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/06-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7710\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/06-sample.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Connect your board to the USB port and wait for VisualGDB to recognize it. Note that the default firmware that is programmed into the board often enters low-power mode, preventing the debugger from connecting to it. In order to avoid it, make sure you check the &#8220;connect under reset&#8221; checkbox: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/07-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7711\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/07-debug.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to create the project. Once it is created, you can build it by pressing Ctrl-Shift-B: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/08-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7712\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/08-built.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>Try running the project by pressing F5. VisualGDB will show a &#8220;Signal 0&#8221; in <strong>main() <\/strong>and OpenOCD will report a JTAG status error. This actually means that the JTAG\/SWD communication with the board was lost after the initial breakpoint in <strong>main()<\/strong>: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/09-sig0.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7713\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/09-sig0.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>This happens because the board enters the sleep mode, disabling the debugger-related logic. You can track down the location of this code by switching the <a href=\"https:\/\/visualgdb.com\/documentation\/codeexplorer\/globals\/\">Code Explorer<\/a> to <strong>global<\/strong> view, configuring the details to show <strong>Outgoing Calls<\/strong> only, pressing the &#8220;<strong>expand all<\/strong>&#8221; button several times, and searching for &#8220;sleep&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/10-sleep.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7714\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/10-sleep.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a>This will point to the <strong>DBG_Init()<\/strong> function checking the DEBUGGER_ON macro.<\/li>\n<li>Press F12 to go to definition of <strong>DEBUGGER_ON<\/strong> and change it from 0 to 1. Note that this will make the compiled firmware bigger and will substantially increase power consumption:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/11-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7715\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/11-debug.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>The <strong>Concentrator<\/strong> project will not start sending beacon packets unless you explicitly request it via a COM port. In order to do that, configure the Raw Terminal (requires Custom edition) to connect to the ST-Link port at 9600 bits\/second, or use any other terminal program:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/12-com.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7716\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/12-com.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>Now you can run the project again, send the &#8220;<strong>AT+BEACON_ON<\/strong>&#8221; command via the COM port and confirm that the board responds with &#8220;OK&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/13-beacon.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7717\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/13-beacon.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><strong>Warning: in order to comply with your local RF spectrum regulations, you may need to set the device region via a separate AT command. See the readme.txt file from the project directory for more details.<\/strong><\/li>\n<li>Now we will create another project for the second board. Leave the first project running and launch another instance of Visual Studio. Pick the name and location of the second project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/14-newsensor.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7718\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/14-newsensor.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Select the same project type and the toolchain, but this time pick <strong>LocalNetwork_Sensor<\/strong> on the Sample Selection page: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/15-prj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7719\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/15-prj.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the <strong>Debug Method<\/strong> page take a note of the serial number of the first board. Then, plug in the second one, and select the newly appeared ST-Link as the debug method:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/16-dbg2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7720\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/16-dbg2.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a>Don&#8217;t forget the &#8220;Connect under reset&#8221; checkbox, as otherwise debugging won&#8217;t work!<\/li>\n<li>Follow the same steps as before to enable the <strong>DEBUGGER_ON<\/strong> macro, then build and run the project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/17-debugger_on.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7721\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/17-debugger_on.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>The <strong>Concentrator<\/strong> project will show a partial AT+RCV message and will stop responding. Press <strong>Debug-&gt;Break All<\/strong> to see that the code is actually stuck in <strong>HardFault_Handler()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/18-stop.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7722\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/18-stop.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>The call stack won&#8217;t be very meaningful, indicating a memory corruption error. To track it down, search the source code for &#8220;AT+RCV&#8221;, and set a breakpoint at a line outputting it. Then, restart the concentrator, issue the initial AT commands, and finally restart the sensor board: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/19-toobig.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7723\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/19-toobig.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a>If you step through the <strong>CONC_Report_RCV()<\/strong> function that outputs the AT+RCV message, you will notice that it calls <strong>memcpy()<\/strong> to set the <strong>data<\/strong> variable without verifying the payload size. As of SDK version 1.0, it resulted in trying to copy 20 bytes into a 3-byte variable and overwriting the saved register addresses in the stack.<\/li>\n<li>You can use the Call Stack view to find that the value of 20 is derived by subtracting 6 from the payload received via <strong>SUBGRF_GetPayload()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/20-size.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7724\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/20-size.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>On the sensor side, this corresponds to the <strong>data_lim<\/strong> field that is set to the default value, and is never overwritten. You can use the Find References command (Shift-F12) along with the\u00a0 toolbar buttons in the Find Symbol Results window to quickly show all code locations where a variable is assigned:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/21-writes.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7725\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/21-writes.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>If you set breakpoints at both lines assigning <strong>data_lim<\/strong>, the first one will hit as soon as the sensor is ready to send, and the second one will never be triggered:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/22-size.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7726\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/22-size.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a>Note that hitting a breakpoint in either of the boards disrupts the board timing and breaks communication between them. We will\u00a0 give an overview of non-intrusive debugging methods that will work in this case at the end of the tutorial.<\/li>\n<li>The easiest way to fix the concentrator crash would be to add a size check just before the faulty memcpy() call:\n<pre class=\"\">      if (DataLen &gt; sizeof(data))\r\n          DataLen = sizeof(data);<\/pre>\n<p>Now you can restart the concentrator again, run the AT commands, start the sensor and confirm that multiple sensor packets are being received successfully:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/23-recv.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7727\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/23-recv.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<li>Note that default project parameters suggested by VisualGDB do not support the &#8220;%hhu&#8221; specifier in <strong>sprintf()<\/strong>. You can fix it by changing the C library type from <strong>Newlib-Nano<\/strong> to <strong>Default\u00a0<\/strong>via VisualGDB Project Properties: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/24-newlib.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7728\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/24-newlib.png\" alt=\"\" width=\"984\" height=\"631\" \/><\/a><\/li>\n<li>This will correct the output from AT+RCV at a cost of increasing the FLASH and RAM use:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/25-format.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7729\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/25-format.png\" alt=\"\" width=\"1427\" height=\"912\" \/><\/a><\/li>\n<\/ol>\n<p>Note that many wireless applications are critical to timing, so stopping the code at a breakpoint is likely to break the communication. As an alternative to breakpoints, consider the following non-intrusive debugging techniques:<\/p>\n<ul>\n<li><a href=\"https:\/\/visualgdb.com\/documentation\/livevars\/\">Live Watch<\/a> for watching and graphing variable values (e.g. packet counters)<\/li>\n<li><a href=\"https:\/\/sysprogs.com\/w\/extending-real-time-watch-with-custom-events\/\">Real-time watch with custom events<\/a> for tracking precise events<\/li>\n<li><a href=\"https:\/\/visualgdb.com\/tutorials\/profiler\/embedded\/coverage\/live\/\">Live Code Coverage<\/a> for viewing the running code paths in real time<\/li>\n<li><a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/semihosting\/\">Fast semihosting<\/a> as a faster alternative to the COM port<\/li>\n<li><a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/tests\/resources\/\">Test Resource Manager<\/a> for creating binary dump files on your development computer directly from the STM32 code<\/li>\n<\/ul>\n<p>You can find the source code shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/stm32\/STM32WL55\">GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use VisualGDB to build, debug and explore the sample projects for the wireless STM32WL55 microcontrollers.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[89],"tags":[242,241],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7704"}],"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=7704"}],"version-history":[{"count":2,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7704\/revisions"}],"predecessor-version":[{"id":7731,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7704\/revisions\/7731"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=7704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=7704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=7704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}