{"id":116,"date":"2019-07-07T15:17:54","date_gmt":"2019-07-07T22:17:54","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=116"},"modified":"2021-01-12T08:40:09","modified_gmt":"2021-01-12T16:40:09","slug":"arm-semihosting","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/semihosting\/","title":{"rendered":"Using Semihosting for Debug Output with VisualGDB"},"content":{"rendered":"<p>This tutorial shows how to use semihosting to send printf()-style messages from the debugged program to VisualGDB. Semihosting is a mechanism of passing data from the debugged program to the debugger via a syscall-style interface. In this tutorial we will create a basic project that sends some debug via semihosting and explain how it works.<\/p>\n<p>You will need\u00a0<a href=\"\/download\/\">VisualGDB 4.3<\/a> or later.<\/p>\n<ol>\n<li>Begin with creating a new project with VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5089\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/01-newprj.png\" alt=\"\" width=\"1024\" height=\"710\" \/><\/a><\/li>\n<li>Select &#8220;Create a new project -&gt; Embedded binary -&gt; MSBuild&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/02-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5091\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/02-newprj.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Select your device. In this example we will use the STM32F4Discovery board. Note that the semihosting interface does not require any special hardware, so it will work with many other devices as well:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/03-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5092\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/03-device.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Select the default sample. You can specify the LED settings that match your board, or proceed with the default ones, as LEDs are not vital for this example:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/04-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5093\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/04-sample.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Specify the debug interface you are using. In this example we will use OpenOCD with ST-Link:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/05-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5094\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/05-debug.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Include the <strong>&lt;stdio.h&gt;<\/strong> file and replace the <strong>for()<\/strong> loop inside the <strong>main()<\/strong> function with the following code:\n<pre class=\"\">for (int i = 0;;i++)\r\n{\r\n    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);\r\n    printf(\"LED ON (%d)\\n\", i);\r\n    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);\r\n    printf(\"LED OFF (%d)\\n\", i);\r\n}<\/pre>\n<p>Make sure your <strong>printf()<\/strong> strings end with a &#8220;<strong>\\n<\/strong>&#8221; as the C library buffers incomplete lines to improve performance. You can override this behavior by calling <strong>setvbuf()<\/strong> or <strong>fflush()<\/strong> on <strong>stdout<\/strong>.<br \/>\nEnsure that you are using our latest ARM toolchain. Build your project by pressing <strong>Ctrl-Shift-B<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/06-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5095\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/06-built.png\" alt=\"\" width=\"1232\" height=\"802\" \/><\/a><\/li>\n<li>The default implementation of <strong>printf()<\/strong>-related syscalls will simply discard the output. In order to change this, open VisualGDB Project Properties and change the syscall implementation to &#8220;Support Semihosting&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/07-support.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5096\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/07-support.png\" alt=\"\" width=\"848\" height=\"625\" \/><\/a><\/li>\n<li>Start debugging by pressing F5. You will see the output from the <strong>printf()<\/strong> function in <strong>Debug-&gt;Windows-&gt;VisualGDB Output-&gt;ARM Semihosting Console<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/07\/semihost.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7134\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/07\/semihost.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a>If you are using VisualGDB 5.4 or earlier, the ARM Semihosting Console will be shown in a separate tool window instead of the VisualGDB Output window.<\/li>\n<li>The regular semihosting mechanism is relatively slow as it stops the CPU in order to send new data to the debugger. In order to improve the performance, VisualGDB provides its own fast semihosting framework that places the data in a memory buffer and uses background memory reads to retrieve it. Reference the fast semihosting framework via <strong>VisualGDB Project Properties -&gt; Embedded Frameworks<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/09-advanced.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5098\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/09-advanced.png\" alt=\"\" width=\"994\" height=\"718\" \/><\/a>Unless you are planning to use sampling profiler, we recommend checking the &#8220;exclude sampling profiler code&#8221; checkbox in order to improve build time and remove platform-specific profiler code that could require MCU-specific adjustments.<\/li>\n<li>If you try building the project now, it will fail with the &#8220;<strong>multiple definition of _isatty<\/strong>&#8221; error:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/multi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5099\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/multi.png\" alt=\"\" width=\"1232\" height=\"802\" \/><\/a><\/li>\n<li>This happens because both regular and fast semihosting provide their own implementation of basic syscalls used by <strong>printf()<\/strong> and other functions. In order to solve this, disable the regular semihosting via VisualGDB Project Properties:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/10-nosemi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5100\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/10-nosemi.png\" alt=\"\" width=\"994\" height=\"718\" \/><\/a><\/li>\n<li>Now you can build and run the updated project. The semihosting will work much faster as the CPU will not need to be stopped after each line:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/11-fast.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5101\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/11-fast.png\" alt=\"\" width=\"1232\" height=\"802\" \/><\/a><\/li>\n<li>VisualGDB&#8217;s semihosting console supports <a href=\"https:\/\/en.wikipedia.org\/wiki\/ANSI_escape_code\">ANSI escape codes<\/a> for moving the cursor, setting text colors, etc. E.g. you can set different colors for the &#8220;LED ON&#8221; and &#8220;LED OFF&#8221; lines using the code below:\n<pre class=\"\">enum class ConsoleColor\r\n{\r\n    Black,\r\n    Red,\r\n    Green,\r\n    Yellow,\r\n    Blue,\r\n    Magenta,\r\n    Cyan,\r\n    White\r\n};\r\n\r\nvoid SetForegroundColor(ConsoleColor color)\r\n{\r\n    printf(\"\\x1b[%dm\", 30 + (int)color);\r\n}\r\n\r\nint main()\r\n{\r\n    \/\/...\r\n    for (int i = 0;;i++)\r\n    {\r\n    \tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);\r\n        SetForegroundColor(ConsoleColor::Green);\r\n        printf(\"LED ON (%d)\\n\", i);\r\n        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET);\r\n        SetForegroundColor(ConsoleColor::Red);\r\n        printf(\"LED OFF (%d)\\n\", i);\r\n    }\r\n}\r\n<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/12-colors.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5102\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2014\/10\/12-colors.png\" alt=\"\" width=\"1232\" height=\"802\" \/><\/a><\/li>\n<\/ol>\n<p>You can also route the output of printf() to another interface (e.g UART) by redefining low-level IO functions. See the <a href=\"http:\/\/visualgdb.com\/tutorials\/arm\/semihosting\/..\/stm32\/uart\/\">UART tutorial<\/a> for details.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use semihosting to send printf()-style messages from the debugged program to VisualGDB. Semihosting is a<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[53],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/116"}],"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=116"}],"version-history":[{"count":5,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/116\/revisions"}],"predecessor-version":[{"id":7135,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/116\/revisions\/7135"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}