{"id":5518,"date":"2020-01-23T18:10:25","date_gmt":"2020-01-24T02:10:25","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=5518"},"modified":"2021-03-26T17:27:56","modified_gmt":"2021-03-27T00:27:56","slug":"debugging-multi-core-stm32-devices-with-visualgdb","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/stm32\/multicore\/","title":{"rendered":"Debugging Multi-Core STM32 Devices with VisualGDB"},"content":{"rendered":"<p>This tutorial shows how to debug the multi-core STM32H7 devices featuring both an ARM Cortex-M7 and an ARM Cortex-M4 core. We will create 2 projects, one for each core, and will show how to configure our OpenOCD fork to automatically debug both cores at the same time. We will use the STM32H7-Discovery board featuring the STM32H747XI device, however the steps shown in this tutorial will work for other multi-core STM32 devices as well.<\/p>\n<p>Before you begin, install VisualGDB 5.5 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/01-emb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5519\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/01-emb.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>First, we will create a project for the Cortex-M7 core. Specify the name and location for the new project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/02-prjname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5520\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/02-prjname.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>On the first page of the VisualGDB&#8217;s wizard select &#8220;Create a new project -&gt; Embedded Binary -&gt; MSBuild&#8221; and click &#8220;Next&#8221; to proceed to the next page:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/03-bin.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5521\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/03-bin.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page select the ARM toolchain and pick your device from the list. Note that the multi-core devices will have 2 entries for each core (in this example, <strong>STM32H747XI<\/strong> corresponds to the Cortex-M7 core, while <strong>STM32H747XI_M4<\/strong> corresponds to the Cortex-M4 core):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/04-dev.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5522\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/04-dev.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page pick the LEDBLink (HAL) example and specify the port\/pin of the on-board LED. The STM32H7-Discovery board has 4 LEDs connected to ports PI12, PI13, PI14 and PI15, so we will select PI12 for the Cortex-M7 project and PI13 for the Cortex-M4 one:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/05-blink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5523\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/05-blink.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Connect your board to the USB port and select it in the &#8220;Debug Using&#8221; field. Ensure that the &#8220;Debugged Device&#8221; is detected as &#8220;STM32H7xx (Cortex M7 + M4)&#8221; and that you can select a specific core below. If not, update your OpenOCD package to the latest version using Tools-&gt;VisualGDB-&gt;Manage VisualGDB Packages:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/01\/dbg7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7246\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/01\/dbg7.png\" alt=\"\" width=\"886\" height=\"672\" \/><\/a><strong>Note: for the best multi-core debugging experience we recommend selecting the ST fork of OpenOCD as shown above.<\/strong><\/li>\n<li>Press &#8220;Finish&#8221; to create the project for the Cortex-M7 core. Build it by pressing Ctrl-Shift-B:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/07-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5525\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/07-built.png\" alt=\"\" width=\"1132\" height=\"786\" \/><\/a><\/li>\n<li>Now we will create a project for the Cortex-M4 core. Launch another Visual Studio instance and open the VisualGDB Project Wizard again:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/08-cm4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5526\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/08-cm4.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>This time, select the <strong>STM32H747XI_M4<\/strong> device:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/09-m4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5527\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/09-m4.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Also choose PI13 instead of PI12 as the LED port:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/10-blink2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5528\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/10-blink2.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the Debug Settings page select the Cortex-M4 core instead of the default Cortex-M7 one: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/01\/dbg4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7248\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/01\/dbg4.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a>Make sure you also uncheck the &#8220;reset device&#8221; flags, as otherwise starting a debug session with the Cortex-M4 core will reset the Cortex-M7 core.<\/li>\n<li>Now you can start debugging both projects, letting each core control one of the on-board LEDs:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/leds.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5534\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/leds.jpg\" alt=\"\" width=\"1280\" height=\"814\" \/><\/a><\/li>\n<li>Set a breakpoint in the <strong>for()<\/strong> loop of the Cortex-M7 project and press F5 in its Visual Studio instance to start debugging. Wait for the breakpoint to trigger:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/12-bp1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5530\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/12-bp1.png\" alt=\"\" width=\"1132\" height=\"786\" \/><\/a><\/li>\n<li>Switch to the Visual Studio instance that has the Cortex-M4 project open, set a breakpoint there and start debugging it as well:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/13-bp2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5531\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/13-bp2.png\" alt=\"\" width=\"1132\" height=\"786\" \/><\/a>The second Visual Studio instance will automatically connect to the OpenOCD session used by the first one, taking control of the Cortex-M4 core.<\/li>\n<li>The 2 Visual Studio instances will allow debugging the 2 cores of the STM32H7 device completely independently. E.g. resuming or halting one core will not affect the other one: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/14-both-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5535\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/14-both-1.png\" alt=\"\" width=\"1130\" height=\"786\" \/><\/a> Note that the cores share the same memory space (FLASH and RAM), however the code for them does not overlap. I.e. each core has its own copy of the <strong>main()<\/strong> function, <strong>HAL_Delay()<\/strong> function, etc., located at different locations in the FLASH memory. Similarly, each core has its own stack in the RAM that must be placed separately from the other core&#8217;s stack. You can use the VisualGDB&#8217;s Embedded Memory Explorer to explore the memory layout of each of the 2 projects and to understand the memory addresses used by each of them: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/15-layout.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5536\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/15-layout.png\" alt=\"\" width=\"1132\" height=\"786\" \/><\/a><\/li>\n<\/ol>\n<p>Note that in this tutorial both cores start and run independently. In most practical cases, the Cortex-M7 core would control the Cortex-M4 core, that requires additional debugger setup. See <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/stm32\/multicore\/startup\/\">this tutorial<\/a> for detailed instructions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to debug the multi-core STM32H7 devices featuring both an ARM Cortex-M7 and an ARM Cortex-M4 core.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[90],"tags":[192,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5518"}],"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=5518"}],"version-history":[{"count":5,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5518\/revisions"}],"predecessor-version":[{"id":7251,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5518\/revisions\/7251"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=5518"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=5518"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=5518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}