{"id":6588,"date":"2020-09-17T09:39:31","date_gmt":"2020-09-17T16:39:31","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=6588"},"modified":"2020-10-23T08:29:28","modified_gmt":"2020-10-23T15:29:28","slug":"creating-simulation-platforms-to-test-embedded-code-without-hardware","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/cmake\/simulation\/","title":{"rendered":"Creating Simulation Platforms to Test Embedded Code without Hardware"},"content":{"rendered":"<p>This tutorial shows how to run high-level code of embedded projects directly on Windows in order to speed up development and tests. We will create a unit test project based on the <a href=\"https:\/\/visualgdb.com\/documentation\/tests\/TinyEmbeddedTest\/\">TinyEmbeddedTest framework<\/a>, will run the tests on the STM32F4 Discovery board, and will then create a separate simulation platform to run the tests directly on Windows.<\/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\/08\/01-newprj-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6589\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/01-newprj-1.png\" alt=\"\" width=\"966\" height=\"624\" \/><\/a><\/li>\n<li>Enter the name and location of your project: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/02-name-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6590\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/02-name-1.png\" alt=\"\" width=\"966\" height=\"624\" \/><\/a><\/li>\n<li>On the first page of the VisualGDB Project Wizard select &#8220;Unit Test -&gt; Advanced CMake&#8221;. Make sure you are using the <strong>TinyEmbeddedTest<\/strong> or <strong>GoogleTest<\/strong> framework, as other frameworks do not support portability between Windows and embedded targets: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/03-test.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6591\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/03-test.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a>If you are using Keil or IAR, start with creating a regular embedded CMake project and then reference the test framework (e.g. see <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/iar\/tests\/\">this tutorial<\/a>).<\/li>\n<li>Select the toolchain and device you would like to target and press &#8220;Next&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/04-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6592\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/04-device.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Pick the basic test sample and proceed to the next page: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/05-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6593\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/05-sample.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally, select the debug settings that work with your target and click &#8220;Finish&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/06-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6594\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/06-debug.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>VisualGDB will create a CMake-based unit test project for the selected device. Try building it, and once the tests are discovered, run them via Test-&gt;Run All Tests: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/07-run.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6595\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/07-run.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>VisualGDB will display the test outcome in the Test Explorer window: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/08-done.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6596\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/08-done.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>The previous command ran the tests directly on the hardware, limiting the speed and the amount of available memory (you can still use <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/tests\/resources\/\">Test Resources<\/a> to feed large data streams into the device). Now we will create a separate VS platform to run the tests directly on Windows. Right-click on the project node in Solution Explorer (CMake icon) and select &#8220;Add a Simulation Platform&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/09-sim.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6597\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/09-sim.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>VisualGDB will ask you for a MinGW-based toolchain (can be installed automatically), the name of the simulation platform, and will offer renaming the regular platform from &#8220;VisualGDB&#8221; to &#8220;hardware&#8221;. Press &#8220;OK&#8221; to confirm the platform names: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/10-platform.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6598\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/10-platform.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>Once the platform is created, switch to it via the VS Platform selector. Note that if you try building the project now, it will fail due to missing STM32-specific headers:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/11-loaded-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6605\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/11-loaded-1.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>This happens because the simulation platform does not emulate any target-specific hardware. Instead, it provides an easy way to build the high-level code with MinGW (GCC for Windows), relying on your own abstraction layer. In this example we will resolve the errors by wrapping STM32-specific code with <strong>#ifndef SIMULATION. <\/strong>You can also prevent STM32-specific files (e.g. <strong>system_stm32f4xx.c<\/strong>) from building via the &#8220;Exclude from Build&#8221; command (we will show how to make the exclusion conditional later):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/12-exclude.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6600\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/12-exclude.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><strong>WARNING: If you are using GoogleTest, update the main() function to pass the command-line arguments to InitGoogleTest() as shown <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/blob\/master\/visualgdb\/ARM\/CMake\/EmbeddedSimulationDemo\/GoogleTest\/EmbeddedSimulationDemo.cpp\">here<\/a>.<\/strong><\/li>\n<li>Now you will be able to build the project and run unit tests:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/13-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6601\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/13-built.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a>If the tests do not appear in Test Explorer, try closing and reopening the solution to reset any VS-level caches.<\/li>\n<li>The tests will work the same way as they do for embedded targets, as long as they don&#8217;t include any hardware-specific code:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/14-fail.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6602\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/14-fail.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>If you try building the hardware platform now, it will fail because we have excluded the <strong>system_stm32f4xx.c<\/strong> file from building. To make the exclusion conditional, locate the <strong>set_source_file_properties()<\/strong> statement in <strong>CMakeLists.txt<\/strong> and wrap it with <strong>if(SIMULATION)\/endif()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/15-condition.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6603\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/15-condition.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>If you would like to run some tests only on hardware (or only on simulation), you can always move them into a separate test executable. Right-click on the project node in Solution Explorer and select <strong>Add-&gt;New Item<\/strong>. Then select <strong>&#8220;Embedded Executable&#8221;<\/strong>: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/16-another.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6606\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/16-another.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>Right-click on the executable and select <strong>Add-&gt;Add Reference<\/strong>. Then reference the test framework:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/17-refs.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6607\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/17-refs.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>Replace the contents of the main source file with the following code:\n<pre class=\"\">#include &lt;TinyEmbeddedTest.h&gt;\r\n\r\nTEST_GROUP(AnotherTestGroup)\r\n{\r\n};\r\n\r\nTEST(AnotherTestGroup, AnotherTest)\r\n{\r\n}\r\n\r\nint main()\r\n{\r\n    RunAllTests();\r\n    return 0;\r\n}<\/pre>\n<\/li>\n<li>Then right-click on the executable and select &#8220;Disable for Current Platform&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/19-disable.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6608\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/19-disable.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a><\/li>\n<li>This will prevent <strong>AnotherTestExecutable <\/strong>from being built on the <strong>Hardware<\/strong> platform (see the <strong>EXCLUDED_PLATFORMS<\/strong> parameter <strong>CMakeLists.txt)<\/strong>, but will still let you build and run the tests declared in it using the Simulation platform:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/20-tested.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6610\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/08\/20-tested.png\" alt=\"\" width=\"1505\" height=\"949\" \/><\/a>If you would like to add code for simulating some STM32-specific peripherals, we advise placing it into a separate static library and disabling it for the <strong>Hardware<\/strong> platform. Disabled libraries will remain in Solution Explorer (so you can reference them unconditionally), but will not build any source files unless you switch to a supported platform.<\/li>\n<li>Finally, we will show how to build and run Embedded CMake test projects outside Visual Studio so that you can integrate them into your Continuous Integration environment. Open the Windows command prompt in the project directory and run the following command lines:\n<pre class=\"\">\"%VISUALGDB_DIR%\\VisualGDB.exe\" \/build EmbeddedSimulationDemo.vgdbcmake \/platform:Hardware \/config:Debug\r\n\"%VISUALGDB_DIR%\\VisualGDB.exe\" \/build EmbeddedSimulationDemo.vgdbcmake \/platform:Simulation \/config:Debug<\/pre>\n<p>The first command line will build the unit tests for the hardware platform, while the second one will build Win32 executables using the MinGW toolchain:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/09\/built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6698\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/09\/built.png\" alt=\"\" width=\"979\" height=\"512\" \/><\/a><\/li>\n<li>Once the project is built, you can run all tests in a specific executable using the following command line:\n<pre class=\"\">\"%VISUALGDB_DIR%\\VisualGDB.exe\" \/runtests EmbeddedSimulationDemo.vgdbcmake \/platform:Simulation \/config:Debug \/targetpath:build\\Simulation\\Debug\\EmbeddedSimulationDemo.exe \/vsoutput:results.trx<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/09\/run.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6700\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/09\/run.png\" alt=\"\" width=\"979\" height=\"512\" \/><\/a>Note that when running tests from Visual Studio, VisualGDB will query CMake for the detailed project structure, and will then determine the paths to the built executables from it. This step is skipped when running tests from command line, so the exact path to the built executable needs to be specified via the <strong>\/targetpath<\/strong> parameter. If you would like to run tests from multiple executables (e.g. <strong>EmbeddedSimulationDemo.exe<\/strong> vs. <strong>AnotherTestExecutable.exe<\/strong>), simply invoke VisualGDB.exe multiple times, specifying a different target path each time.<\/li>\n<li>You can also run the tests directly on the hardware using the command line shown below:\n<pre class=\"\">\"%VISUALGDB_DIR%\\VisualGDB.exe\" \/runtests EmbeddedSimulationDemo.vgdbcmake \/platform:Hardware \/config:Debug \/targetpath:build\\Hardware\\Debug\\EmbeddedSimulationDemo \/vsoutput:results.trx<\/pre>\n<p>The results will be saved into the <strong>results.trx<\/strong> file compatible with the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/tasks\/test\/publish-test-results?view=azure-devops&amp;tabs=yaml\">test results files<\/a> produced by Visual Studio itself.<\/li>\n<\/ol>\n<p>You can find the source code of the project shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/CMake\/EmbeddedSimulationDemo\">Github repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to run high-level code of embedded projects directly on Windows in order to speed up development<\/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":[77,133,223,61,129],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6588"}],"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=6588"}],"version-history":[{"count":7,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6588\/revisions"}],"predecessor-version":[{"id":7051,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6588\/revisions\/7051"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=6588"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=6588"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=6588"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}