{"id":6958,"date":"2021-01-20T14:37:56","date_gmt":"2021-01-20T22:37:56","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=6958"},"modified":"2021-01-20T14:37:56","modified_gmt":"2021-01-20T22:37:56","slug":"adding-linux-platforms-to-advanced-embedded-projects","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/cmake\/linux\/","title":{"rendered":"Adding Linux Platforms to Advanced Embedded Projects"},"content":{"rendered":"<p>This tutorial shows how to add Linux platforms to Advanced CMake-based embedded projects in order to target both barebone and Linux-based devices from the same project.<\/p>\n<p>We will create a basic &#8220;Blinking LED&#8221; application for the STM32H747I-Discovery board and will then add a Linux platform for targeting Raspberry Pi using a cross-toolchain.<\/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\/2020\/10\/01-newprj-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6914\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/01-newprj-3.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Enter the name and location of the project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/01-prjname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6959\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/01-prjname.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Select &#8220;<strong>Create a new project -&gt; Embedded Application -&gt; Advanced CMake<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/02-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6960\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/02-cmake.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page of the wizard select the ARM toolchain and the target device. In this tutorial we will use the STM32H747XI device, however the steps shown here will also work with other devices as well:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/03-device-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6961\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/03-device-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Select the basic &#8220;LEDBlink (HAL)&#8221; sample and click &#8220;Next&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/04-blink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6962\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/04-blink.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally, pick debugging settings that work for your board and click &#8220;Finish&#8221; to generate the project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/05-debug-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6963\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/05-debug-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>VisualGDB will generate a basic &#8220;Blinking LED&#8221; project for your target. The project will include the <strong>main()<\/strong> function, as well as the STM32-specific hardware drivers (HAL): <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/06-built-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6964\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/06-built-1.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>To demonstrate very basic portability between STM32 and Linux, we will modify the main file to print some text using the <strong>printf()<\/strong> call. For optimal <strong>printf()<\/strong> performance on STM32, open <strong>VisualGDB Project Properties<\/strong> and reference the <strong>Fast Semihosting and Embedded Profiler<\/strong> framework:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/07-semihost.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6965\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/07-semihost.png\" alt=\"\" width=\"967\" height=\"694\" \/><\/a><\/li>\n<li>If you have not included the <strong>&lt;stdio.h&gt;<\/strong> file before, calling <strong>printf()<\/strong> will result in an error, however VisualGDB can automatically find the missing header:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/08-printf.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6966\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/08-printf.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Once you click &#8220;Include&#8221;, VisualGDB will automatically include <strong>&lt;stdio.h&gt;<\/strong> from the main source file and the code will build: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/09-include.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6967\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/09-include.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Update the main loop to print &#8220;<strong>Iteration &lt;number&gt;<\/strong>&#8221; messages and press F5 to test it out:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/10-semihost.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6968\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/10-semihost.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Now we will show how to create a Linux platform to run the same code on Raspberry Pi. Open <strong>VisualGDB Project Properties<\/strong> and click the &#8220;Manage&#8221; button near the configuration list:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/11-manage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6969\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/11-manage.png\" alt=\"\" width=\"967\" height=\"694\" \/><\/a><\/li>\n<li>In the platform\/configuration manager, remove the <strong>MinSizeRel<\/strong> and <strong>RelWithDebInfo<\/strong> configurations, then click &#8220;Add a new Linux-based platform&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/12-linux.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6970\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/12-linux.png\" alt=\"\" width=\"1059\" height=\"778\" \/><\/a><\/li>\n<li>Rename the platform to &#8220;Linux&#8221; and make sure it has separate <strong>Project<\/strong>, <strong>Build<\/strong> and <strong>Debug<\/strong> settings. In order to allow distinguishing between Embedded and Linux platforms in <strong>CMakeLists.txt<\/strong>, add the <strong>USE_LINUX<\/strong> definition to it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/13-def.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6971\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/13-def.png\" alt=\"\" width=\"1059\" height=\"778\" \/><\/a><\/li>\n<li>Click &#8220;OK&#8221; to apply the changes. Go to the Project Settings page of VisualGDB Project Properties and select the machine where you would like to build and deploy the application. In this tutorial we will build the code on Windows using a cross-toolchain, however you can also build it directly on Raspberry Pi: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/14-raspi-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6982\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/14-raspi-1.png\" alt=\"\" width=\"1084\" height=\"737\" \/><\/a><\/li>\n<li>Go to the CMake Build Settings page and select a toolchain compatible with Raspberry Pi. If you are building on the target, also update the <strong>CMake<\/strong> and <strong>Ninja<\/strong> commands to use valid paths on the Raspberry Pi itself:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/15-toolchain-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6983\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/15-toolchain-1.png\" alt=\"\" width=\"1084\" height=\"737\" \/><\/a><\/li>\n<li>Go to the Debug Settings page and make sure the project is configured to debug <strong>$(TargetPath)<\/strong> or <strong>$(SelectedCMakeTarget)<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/15a-debug-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6984\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/15a-debug-1.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Press &#8220;OK&#8221; to apply the new settings. Now you can switch the current Visual Studio platform to &#8220;Linux&#8221;. This will very likely cause a configuration error, because the <strong>find_bsp()<\/strong> statement is only supported for embedded targets:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/16-error.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6975\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/16-error.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>You can work around it by making the LinuxPlatformDemo definition conditional:\n<pre class=\"\">if (USE_LINUX)\r\nadd_executable(LinuxPlatformDemo LinuxPlatformDemo.cpp)\r\nelse()\r\nfind_bsp(...)\r\nendif()<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/17-fixed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6976\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/17-fixed.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>In order to build our application for Linux, we will need to make the STM32-specific code conditional. Open VS properties for the application target and add &#8220;USE_LINUX&#8221; to preprocessor definitions: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/18-macro.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6977\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/18-macro.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Make sure the <strong>target_compile_definitions()<\/strong> statement adding it ends up inside the <strong>if(USE_LINUX)<\/strong> condition. This ensures that the macro will only be defined when using the &#8220;Linux&#8221; platform defining <strong>USE_LINUX<\/strong> on CMake level:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/19-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6978\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/19-cmake.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Now you can wrap STM32-specific code with <strong>#ifdef USE_LINUX<\/strong> and the code will build:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/21-output.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6980\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/21-output.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<li>Switching back to the &#8220;VisualGDB&#8221; platform will build the code for the STM32 target again:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/22-emb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6981\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/22-emb.png\" alt=\"\" width=\"1193\" height=\"873\" \/><\/a><\/li>\n<\/ol>\n<p>You can improve the code reuse between Linux and barebone targets by refactoring platform-specific code into a separate abstraction layer, and using the abstractions from the main code. See our <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/cmake\/multitarget\/\">tutorial on multi-target embedded projects<\/a> for more details.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to add Linux platforms to Advanced CMake-based embedded projects in order to target both barebone and<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[222],"tags":[223,84],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6958"}],"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=6958"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6958\/revisions"}],"predecessor-version":[{"id":6985,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6958\/revisions\/6985"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=6958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=6958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=6958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}