{"id":5615,"date":"2020-04-29T09:27:58","date_gmt":"2020-04-29T16:27:58","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=5615"},"modified":"2020-05-06T09:15:02","modified_gmt":"2020-05-06T16:15:02","slug":"using-test-resources-with-embedded-unit-test-projects","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/tests\/resources\/","title":{"rendered":"Using Test Resources with Embedded Unit Test Projects"},"content":{"rendered":"<p>This tutorial shows how to use the <a href=\"https:\/\/visualgdb.com\/reference\/semihosting\/_t_r_m_a_p_i.html\">Test Resource Manager API<\/a> to access the files in the project&#8217;s <strong>TestResources<\/strong> subdirectory from your embedded unit test projects.<\/p>\n<p>We will create a basic unit test project verifying the behavior of the <strong>sinf()<\/strong> function on the STM32F4-Discovery board and will use the test resources to feed 2 megabytes of test data into the device, that would normally not fit into the device&#8217;s memory. Before you begin, install VisualGDB 5.5 or later.<\/p>\n<ol>\n<li>Start Visual Studio and select the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5616\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/01-newprj.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Specify the name and location for your project and press &#8220;Create&#8221; to launch the VisualGDB&#8217;s portion of the wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/02-resources.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5617\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/02-resources.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>On the first page of the VisualGDB Embedded Project wizard, select &#8220;<strong>Create a new project -&gt; Unit Test -&gt; MSBuild<\/strong>&#8220;. Then pick the test framework you would like to use. In this tutorial we will use the lightweight <a href=\"https:\/\/visualgdb.com\/tutorials\/tests\/arm\/\">TinyEmbeddedTest<\/a> framework, however the steps shown here will work with other frameworks as well:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/03-testprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5618\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/03-testprj.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page of the wizard choose the device you would like to target. As we are targeting the STM32F4Discovery board, we will pick the STM32F407VG device:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/04-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5619\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/04-device.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a>Although we demonstrate the test resources on the STM32F4-Discovery board, the steps shown in this tutorial will work for any ARM-based device that supports background memory access (most ARM Cortex-based devices do). Also it is recommended to select the software floating point mode when creating the project, as we will be later comparing it against the hardware mode.<\/li>\n<li>On the next page proceed with the default sample for the TinyEmbeddedTest framework:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/05-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5620\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/05-sample.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Connect your embedded board to the USB port and let VisualGDB detect the debug configuration:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/06-stlink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5621\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/06-stlink.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally, press &#8220;Finish&#8221; to create the project. Once it is created, build it and ensure that the Test Explorer window shows the sample tests:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/07-tests.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5622\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/07-tests.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<li>Now we will add a test method that will read a stream of inputs to <strong>sinf()<\/strong> from one file on the Windows machine, a stream of outputs from another one and will compare them with the actual results produced by <strong>sinf()<\/strong>. Replace the contents of the Tests file with the following code:\n<pre class=\"\">#include &lt;TinyEmbeddedTest.h&gt;\r\n#include &lt;stdio.h&gt;\r\n#include &lt;math.h&gt;\r\n\r\n#include &lt;TestResourceManager.h&gt;\r\n\r\nTEST_GROUP(DataProcessingTestGroup)\r\n{\r\n};\r\n\r\nuint32_t g_Progress;\r\n\r\nTEST(DataProcessingTestGroup, SineTest)\r\n{\r\n    auto hInputs = TRMCreateFile(\"inputs.dat\", sfmOpenReadOnly);\r\n    auto hOutputs = TRMCreateFile(\"outputs.dat\", sfmOpenReadOnly);\r\n    uint32_t total = 0;\r\n\r\n    CHECK(hInputs != 0);\r\n    CHECK(hOutputs != 0);\r\n    float buf1[1024], buf2[1024];\r\n\r\n    for (;;)\r\n    {\r\n        ssize_t done = TRMReadFile(hInputs, buf1, sizeof(buf1));\r\n        CHECK(done &gt;= 0);\r\n\r\n        if (!done)\r\n            break;\r\n\r\n        ssize_t done2 = TRMReadFile(hOutputs, buf2, done);\r\n        CHECK_EQUAL(done, done2);\r\n        for (int i = 0; i &lt; (done \/ sizeof(buf1[0])); i++)\r\n            CHECK_EQUAL(buf2[i], sinf(buf1[i]));\r\n\r\n        total += done;\r\n        g_Progress = total;\r\n    }\r\n\r\n    CHECK(total &gt;= 1024 * 1024);\r\n\r\n    TRMCloseFile(hInputs);\r\n    TRMCloseFile(hOutputs);\r\n}<\/pre>\n<p>You can find a detailed documentation on TRMCreateFile() and other similar functions <a href=\"https:\/\/visualgdb.com\/reference\/semihosting\/_test_resource_manager_8h.html\">here<\/a>. Once you are done, build the project and start debugging the newly created test:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/08-sinetest.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5623\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/08-sinetest.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<li>If you are doing it for the first time, the test logic will freeze in the <strong>RunBlockingFastSemihostingCall()<\/strong> function. This happens because VisualGDB is not expecting the code to call the resource manager API:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/09-stuck.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5624\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/09-stuck.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<li>Stop debugging the test and open <strong>VisualGDB Project Properties<\/strong> on the <strong>Unit Tests<\/strong> page. Enable the test resources for the project via a checkbox at the bottom of the page:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/10-resources.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5625\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/10-resources.png\" alt=\"\" width=\"842\" height=\"618\" \/><\/a><\/li>\n<li>Now you will be able to run the test, however it will immediately fail due to the missing <strong>inputs.dat<\/strong> file:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/11-error.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5626\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/11-error.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<li>We could generate the test files using a simple program on the Windows side, however in this tutorial we will generate them on the target and save them to the host via the Test Resource Manager API. Locate the <strong>main()<\/strong> function in your program and modify it as shown below:\n<pre class=\"\">#include &lt;TestResourceManager.h&gt;\r\n\r\nextern uint32_t g_Progress;\r\n\r\nvoid GenerateTestData()\r\n{\r\n    auto hInputs = TRMCreateFile(\"inputs.dat\", sfmCreateOrTruncateWriteOnly);\r\n    auto hOutputs = TRMCreateFile(\"outputs.dat\", sfmCreateOrTruncateWriteOnly);\r\n\r\n    uint32_t total = 0;\r\n    float buf1[1024], buf2[1024];\r\n    float nextValue = 0;\r\n\r\n    for (int block = 0; block &lt; 256; block++)\r\n    {\r\n        for (int i = 0; i &lt; (sizeof(buf1) \/ sizeof(buf1[0])); i++)\r\n        {\r\n            buf1[i] = nextValue += 0.01F;\r\n            buf2[i] = sinf(buf1[i]);\r\n        }\r\n\r\n        ssize_t done = TRMWriteFile(hInputs, buf1, sizeof(buf1));\r\n        done = TRMWriteFile(hOutputs, buf2, sizeof(buf2));\r\n        g_Progress = block;\r\n    }\r\n\r\n    TRMCloseFile(hInputs);\r\n    TRMCloseFile(hOutputs);\r\n}\r\n\r\nint main(void)\r\n{\r\n    HAL_Init();\r\n\r\n    if (IsRunningUnitTests())\r\n    {\r\n        RunAllTests();\r\n    }\r\n    else\r\n    {\r\n        GenerateTestData();\r\n    }\r\n    return 0;\r\n}<\/pre>\n<p>Note how <strong>GenerateTestData()<\/strong> is only called when no unit tests are running (i.e. when a debug session was started via Debug-&gt;Start Debugging). Set a breakpoint near a call to TRMWriteFile() and start a regular debug session by pressing F5. Once the breakpoint hits, add <strong>g_Progress<\/strong> to the Live Variables window:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/12-progress.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5627\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/12-progress.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<li>Resume the debug session. You can now track the progress of the test file generation via the Live Variables view:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/13-running-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5633\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/13-running-1.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a>When the counter stops updating, end the debug session and verify that the <strong>inputs.dat<\/strong> and <strong>outputs.dat<\/strong> files have been created in the <strong>TestResources<\/strong> directory and have the correct size:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/files.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5637\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/files.png\" alt=\"\" width=\"805\" height=\"387\" \/><\/a>You can also add <strong>asm(&#8220;bkpt 255&#8221;)<\/strong> line to the end of <strong>GenerateTestData()<\/strong> to explicitly trigger a breakpoint when the test data has been generated.<\/li>\n<li>Now you can start the <strong>SineTest<\/strong> again. This time it will be able to read the <strong>inputs.dat<\/strong> and <strong>outputs.dat<\/strong> and will succeed:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/14-passed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5629\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/14-passed.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a>Note that the test resource files will be saved in the <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/TestResourcesDemo\/TestResources\">TestResources subdirectory<\/a> inside your project&#8217;s directory on the Windows machine.<\/li>\n<li>Open VisualGDB Project Properties and switch the <strong>Floating Point<\/strong> setting to <strong>Hardware<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/15-hwfloat.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5630\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/15-hwfloat.png\" alt=\"\" width=\"893\" height=\"741\" \/><\/a><\/li>\n<li>Build the project and start running the test again. It will now fail due to minor differences between hardware and software floating point implementation:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/16-error.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5631\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/16-error.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<li>In order to do a more meaningful comparison, replace the strict check of the sinf() output with the following code:\n<pre class=\"\">        for (int i = 0; i &lt; (done \/ sizeof(buf1[0])); i++)\r\n        {\r\n            float error = fabsf(buf2[i] - sinf(buf1[i]));\r\n            CHECK(error &lt; 0.001F);\r\n        }<\/pre>\n<p>Instead of comparing the returned value bit-by-bit (that won&#8217;t work due to different rounding and encoding used in different FP implementations), it will make sure that the difference between the values does not exceed the acceptable margin. The <strong>SineTest<\/strong> will now succeed:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/17-faster.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5632\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/17-faster.png\" alt=\"\" width=\"1224\" height=\"821\" \/><\/a><\/li>\n<\/ol>\n<p>You can find the code for the project shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/TestResourcesDemo\">GitHub repository<\/a>.<\/p>\n<p>If your test depends on transferring large amounts of data, make sure you use the <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/tests\/resources\/bursts\/\">TRM Burst API<\/a> to optimize it even further.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use the Test Resource Manager API to access the files in the project&#8217;s TestResources subdirectory<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[128],"tags":[53,133,168,129],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5615"}],"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=5615"}],"version-history":[{"count":5,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5615\/revisions"}],"predecessor-version":[{"id":6005,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5615\/revisions\/6005"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=5615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=5615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=5615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}