{"id":7597,"date":"2021-11-01T16:22:36","date_gmt":"2021-11-01T23:22:36","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=7597"},"modified":"2021-11-01T16:22:36","modified_gmt":"2021-11-01T23:22:36","slug":"profiling-raspberry-pi-pico-projects-with-visualgdb","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/raspberry\/pico\/profiling\/","title":{"rendered":"Profiling Raspberry Pi Pico Projects with VisualGDB"},"content":{"rendered":"<p>This tutorial shows how to profile the Raspberry Pi Pico project that use PicoSDK with VisualGDB. We will create a basic project using demonstrating the USB connectivity, and will show how to use the instrumenting profiler to analyze which functions take the most time.<\/p>\n<ol>\n<li>Start Visual Studio and locate the VisualGDB Raspberry Pi Pico Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7598\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/01-newprj.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Enter the name and location for your project: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/02-path.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7599\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/02-path.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>On the first page of the VisualGDB-specific part of the wizard, select &#8220;Create a new project based on a sample project&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/03-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7600\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/03-newprj.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Pick your ARM toolchain and the PicoSDK version that you would like to use. If you have not created PicoSDK-based projects yet, VisualGDB can automatically download and install the latest PicoSDK for you: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/03-sdk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7601\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/03-sdk.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Select the project template you would like to clone. In this tutorial, we will create a project based on the <strong>hello_world\\usb<\/strong> example: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/04-usb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7602\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/04-usb.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Finally, connect a debugger to your board and select the debugging settings on the last page of the wizard. Use the &#8220;Test&#8221; button to verify that the debugging connection works: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/05-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7603\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/05-debug.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to create the project. Once it has been created, build it by pressing Ctrl-Shift-B:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/06-built-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7610\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/06-built-1.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<li>Before we can profile the project with VisualGDB, we need to reference the <strong>Fast Semihosting and Embedded Profiler<\/strong> framework. Open VisualGDB Project Properties, go to the Embedded Frameworks page and reference it there:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/07-profiler.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7605\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/07-profiler.png\" alt=\"\" width=\"934\" height=\"751\" \/><\/a>Make sure that the following configuration options are set as shown below:\n<ul>\n<li>&#8220;<strong>Exclude sampling profiler code<\/strong>&#8221; checkbox should be checked, as the sampling profiler does not support Raspberry Pi Pico yet.<\/li>\n<li>&#8220;<strong>Redirect printf() to fast semihosting<\/strong>&#8221; checkbox should be unchecked, as trying to use the Raspberry Pi Pico semihosting while profiling may result in a crash.<\/li>\n<\/ul>\n<\/li>\n<li>Modify the main source file to include <strong>&lt;SysprogsProfiler.h&gt;<\/strong> and call <strong>InitializeInstrumentingProfiler()<\/strong> from <strong>main()<\/strong> as shown below. Then, build the project and select &#8220;Analyze-&gt;Analyze Performance with VisualGDB:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/06-built-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7615\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/06-built-3.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<li>In the New Profiling Session window select &#8220;Instrument functions to record their time&#8221;. Note that some of the PicoSDK functions are placed in RAM and instrumenting them may result in a crash. In order to exclude them from instrumentation, sort the functions by address and uncheck every function located in RAM:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/08-noflash-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7612\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/08-noflash-1.png\" alt=\"\" width=\"803\" height=\"822\" \/><\/a>Note that you can uncheck multiple functions by selecting them with <strong>Shift<\/strong>, and pressing <strong>Space<\/strong>.<\/li>\n<li>Press &#8220;OK&#8221; to start a profiling session. The PicoSDK will likely trigger a breakpoint as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/09-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7607\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/09-bkpt.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<li>Use the call stack to navigate to the function triggering it. As of PicoSDK 1.3.0, the <strong>hard_assert()<\/strong> inside <strong>irq_set_exclusive_handler()<\/strong> will trigger during a profiling session, because some of the interrupt handlers have been instrumented. You can suppress this breakpoint by commenting out the <strong>hard_assert()<\/strong> line shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/10-func.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7608\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/10-func.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<li>Now that you have commented it out, you will be able to profile the code. Use the <strong>Live Profiling<\/strong> window to see what functions take the most time:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/11-profiling-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7613\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/11-profiling-1.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a>Note that the &#8220;<strong>USB Hello, World<\/strong>&#8221; example shown in this tutorial will not work correctly when profiled in the <strong>Debug<\/strong> configuration. This happens because the overhead introduced by unoptimized profiling code make the code too slow to handle USB requests. Switching to the <strong>RelWithDebInfo<\/strong> configuration via Visual Studio Configuration Manager enables optimization and fully resolves the issue.<\/li>\n<li>You may find that some functions are called too frequently and are causing too much profiler overhead. If this happens, you can either exclude them from instrumentation via the <strong>New Profiling Session<\/strong> window, or programmatically suspend the profiler while they run. E.g. profiling an unoptimized build shows that most of the time is consumed by numerous small functions called by <strong>hardware_alarm_irq_handler()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/12-alarm-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7620\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/12-alarm-1.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<li>Use the Code Explorer to locate the <strong>g_SuppressInstrumentingProfiler<\/strong> variable. Edit the <strong>hardware_alarm_irq_handler()<\/strong> function to increment the it on entry and decrement it before exit:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/13-suppress.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7618\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/13-suppress.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<li>Now the overhead of the <strong>hardware_alarm_irq_handler()<\/strong> function has considerably reduced. The small functions called by it still work as before, but the profiler no longer measures their execution time separately, as if all of the work was done in <strong>hardware_alarm_irq_handler()<\/strong> itself: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/14-suppressed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7619\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/11\/14-suppressed.png\" alt=\"\" width=\"1355\" height=\"822\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to profile the Raspberry Pi Pico project that use PicoSDK with VisualGDB. We will create a<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[197],"tags":[109,231],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7597"}],"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=7597"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7597\/revisions"}],"predecessor-version":[{"id":7621,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7597\/revisions\/7621"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=7597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=7597"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=7597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}