{"id":5791,"date":"2020-03-26T18:37:28","date_gmt":"2020-03-27T01:37:28","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=5791"},"modified":"2020-03-26T18:37:28","modified_gmt":"2020-03-27T01:37:28","slug":"debugging-embedded-projects-remotely","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/remote\/","title":{"rendered":"Debugging Embedded Projects Remotely"},"content":{"rendered":"<p>This tutorial shows how to debug embedded VisualGDB projects remotely, i.e. with the JTAG\/SWD debugger connected to a different physical machine.<\/p>\n<p>We will create a basic STM32-based project debugged with OpenOCD, and will show how to change the settings to run OpenOCD on a remote machine and connect to it from VisualGDB.<\/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\/03\/01-newprj-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5808\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/01-newprj-2.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Enter a name and location for the new project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/02-remote.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5792\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/02-remote.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Proceed with creating a new MSBuild-based embedded binary:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/03-type.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5793\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/03-type.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page of the wizard, select your toolchain and device. Then proceed with the default settings:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/04-device-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5794\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/04-device-2.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>In this tutorial we will be focusing on configuring the debugger, so pick the simplest &#8220;LEDBlink&#8221; sample: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/05-blink-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5795\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/05-blink-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally, choose the debug settings. We will begin with a regular OpenOCD-based setup where the ST-Link is connected to the main development machine. Later in the tutorial, we will update it to run OpenOCD remotely:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/06-debug-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5796\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/06-debug-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Click &#8220;Finish&#8221; to generate the project. Once it is created, build it by pressing Ctrl-Shift-B:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/07-built-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5797\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/07-built-2.png\" alt=\"\" width=\"1181\" height=\"864\" \/><\/a><\/li>\n<li>Debugging embedded projects generally involves 3 components:\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>VisualGDB integrated in Visual Studio that controls other tools<\/li>\n<li>GDB debugger that translates names (e.g. <strong>main()<\/strong>) to addresses, evaluates variables, etc<\/li>\n<li>GDB stub, such as OpenOCD, that interacts with the hardware and handles low-level requests from GDB. Since the debugging symbols are handled by gdb, OpenOCD (or another gdb stub) does not need to access the built project, and can generally run on any computer accessible via network.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The diagram below summarizes the setup:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/pipeline-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5811\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/pipeline-1.png\" alt=\"\" width=\"1532\" height=\"133\" \/><\/a><\/p>\n<p>Before we can switch to running OpenOCD on another machine, we would need to make note of all command lines and GDB commands involved in running it manually.<\/li>\n<li>Set a breakpoint somewhere in the <strong>main()<\/strong> function and start debugging. Once the breakpoint triggers, open the <strong>Debug-&gt;Windows-&gt;GDBServer Console <\/strong>window and make a note of the command line:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/08-oocd.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5798\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/08-oocd.png\" alt=\"\" width=\"1181\" height=\"864\" \/><\/a>A typical OpenOCD command line is shown below:\n<pre class=\"\">C:\\Users\\virtual.SYSPROGS\\AppData\\Local\\VisualGDB\\EmbeddedDebugPackages\\com.sysprogs.arm.openocd\\bin\\openocd.exe -c \"gdb_port 55896\" -c \"telnet_port 55895\" -f interface\/stlink-v2-1.cfg -f target\/stm32f4x.cfg -c init -c \"reset init\" -c \"echo VisualGDB_OpenOCD_Ready\"<\/pre>\n<\/li>\n<li>Now open the <strong>GDB Session<\/strong> window and switch it to the &#8220;All GDB Interaction&#8221; mode. Locate the &#8220;target remote command&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/09-gdbcommands.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5799\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/09-gdbcommands.png\" alt=\"\" width=\"1181\" height=\"864\" \/><\/a>The &#8220;target remote&#8221; command tells GDB to connect to the port where OpenOCD is listening (see the <strong>gdb_port<\/strong> command). Once it is connected, GDB will drive the high-level aspects of the debug session, while OpenOCD will drive the low-level parts.<\/li>\n<li>In addition to the &#8220;target remote&#8221; command, VisualGDB issues a few special commands to reset the device and program its FLASH memory. If you are using OpenOCD, you can find them in the &#8220;<strong>Startup GDB Commands<\/strong>&#8221; field inside <strong>Advanced Settings<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/10-oocdsettings-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5813\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/10-oocdsettings-1.png\" alt=\"\" width=\"1063\" height=\"786\" \/><\/a><\/li>\n<li>Now that we know the OpenOCD command line, we can run it on a different machine. In this tutorial, we will run a Linux port of OpenOCD on a Linux machine, however you can also run it on Windows by copying the OpenOCD package to another computer. Add the following argument to the beginning of the captured gdb command line and run it on the second machine:\n<pre class=\"\">-c \"bindto 0.0.0.0\"<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/11-remoterun.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5801\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/11-remoterun.png\" alt=\"\" width=\"1140\" height=\"771\" \/><\/a>The &#8220;bindto 0.0.0.0&#8221; command tells OpenOCD to accept connections from all remote machines, not just <strong>localhost<\/strong>. If you are using J-Link or another tool instead of OpenOCD, refer to its documentation for the name of the equivalent command.<\/li>\n<li>Go to the Debug Settings page of VisualGDB Project Properties and switch the Debug Method to &#8220;<strong>Full-Custom Mode<\/strong>&#8221; (you will need to switch the view from <strong>USB Devices<\/strong> to <strong>Debug Methods<\/strong>). Then, enter the following parameters:<br \/>\n<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 50%;\">Parameter<\/td>\n<td style=\"width: 50%;\">Value<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Command<\/td>\n<td style=\"width: 50%;\">&lt;path to gdb.exe&gt;<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Arguments<\/td>\n<td style=\"width: 50%;\">&#8211;interpreter mi $(TargetPath)<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">Target selection command<\/td>\n<td style=\"width: 50%;\">target remote &lt;name of machine running OpenOCD&gt;:&lt;port&gt;<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">After selecting target<\/td>\n<td style=\"width: 50%;\">Use the &#8220;continue&#8221; command<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/12-settings.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5802\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/12-settings.png\" alt=\"\" width=\"1176\" height=\"754\" \/><\/a><\/li>\n<li>Start debugging. VisualGDB will now connect to the remote OpenOCD instance and debug session will work as expected:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/13-remotedone.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5803\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/13-remotedone.png\" alt=\"\" width=\"1176\" height=\"820\" \/><\/a><\/li>\n<li>Note that the previous setup did not include the resetting and FLASH loading commands, so it will only work as long as you haven&#8217;t modified your program. In order to program the FLASH memory remotely, add the startup commands from the original OpenOCD settings to VisualGDB Project Properties -&gt; Additional GDB Commands -&gt; After selecting a target:\n<pre class=\"\">mon halt\r\nmon reset init\r\nload<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/14-load.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5804\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/14-load.png\" alt=\"\" width=\"934\" height=\"648\" \/><\/a><\/li>\n<li>Now both debugging and FLASH memory programming will work:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/load.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5815\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/load.png\" alt=\"\" width=\"1176\" height=\"820\" \/><\/a>Make sure you keep running the remote OpenOCD instance after the end of the debug session, so you can connect to it again when you debug next time.<\/li>\n<li>If you are using the Custom edition of VisualGDB or higher, you can configure it to automatically launch OpenOCD for you (Linux machines only). First of all, add &#8220;mon shutdown&#8221; to the session termination commands, as otherwise OpenOCD will keep running after gdb exits:<\/li>\n<li><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/15-shutdown.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5805\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/15-shutdown.png\" alt=\"\" width=\"934\" height=\"648\" \/><\/a>Then, go to the Custom Debug Steps page of VisualGDB Project Properties and switch the <strong>Remote Console<\/strong> to &#8220;<strong>Run a specified command<\/strong>&#8220;. Select the machine where you have OpenOCD installed and enter the OpenOCD command line there: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/16-runocd.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5806\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/16-runocd.png\" alt=\"\" width=\"934\" height=\"648\" \/><\/a><\/li>\n<li>Now VisualGDB will start and stop remote OpenOCD completely automatically, as if it was running on the same machine as Visual Studio: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/17-running.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5807\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/03\/17-running.png\" alt=\"\" width=\"1176\" height=\"820\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to debug embedded VisualGDB projects remotely, i.e. with the JTAG\/SWD debugger connected to a different physical<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[60,203,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5791"}],"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=5791"}],"version-history":[{"count":3,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5791\/revisions"}],"predecessor-version":[{"id":5816,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5791\/revisions\/5816"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=5791"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=5791"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=5791"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}