{"id":3508,"date":"2017-12-13T10:18:48","date_gmt":"2017-12-13T18:18:48","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=3508"},"modified":"2017-12-13T10:18:48","modified_gmt":"2017-12-13T18:18:48","slug":"developing-embedded-gui-using-stemwin-library","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/stemwin\/","title":{"rendered":"Developing Embedded GUI using STemWin Library"},"content":{"rendered":"<p>This tutorial shows how to create a basic GUI application for the STM32F429I-Discovery board using the STemWin library. We will start with a basic example shipped with the STM32 SDK, will show how to locate different demos inside it and will create a basic demo using the TreeView control to show how the message handling works.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/01-prjname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3509\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/01-prjname.png\" alt=\"01-prjname\" width=\"849\" height=\"532\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/01-prjname.png 849w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/01-prjname-300x188.png 300w\" sizes=\"(max-width: 849px) 100vw, 849px\" \/><\/a><\/li>\n<li>Proceed with the default &#8220;Create a new MSBuild project&#8221; options:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/02-msbuild.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3510\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/02-msbuild.png\" alt=\"02-msbuild\" width=\"822\" height=\"642\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/02-msbuild.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/02-msbuild-300x234.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>On the next page select the ARM toolchain and choose your device. In this tutorial we will use the STM32F429-Discovery board with an on-board LCD screen, so we select the STM32F429ZI device:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/03-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3511\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/03-device.png\" alt=\"03-device\" width=\"822\" height=\"642\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/03-device.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/03-device-300x234.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>On the next page select &#8220;Show STM32 CubeMX Samples&#8221;. Search for &#8220;STemWin&#8221; to locate STemWin samples for your board:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/04-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3512\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/04-sample.png\" alt=\"04-sample\" width=\"822\" height=\"642\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/04-sample.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/04-sample-300x234.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Connect your board to the computer via USB so that VisualGDB automatically detects it and select your ST-Link in the &#8220;Debug using&#8221; field:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/05-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3513\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/05-debug.png\" alt=\"05-debug\" width=\"822\" height=\"642\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/05-debug.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/05-debug-300x234.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to create the project. VisualGDB will generate a project based on the STemWin sample. Build it start :<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/06-main.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3514\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/06-main.png\" alt=\"06-main\" width=\"1123\" height=\"739\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/06-main.png 1123w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/06-main-300x197.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/06-main-1024x674.png 1024w\" sizes=\"(max-width: 1123px) 100vw, 1123px\" \/><\/a><\/li>\n<li>Calibrate the on-board screen and wait for the radial menu demo to appear:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/radial1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3523\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/radial1.jpg\" alt=\"radial\" width=\"700\" height=\"1188\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/radial1.jpg 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/radial1-177x300.jpg 177w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/radial1-603x1024.jpg 603w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>Press the &#8220;break all&#8221; button in Visual Studio and use the Call Stack window to navigate to the <strong>_Main()<\/strong> function. See how it is looping through the tests defined in _GUIDemoConfig.apFunc:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/07-call.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3515\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/07-call.png\" alt=\"07-call\" width=\"1123\" height=\"739\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/07-call.png 1123w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/07-call-300x197.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/07-call-1024x674.png 1024w\" sizes=\"(max-width: 1123px) 100vw, 1123px\" \/><\/a><\/li>\n<li>You can use the Code Map powered by VisualGDB Clang IntelliSense to quickly locate the function responsible for filling the apFunc array: <strong>GUIDemo_Config()<\/strong>. The function reads the list of tests from the global <strong>_apfTest<\/strong> variable and writes them to apFunc:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/08-map.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3516\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/08-map.png\" alt=\"08-map\" width=\"1123\" height=\"739\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/08-map.png 1123w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/08-map-300x197.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/08-map-1024x674.png 1024w\" sizes=\"(max-width: 1123px) 100vw, 1123px\" \/><\/a><\/li>\n<li>Double-click on <strong>_apfTest<\/strong> and go to its definition. Hover the mouse over it to see the list of tests actually included in the build:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/09-funcs.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3517\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/09-funcs.png\" alt=\"09-funcs\" width=\"1123\" height=\"739\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/09-funcs.png 1123w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/09-funcs-300x197.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/09-funcs-1024x674.png 1024w\" sizes=\"(max-width: 1123px) 100vw, 1123px\" \/><\/a><\/li>\n<li>One of the tests shown in the list is GUIDEMO_Treeview. Locate the corresponding file in Solution Explorer and open it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/10-treeview.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3518\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/10-treeview.png\" alt=\"10-treeview\" width=\"1123\" height=\"739\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/10-treeview.png 1123w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/10-treeview-300x197.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/10-treeview-1024x674.png 1024w\" sizes=\"(max-width: 1123px) 100vw, 1123px\" \/><\/a><\/li>\n<li>The demo creates a basic tree view using the <strong>TREEVIEW_CreateIndirect()<\/strong> function and fills it with sample items. We will now create a new demo based on it to show the basic usage of STemWin. Create a new file called <strong>Experiments.cpp<\/strong> and add the following code there:\n<pre class=\"\">#include \"main.h\"\r\n#include \"rtc.h\"\r\n#include \"GUIDEMO.h\"\r\n#include \"WM.h\"\r\nstatic bool s_bDone;\r\n\r\nextern \"C\" void RunExperiments()\r\n{\r\n\u00a0\u00a0\u00a0 WM_HWIN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hWin, hClient, hTree;\r\n\u00a0\u00a0\u00a0 int\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 xSize, ySize, xSizeClient, ySizeClient;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 GUI_WIDGET_CREATE_INFO controlList[] = {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 { FRAMEWIN_CreateIndirect, \"Explorer\", 0, 0, 0, 0, 0 },\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 { TREEVIEW_CreateIndirect, NULL, GUI_ID_TREEVIEW0, 0, 0, 0, 0 },\r\n\u00a0\u00a0\u00a0 };\r\n\r\n\u00a0\u00a0\u00a0 xSize\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = LCD_GetXSize();\r\n\u00a0\u00a0\u00a0 ySize\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = LCD_GetYSize();\r\n\u00a0\u00a0\u00a0 controlList[0].xSize = xSize \/ 2;\r\n\u00a0\u00a0\u00a0 controlList[0].ySize = ySize;\r\n\u00a0\u00a0\u00a0 controlList[1].xSize = xSize \/ 2;\r\n\u00a0\u00a0\u00a0 controlList[1].ySize = ySize;\r\n\u00a0\u00a0\u00a0 hWin\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = GUI_CreateDialogBox(controlList, GUI_COUNTOF(controlList), DialogCallback, WM_HBKWIN, 0, 0);\r\n\u00a0\u00a0\u00a0 hClient\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = WM_GetClientWindow(hWin);\r\n\u00a0\u00a0\u00a0 xSizeClient\u00a0\u00a0\u00a0\u00a0\u00a0 = WM_GetWindowSizeX(hClient);\r\n\u00a0\u00a0\u00a0 ySizeClient\u00a0\u00a0\u00a0\u00a0\u00a0 = WM_GetWindowSizeY(hClient);\r\n\u00a0\u00a0\u00a0 hTree\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = WM_GetDialogItem(hWin, GUI_ID_TREEVIEW0);\r\n\u00a0\u00a0\u00a0 WM_SetSize(hTree, xSizeClient, ySizeClient);\r\n\r\n\u00a0\u00a0\u00a0 while (!s_bDone)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GUI_Exec();\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 WM_DeleteWindow(hWin);\r\n}<\/pre>\n<p>The code creates a basic window in the left half of the screen that will consist of a basic window frame and a tree view. STemWin uses messages and functions similar to the native Win32 API functions for managing windows. Once your application creates all the GUI elements, it should call GUI_Exec() in a loop.<\/li>\n<li>Add a DialogCallback function similar to the Win32 dialog function that will handle the WM_INIT_DIALOG and WM_NOTIFY_PARENT messages:\n<pre class=\"\">static void DialogCallback(WM_MESSAGE * pMsg) \r\n{\r\n\u00a0\u00a0\u00a0 WM_HWIN hItem, hDlg;\r\n\u00a0\u00a0\u00a0 hDlg = pMsg-&gt;hWin;\r\n\u00a0\u00a0\u00a0 switch (pMsg-&gt;MsgId)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0 case WM_INIT_DIALOG:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hItem = WM_GetDialogItem(hDlg, GUI_ID_TREEVIEW0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PopulateTreeView(hItem);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0 case WM_NOTIFY_PARENT:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 switch (pMsg-&gt;Data.v)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case WM_NOTIFICATION_CLICKED:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (WM_GetId(pMsg-&gt;hWinSrc) == GUI_ID_TREEVIEW0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WM_HWIN hItem = TREEVIEW_GetSel(pMsg-&gt;hWinSrc);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 unsigned char tmp[32];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TREEVIEW_ITEM_GetText(hItem, tmp, sizeof(tmp));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"%s\\n\", tmp);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<\/li>\n<li>Finally add a PopulateTreeView() function that will create 2 levels of items in the tree view: 3 books with 5 pages in each book:\n<pre class=\"\">static void PopulateTreeView(WM_HWIN hTree)\r\n{\r\n\u00a0\u00a0\u00a0 TREEVIEW_ITEM_Handle hBook, hPage;\r\n\u00a0\u00a0\u00a0 char tmp[128];\r\n\u00a0\u00a0\u00a0 for (int i = 0; i &lt; 3; i++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sprintf(tmp, \"Book %d\", i);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!i)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hBook = TREEVIEW_InsertItem(hTree, TREEVIEW_ITEM_TYPE_NODE, 0, 0, tmp);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hBook = TREEVIEW_InsertItem(hTree, TREEVIEW_ITEM_TYPE_NODE, hBook, TREEVIEW_INSERT_BELOW, tmp);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for (int j = 0; j &lt; 5; j++)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sprintf(tmp, \"Page %d\", j);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!j)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hPage = TREEVIEW_InsertItem(hTree, TREEVIEW_ITEM_TYPE_LEAF, hBook, TREEVIEW_INSERT_FIRST_CHILD, tmp);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hPage = TREEVIEW_InsertItem(hTree, TREEVIEW_ITEM_TYPE_LEAF, hPage, TREEVIEW_INSERT_BELOW, tmp);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 TREEVIEW_SetAutoScrollH(hTree, 1);\r\n\u00a0\u00a0\u00a0 TREEVIEW_SetAutoScrollV(hTree, 1);\r\n\u00a0\u00a0\u00a0 TREEVIEW_ITEM_Expand(TREEVIEW_GetItem(hTree, 0, TREEVIEW_GET_FIRST));\r\n\u00a0\u00a0\u00a0 WM_SetFocus(hTree);\r\n}<\/pre>\n<\/li>\n<li>In order to see the output from <strong>printf() <\/strong>you need to enable semihosting (mechanism for sending text from the program to the debugger). You can do this via the first page of VisualGDB Project Properties:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/11-semihost.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3519\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/11-semihost.png\" alt=\"11-semihost\" width=\"1059\" height=\"755\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/11-semihost.png 1059w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/11-semihost-300x214.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/11-semihost-1024x730.png 1024w\" sizes=\"(max-width: 1059px) 100vw, 1059px\" \/><\/a><\/li>\n<li>Now you can build the program and start it by pressing F5. Check the screen on your board to see the tree view:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/treeview.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3524\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/treeview.jpg\" alt=\"treeview\" width=\"700\" height=\"1250\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/treeview.jpg 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/treeview-168x300.jpg 168w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/treeview-573x1024.jpg 573w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>Try tapping on some of the elements and observe the ARM Semihosting Console window in Visual Studio: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/12-run.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3520\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/12-run.png\" alt=\"12-run\" width=\"1123\" height=\"739\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/12-run.png 1123w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/12-run-300x197.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/12-run-1024x674.png 1024w\" sizes=\"(max-width: 1123px) 100vw, 1123px\" \/><\/a><\/li>\n<li>Normally each semihosting call (i.e. a call to <strong>printf()<\/strong>) requires the debugger to handle an interrupt, read memory and resume the program, resulting in noticeable delays. You can reduce them by enabling the fast semihosting framework via VisualGDB Project Properties:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/13-fast.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3521\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/13-fast.png\" alt=\"13-fast\" width=\"786\" height=\"594\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/13-fast.png 786w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2017\/11\/13-fast-300x227.png 300w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/a>Fast semihosting will use a ring buffer inside the device memory to send the data to the debugger non-stop, greatly improving the performance.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create a basic GUI application for the STM32F429I-Discovery board using the STemWin library. We will<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[90],"tags":[154,99,155,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/3508"}],"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=3508"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/3508\/revisions"}],"predecessor-version":[{"id":3525,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/3508\/revisions\/3525"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=3508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=3508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=3508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}