{"id":8794,"date":"2016-08-15T05:10:49","date_gmt":"2016-08-15T04:10:49","guid":{"rendered":"https:\/\/sysprogs.com\/w\/?p=8794"},"modified":"2016-08-15T05:10:49","modified_gmt":"2016-08-15T04:10:49","slug":"introducing-the-new-real-time-watch","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/w\/introducing-the-new-real-time-watch\/","title":{"rendered":"Introducing the new Real-time Watch"},"content":{"rendered":"<p>One of the toughest types of problems faced by embedded software developers is timing problems. Seeing what exactly happened before a problem popped up and being able to put multiple events on one scale could save hours of time. The previous version of VisualGDB included an <a href=\"http:\/\/visualgdb.com\/tutorials\/profiler\/embedded\/instrumentation\/\">embedded profiler<\/a> that could\u00a0collect\u00a0statistics on the runtime\u00a0of various functions. VisualGDB 5.2 takes this even further and introduces\u00a0<strong>Real-time watch<\/strong> &#8211; a framework for convenient recording and visualization of various real-time events in your program\u00a0that\u00a0works out-of-the-box with FreeRTOS and supports non-RTOS environments as well:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/rtw.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8797\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/rtw.png\" alt=\"rtw\" width=\"845\" height=\"364\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/rtw.png 845w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/rtw-300x129.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/rtw-768x331.png 768w\" sizes=\"(max-width: 845px) 100vw, 845px\" \/><\/a><\/p>\n<p><!--more--><\/p>\n<h2>Supported platforms<\/h2>\n<p>Real-time watch works with any\u00a0ARM Cortex\u00a0microcontroller that can be debugged with either OpenOCD or Segger J-Link software.\u00a0It consists of a transparent framework that\u00a0sends timing information to VisualGDB over JTAG\/SWD and a\u00a0set of GUI\u00a0in VisualGDB that allows easily selecting what information to collect and presents it in a understandable form.<\/p>\n<h2>Setup<\/h2>\n<p>We have made Real-time watch extremely easy to setup. Simply go to the Dynamic Analysis page of VisualGDB Project Properties and enable\u00a0it for the event types you want to trace:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/properties.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8798\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/properties.png\" alt=\"properties\" width=\"996\" height=\"737\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/properties.png 996w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/properties-300x222.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/properties-768x568.png 768w\" sizes=\"(max-width: 996px) 100vw, 996px\" \/><\/a>In the pre-release version you will need to add the USE_FREERTOS macro to project properties (if you are using FreeRTOS) and call the initalization function from your main(), but once we\u00a0update our BSPs for the most popular platforms, this will be done automatically.<\/p>\n<p>Enabling real-time watch will\u00a0automatically add a reference to the Fast Semihosting and Profiler framework:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/framework.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8799\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/framework.png\" alt=\"framework\" width=\"916\" height=\"623\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/framework.png 916w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/framework-300x204.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/framework-768x522.png 768w\" sizes=\"(max-width: 916px) 100vw, 916px\" \/><\/a><\/p>\n<p>The framework itself won&#8217;t\u00a0interfere with your program&#8217;s workflow unless you explicitly enable Visual Watch, but enabling it\u00a0will automatically\u00a0activate its full power\u00a0of recording and displaying what is going on in your program.<\/p>\n<h2>Viewing function timing<\/h2>\n<p>Let&#8217;s start with something easy. Create a basic &#8220;Blinking LED&#8221; project, enable real-time watch in the VisualGDB Project Properties and get a nice graphical representation\u00a0of the\u00a0interrupt handler, delay function and the function that toggles the LED.<\/p>\n<p>Once you enabled it on the Dynamic Analysis page, simply start a normal debugging session, let it stop at a breakpoint, open the Real-time watch window and add the <strong>HAL_Delay<\/strong>, <strong>HAL_GPIO_WritePin<\/strong> and <strong>SysTick_Handler<\/strong> functions there:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/add.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8800\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/add.png\" alt=\"add\" width=\"967\" height=\"715\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/add.png 967w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/add-300x222.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/add-768x568.png 768w\" sizes=\"(max-width: 967px) 100vw, 967px\" \/><\/a><\/p>\n<p>VisualGDB will automatically do the instrumentation magic and once you hit F5 it will begin plotting the function run time in the real-time watch window:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/blink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8801\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/blink.png\" alt=\"blink\" width=\"831\" height=\"206\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/blink.png 831w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/blink-300x74.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/blink-768x190.png 768w\" sizes=\"(max-width: 831px) 100vw, 831px\" \/><\/a><\/p>\n<p>That&#8217;s exactly what would expect: <strong>HAL_Delay()<\/strong> taking most of the time, <strong>HAL_GPIO_WritePin()<\/strong> getting called every 500 ms, timer interrupt firing all the time. The window is fully interactive, so you can zoom in\/out and\u00a0measure precise\u00a0timing of various events:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/zoomin.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8802\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/zoomin.png\" alt=\"zoomin\" width=\"911\" height=\"206\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/zoomin.png 911w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/zoomin-300x68.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/zoomin-768x174.png 768w\" sizes=\"(max-width: 911px) 100vw, 911px\" \/><\/a>Tracing every call of a function that gets executed too often can create a considerable overhead, so we made it easy to estimate and manage\u00a0it. First\u00a0of all, the statistics button displays the estimated overhead:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/overhead.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8803\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/overhead.png\" alt=\"overhead\" width=\"806\" height=\"208\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/overhead.png 806w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/overhead-300x77.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/overhead-768x198.png 768w\" sizes=\"(max-width: 806px) 100vw, 806px\" \/><\/a><\/p>\n<p>Second of all, VisualGDB goes smart about instrumenting the functions, so if you pause the recording for some of them, or remove them from Visual \u00a0Watch, the overhead will be reduced without restarting your program:<br \/>\n<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/paused.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8804\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/paused.png\" alt=\"paused\" width=\"803\" height=\"206\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/paused.png 803w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/paused-300x77.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/paused-768x197.png 768w\" sizes=\"(max-width: 803px) 100vw, 803px\" \/><\/a><\/p>\n<p>Finally, we have automated adding\/removing of functions via presets. Simply save a set of watched functions as a preset and you can get back to recording them any time you want:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/presets.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8806\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/presets.png\" alt=\"presets\" width=\"877\" height=\"208\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/presets.png 877w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/presets-300x71.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/presets-768x182.png 768w\" sizes=\"(max-width: 877px) 100vw, 877px\" \/><\/a><\/p>\n<h2><\/h2>\n<h2>RTOS integration<\/h2>\n<p>Real-time watch goes beyond just measuring the function run times.\u00a0It can seamlessly plot various events inside your RTOS:<\/p>\n<ul>\n<li>The exact time when\u00a0each thread was running<\/li>\n<li>Queue\/semaphore use over time<\/li>\n<li>Mutex ownership\u00a0over time<\/li>\n<li>Overall CPU utilization and per-thread CPU utilization<\/li>\n<\/ul>\n<p>FreeRTOS is supported out-of-the-box, other RTOSes can be\u00a0supported\u00a0via the extension SDK.<\/p>\n<p>Let&#8217;s\u00a0look at something easily recognizable: a basic\u00a0producer-consumer pattern. One thread will be producing 5 tokens at a time with a large pause afterwards and another one will be slowly consuming them one-by-one.\u00a0The threads will use a FreeRTOS semaphore to communicate to each other:<\/p>\n<pre class=\"\">static void LED_Thread1(void const *argument)\r\n{\r\n    for (;;)\r\n    {\r\n        for (int i = 0; i &lt; 5; i++)\r\n        {\r\n            HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);\r\n            osSemaphoreRelease(g_Semaphore);\r\n            osDelay(5);\r\n        }\r\n \r\n        osDelay(200);\r\n    }\r\n}\r\n\r\nstatic void LED_Thread2(void const *argument)\r\n{\r\n    for (;;)\r\n    {\r\n        while (osSemaphoreWait(g_Semaphore, -1) == osOK)\r\n        {\r\n            HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);\r\n            osDelay(30);\r\n        }\r\n    }\r\n}<\/pre>\n<p>For simplicity, we don&#8217;t send any actual data between the threads, but\u00a0we\u00a0use the semaphore as if we were sending it.<\/p>\n<p>The second thread takes 30 milliseconds to\u00a0process a\u00a0token and the first one produces 5 of them in short succession and then waits for 200 milliseconds.\u00a0This should result in the semaphore going\u00a0quickly from 0 to 5 and then slowly back to zero as the tokens are consumed. Let&#8217;s build this, start debugging, stop it once the threads are created, and add both threads and the semaphore variable to real-time watch:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/threads.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8808\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/threads.png\" alt=\"threads\" width=\"479\" height=\"278\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/threads.png 479w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/threads-300x174.png 300w\" sizes=\"(max-width: 479px) 100vw, 479px\" \/><\/a><\/p>\n<p>After you resume the session you will quickly see that the thread run times and\u00a0the semaphore value follow a periodic pattern:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/period.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8809\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/period.png\" alt=\"period\" width=\"682\" height=\"246\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/period.png 682w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/period-300x108.png 300w\" sizes=\"(max-width: 682px) 100vw, 682px\" \/><\/a><\/p>\n<p>Zoom it in to see what&#8217;s going on. As expected, the semaphore value\u00a0quickly grows in the beginning of the cycle and then decreases by 1 every 30 milliseconds. The thread\u00a0timing bars show\u00a0the exact time when each thread was\u00a0active. Note how when a thread calls the osDelay() function, FreeRTOS automatically switches to another thread:<br \/>\n<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/semaphore.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8810\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/semaphore.png\" alt=\"semaphore\" width=\"683\" height=\"251\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/semaphore.png 683w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/semaphore-300x110.png 300w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/a><\/p>\n<p>The graph also shows that the\u00a0semaphore value did not grow to 5 and stayed at 4 for a short while because the\u00a0second thread started processing the first token\u00a0as soon as\u00a0first thread\u00a0started sleeping for the first time.<\/p>\n<p>Let&#8217;s experiment\u00a0a little more with the threads and\u00a0enclose\u00a0the code that produces 5 tokens and the code that consumes them with a mutex.<\/p>\n<pre class=\"\">static void LED_Thread1(void const *argument)\r\n{\r\n    for (;;)\r\n    {\r\n        osMutexWait(g_Mutex, -1);\r\n        for (int i = 0; i &lt; 5; i++)\r\n        {\r\n            HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);\r\n            osSemaphoreRelease(g_Semaphore);\r\n            osDelay(5);\r\n        }\r\n        osMutexRelease(g_Mutex);\r\n \r\n        osDelay(200);\r\n    }\r\n}\r\n\r\nstatic void LED_Thread2(void const *argument)\r\n{\r\n    for (;;)\r\n    {\r\n        while (osSemaphoreWait(g_Semaphore, -1) == osOK)\r\n        {\r\n            osMutexWait(g_Mutex, -1);\r\n            HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);\r\n            osDelay(30);\r\n    \u00a0 \u00a0 \u00a0 \u00a0 osMutexRelease(g_Mutex);\r\n        }\r\n    }\r\n}<\/pre>\n<p>Real-time watch\u00a0can show the mutex owner on the same scale\u00a0and easily\u00a0visualize what has changed:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/mutex.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8811\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/mutex.png\" alt=\"mutex\" width=\"684\" height=\"248\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/mutex.png 684w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/mutex-300x109.png 300w\" sizes=\"(max-width: 684px) 100vw, 684px\" \/><\/a><\/p>\n<h2>Report files<\/h2>\n<p>The data collected by the real-time watch does not have to disappear when you close the debug session. Instead you can\u00a0export\u00a0it to a real-time watch report file, open those reports in Visual Studio and compare them side-by-side:<a href=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/report.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-8812\" src=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/report-1024x517.png\" alt=\"report\" width=\"474\" height=\"239\" srcset=\"https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/report-1024x517.png 1024w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/report-300x151.png 300w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/report-768x388.png 768w, https:\/\/sysprogs.com\/w\/wp-content\/uploads\/2016\/08\/report.png 1026w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<h2>More features<\/h2>\n<p>Real-time watch\u00a0can also visualize custom events, custom graphs and track execution time of custom code regions\u00a0without the need for instrumenting any functions.\u00a0<a href=\"http:\/\/twitter.com\/Sysprogs\/\">Follow us on twitter<\/a> to learn more about the customization features.<\/p>\n<h2>Download<\/h2>\n<p>The real-time watch feature is available starting from the Custom edition in VisualGDB 5.2 and later. You can download the Preview version of VisualGDB 5.2 on the <a href=\"http:\/\/visualgdb.com\/download\/\">download page<\/a>. Feel free to share your feedback with us via our <a href=\"http:\/\/sysprogs.com\/support\/\">contact form<\/a> or by\u00a0dropping us an email.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the toughest types of problems faced by embedded software developers is timing problems. Seeing what exactly happened before a problem popped up and being able to put multiple events on one scale could save hours of time. The previous version of VisualGDB included an embedded profiler that could\u00a0collect\u00a0statistics on the runtime\u00a0of various functions. &hellip; <a href=\"https:\/\/sysprogs.com\/w\/introducing-the-new-real-time-watch\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Introducing the new Real-time Watch<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[1],"tags":[216],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/8794"}],"collection":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/comments?post=8794"}],"version-history":[{"count":5,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/8794\/revisions"}],"predecessor-version":[{"id":8827,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/posts\/8794\/revisions\/8827"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/media?parent=8794"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/categories?post=8794"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/w\/wp-json\/wp\/v2\/tags?post=8794"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}