{"id":8973,"date":"2025-03-13T15:37:59","date_gmt":"2025-03-13T22:37:59","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=8973"},"modified":"2025-03-13T15:37:59","modified_gmt":"2025-03-13T22:37:59","slug":"debugging-the-openamp-example-on-the-stm32mp2-device","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/stm32\/stm32mp2\/openamp\/","title":{"rendered":"Debugging the OpenAMP example on the STM32MP2 device"},"content":{"rendered":"<p>This tutorial shows how to build and debug the OpenAMP example on the Cortex-M33 core of the STM32MP2 device. OpenAMP allows exchanging messages between the Cortex-A core running Linux and the Cortex-M33 core running a separate embedded firmware.<\/p>\n<p>Before you begin, make sure you can boot your STM32MP2 device into Linux (see <a href=\"https:\/\/visualgdb.com\/tutorials\/linux\/stm32mp1\/sdk\/\">this tutorial<\/a> for instructions on building Linux images for STM32MP1 devices, and <a href=\"https:\/\/visualgdb.com\/documentation\/arm\/stm32\/stm32mp2\/\">this page<\/a> for differences between STM32MP1 and STM32MP2).<\/p>\n<ol>\n<li>Start Visual Studio and locate the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/01-embwiz.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8974\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/01-embwiz.png\" alt=\"\" width=\"1014\" height=\"675\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/01-embwiz.png 1014w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/01-embwiz-300x200.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/01-embwiz-768x511.png 768w\" sizes=\"(max-width: 1014px) 100vw, 1014px\" \/><\/a><\/li>\n<li>Enter the name and location for your project: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/02-prjname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8975\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/02-prjname.png\" alt=\"\" width=\"1014\" height=\"675\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/02-prjname.png 1014w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/02-prjname-300x200.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/02-prjname-768x511.png 768w\" sizes=\"(max-width: 1014px) 100vw, 1014px\" \/><\/a><\/li>\n<li>Select <strong>New Project -&gt; Embedded Application -&gt; Advanced CMake<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/03-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8976\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/03-cmake.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/03-cmake.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/03-cmake-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/03-cmake-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>On the next page select your STM32MP2 device. If this is the first time you are targeting STM32MP2, VisualGDB will suggest installing the STM32MP2 BSP:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/04-stm32mp2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8977\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/04-stm32mp2.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/04-stm32mp2.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/04-stm32mp2-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/04-stm32mp2-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Once the BSP is installed, proceed with the default settings:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/05-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8978\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/05-device.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/05-device.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/05-device-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/05-device-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>On the next page, select <strong>STM32CubeMX Samples -&gt; OpenAMP_TTY_echo<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/06-echo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8979\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/06-echo.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/06-echo.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/06-echo-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/06-echo-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Connect your ST-Link probe to the board and make sure the Cortex-M33 core is started by running &#8220;<strong>echo start &gt; \/sys\/class\/remoteproc\/remoteproc0\/state<\/strong>&#8221; from the Linux terminal on STM32MP2: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/07-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8980\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/07-debug.png\" alt=\"\" width=\"937\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/07-debug.png 937w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/07-debug-300x222.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/07-debug-768x568.png 768w\" sizes=\"(max-width: 937px) 100vw, 937px\" \/><\/a><\/li>\n<li>Once the M33 core is running, you can test the debugging connection by pressing the <strong>Test<\/strong> button : <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/08-tested.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8981\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/08-tested.png\" alt=\"\" width=\"916\" height=\"622\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/08-tested.png 916w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/08-tested-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/08-tested-768x522.png 768w\" sizes=\"(max-width: 916px) 100vw, 916px\" \/><\/a><\/li>\n<li>Click &#8220;Finish&#8221; to complete the wizard. Then build the project by pressing Ctrl-Shift-B:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8982\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built.png\" alt=\"\" width=\"1158\" height=\"790\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built.png 1158w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built-1024x699.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built-768x524.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/09-built-130x90.png 130w\" sizes=\"(max-width: 1158px) 100vw, 1158px\" \/><\/a><\/li>\n<li>Running the OpenAMP example on the Cortex-M33 core requires special steps:\n<ul>\n<li>The M33 firmware must include the OpenAMP descriptor table (included in this example)<\/li>\n<li>The firmware (ELF file) must be uploaded to <strong>\/lib\/firmware<\/strong> in the Linux system<\/li>\n<li>The M33 core must be started by writing &#8220;<strong>start<\/strong>&#8221; into the <strong>\/sys\/class\/remoteproc\/remoteproc0\/state<\/strong> file<\/li>\n<\/ul>\n<p>You can configure VisualGDB to automate these steps via the Custom Debug Steps page of VisualGDB Project Properties:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8983\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer.png\" alt=\"\" width=\"1166\" height=\"808\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer.png 1166w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer-300x208.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer-1024x710.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer-768x532.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer-392x272.png 392w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/10-transfer-130x90.png 130w\" sizes=\"(max-width: 1166px) 100vw, 1166px\" \/><\/a><\/li>\n<li>First, add a file transfer action:<br \/>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 50%;\">File<\/td>\n<td style=\"width: 50%;\">$(TargetPath)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Remote path<\/td>\n<td style=\"width: 50%;\">\/lib\/firmware\/$(TargetFileName)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Remote machine<\/td>\n<td style=\"width: 50%;\">(hostname for the STM32MP2 device)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li>\n<pre>Then add another action to run the following script:\r\n#!\/bin\/sh\r\necho stop &gt; \/sys\/class\/remoteproc\/remoteproc0\/state\r\necho $(TargetFileName) &gt; \/sys\/class\/remoteproc\/remoteproc0\/firmware\r\necho start &gt; \/sys\/class\/remoteproc\/remoteproc0\/state<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/11-start.png\"><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8984\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/11-start.png\" alt=\"\" width=\"1488\" height=\"846\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/11-start.png 1488w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/11-start-300x171.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/11-start-1024x582.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/11-start-768x437.png 768w\" sizes=\"(max-width: 1488px) 100vw, 1488px\" \/><\/a><\/p>\n<p>You can also add a step to run &#8220;echo stop &gt; \/sys\/class\/remoteproc\/remoteproc0\/state&#8221; to the post-debugging steps to automatically stop the M33 core after you finished debugging it.<\/li>\n<li>Change the FLASH programming mode to <strong>Never<\/strong> because the Linux kernel will already load the firmware into the M33 core for you: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/12-noflash.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8985\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/12-noflash.png\" alt=\"\" width=\"1136\" height=\"562\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/12-noflash.png 1136w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/12-noflash-300x148.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/12-noflash-1024x507.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/12-noflash-768x380.png 768w\" sizes=\"(max-width: 1136px) 100vw, 1136px\" \/><\/a>Note that keeping the default FLASH programming mode may work for some projects, but will cause OpenAMP to lose synchronization between the Linux and the Cortex-M33 sides (OpenAMP will be stuck in initialization code after VisualGDB resets the M33 core).<\/li>\n<li>Press F5 to start debugging. You can then use Debug-&gt;Break All to see what code is running currently. Normally, it should be looping inside <strong>OPENAMP_check_for_message()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8986\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check.png\" alt=\"\" width=\"1158\" height=\"790\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check.png 1158w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check-1024x699.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check-768x524.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/13-check-130x90.png 130w\" sizes=\"(max-width: 1158px) 100vw, 1158px\" \/><\/a><\/li>\n<li>Set breakpoints on the lines setting <strong>VirtualUartNRxMsg<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8987\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt.png\" alt=\"\" width=\"1158\" height=\"790\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt.png 1158w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt-1024x699.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt-768x524.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/14-bkpt-130x90.png 130w\" sizes=\"(max-width: 1158px) 100vw, 1158px\" \/><\/a><\/li>\n<li>Verify that the \/dev\/ttyRPMSG0 was created on the Linux side (check the dmesg output it it hasn&#8217;t) and then try running &#8220;<strong>echo hello &gt; \/dev\/ttyRPMSG0<\/strong>&#8221; in the Linux terminal. The branch responsible for reading the channel #0 will trigger a breakpoint, showing the message that got received:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8988\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped.png\" alt=\"\" width=\"1158\" height=\"790\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped.png 1158w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped-1024x699.png 1024w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped-768x524.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2025\/03\/15-stopped-130x90.png 130w\" sizes=\"(max-width: 1158px) 100vw, 1158px\" \/><\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to build and debug the OpenAMP example on the Cortex-M33 core of the STM32MP2 device. OpenAMP<\/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":[33,250,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/8973"}],"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=8973"}],"version-history":[{"count":2,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/8973\/revisions"}],"predecessor-version":[{"id":8990,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/8973\/revisions\/8990"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=8973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=8973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=8973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}