{"id":6314,"date":"2020-06-09T19:48:36","date_gmt":"2020-06-10T02:48:36","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=6314"},"modified":"2021-11-05T11:20:20","modified_gmt":"2021-11-05T18:20:20","slug":"targeting-multi-core-nrf53-devices-with-visual-studio","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/nrfconnect\/nrf5340\/","title":{"rendered":"Targeting Multi-Core nRF53 Devices with Visual Studio"},"content":{"rendered":"<p>This tutorial shows how to create, build and debug a basic project for the multi-core nRF5340 device<\/p>\n<p>The <a href=\"https:\/\/www.nordicsemi.com\/Products\/Low-power-short-range-wireless\/nRF5340\">nRF5340<\/a> device includes 2 cores:<\/p>\n<ul>\n<li>The application core runs the high-level logic.<\/li>\n<li>The network core, running at a lower clock frequency, receives low-level Bluetooth LE requests from the network core and resends them to the BLE hardware.<\/li>\n<\/ul>\n<p>In this tutorial build the <strong>Nordic LED and Button Service<\/strong> example for the nRF5340-DK board (<strong>peripheral_lbs<\/strong>), and will show how to observe and control the LEDs and observe the buttons on the board using a Bluetooth LE-capable Android device. We will also show how the 2 cores interact, and how to debug them at the same time using 2 independent Visual Studio instances.<\/p>\n<p>Before you begin, install VisualGDB 5.5 or higher.<\/p>\n<ol>\n<li>Start Visual Studio and locate the VisualGDB nRFConnect Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/01-wizard.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6315\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/01-wizard.png\" alt=\"\" width=\"966\" height=\"624\" \/><\/a><\/li>\n<li>First, we will create the project for the Application core. Note that we won&#8217;t be able to actually use it until we program a special firmware into the Network core (shown later in the tutorial). Pick the name and location for the Application core project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/02-app.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6316\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/02-app.png\" alt=\"\" width=\"966\" height=\"624\" \/><\/a><\/li>\n<li>Select &#8220;Create a new project based on a sample project&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/03-new.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6317\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/03-new.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Pick your ARM toolchain, nRFConnect checkout (follow <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/nrfconnect\/nrf9160\/\">this tutorial<\/a> for instructions on getting nRFConnect checkouts working) and the target device. The target for the application core of nRF5340 is called <strong>NRF5340-DK-NRF5340-application-MCU<\/strong>: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/04-appmcu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6318\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/04-appmcu.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>On the on the next page pick the <strong>peripheral_lbs<\/strong> example that exposes the on-board LEDs and buttons via Bluetooth LE:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/05-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6319\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/05-sample.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Make sure you are using the latest version of the Segger J-Link software and have installed the <a href=\"https:\/\/www.nordicsemi.com\/Software-and-tools\/Development-Tools\/nRF-Command-Line-Tools\">nRF Command-Line tools<\/a>. Then plug your board into the USB port and configure the debugging settings as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/06-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6320\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/06-device.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a> We recommend programming the FLASH memory with <strong>nrfjprog<\/strong> as it handles core reset better than the J-Link GDB stub.<\/li>\n<li>Press &#8220;Finish&#8221; to complete the wizard. VisualGDB will generate a basic project based on the nRFConnect framework, showing its contents in Solution Explorer:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/07-main.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6321\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/07-main.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>Now we will create a project for the network core. It will receive commands from the <strong>peripheral_lbs<\/strong> example and will forward them to the Bluetooth LE hardware. Start <strong>another<\/strong> instance of Visual Studio, select the nRFConnect Project Wizard again and pick the location for the second project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/08-network.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6322\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/08-network.png\" alt=\"\" width=\"966\" height=\"624\" \/><\/a><\/li>\n<li>This time, select the network core (NRF5340-DK-NRF5340-network-MCU): <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/09-netcpu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6323\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/09-netcpu.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Select the <strong>hci_rpmsg<\/strong> sample. This project needs to run on the Network core in order to use any of the Bluetooth LE examples on the Application core: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/10-rpmsg.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6324\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/10-rpmsg.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>The nRFConnect tools will program the FLASH memory for both Application and Network cores when launching the Application project (we will show how to link the two projects later in the tutorial), so make sure you select &#8220;<strong>Program FLASH Memory = Never<\/strong>&#8221; and disable device resetting: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/11-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6325\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/11-debug.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a>We also suggest double-checking that the debugged device shows <strong>nRF5340_xxAA_NET<\/strong>\u00a0 and not <strong>nRF5340_xxAA_APP<\/strong>.<\/li>\n<li>As of nRFConnect SDK 1.2.0, trying to build the nRF5340 samples without optimization will result in a stack overflow. To avoid this, set configuration-specific optimization to &#8220;<strong>Optimize for debugging<\/strong>&#8221; as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/12-optimize.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6326\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/12-optimize.png\" alt=\"\" width=\"1069\" height=\"682\" \/><\/a>Note that this <strong>will<\/strong> slightly reduce debugging usability compared to no optimization (e.g. unused variables will be eliminated and hence won&#8217;t be viewable).<\/li>\n<li>Build the project by pressing Ctrl-Shift-B:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/13-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6327\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/13-built.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>When the build succeeds, go to the VisualGDB Project Properties of the <strong>Application core<\/strong> project (another Visual Studio instance) and link it with the network core project as shown below: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/14-firm2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6328\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/14-firm2.png\" alt=\"\" width=\"1069\" height=\"682\" \/><\/a>VisualGDB will automatically pick up the matching configuration\/platform from the linked project when programming the FLASH memory, however it won&#8217;t rebuild it automatically when building the Application core project.<\/li>\n<li>If you are using the Custom edition or higher, you can use the <strong>Raw Terminal<\/strong> page of VisualGDB Project Properties to observe the debug output from the nRF5340-DK board. Otherwise, try using any other terminal program (e.g. <a href=\"https:\/\/sysprogs.com\/SmarTTY\/\">SmarTTY<\/a>):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/15-term.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6329\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/15-term.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>Normally, programming the FLASH memory using the nRFConnect tools will let the device start before VisualGDB gets a chance to attach to it. To work around it, add the following function to your main file and call it from main():\n<pre class=\"\">void __attribute__((noinline)) SysprogsWaitForDebugger()\r\n{\r\n    static volatile int SysprogsDebuggerAttached = 0;\r\n    while (!SysprogsDebuggerAttached)\r\n    {\r\n    }\r\n}<\/pre>\n<\/li>\n<li>Build the <strong>Application<\/strong> project, set a breakpoint in <strong>main()<\/strong> after the call to <strong>SysprogsWaitForDebugger()<\/strong> and start debugging it. The breakpoint will trigger, letting you step through the code. If you are using the Custom edition or higher, VisualGDB will automatically decode and show the state of Zephyr threads running on the core:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/16-hit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6330\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/16-hit.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>Resume the program and observe the output in the Terminal window. Once the example fully initializes, it will print the &#8220;Advertising Successfully Started&#8221; message: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/17-run.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6331\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/17-run.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>Install <a href=\"https:\/\/www.nordicsemi.com\/Software-and-tools\/Development-Tools\/nRF-Connect-for-mobile\">nRFConnect for Mobile<\/a> on your mobile device and locate the nRF52840 board. Connect to it and subscribe to the button events:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/nrfconnect-1280-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6341\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/nrfconnect-1280-1.png\" alt=\"\" width=\"1280\" height=\"797\" \/><\/a>Each time you press or release the on-board button #1, the app will show the updated value.<\/li>\n<li>We will now show how the sample project passes the button state to the nRFConnect Mobile app. Note that stopping at a breakpoint would normally quickly lead to a Bluetooth LE time-out. As an alternative, consider adding invocation counters to functions that you would like to observe and then monitoring them using VisualGDB&#8217;s <a href=\"https:\/\/visualgdb.com\/documentation\/livevars\/\">Live Watch<\/a>. Add a counter to the <strong>button_pressed<\/strong> function in the <strong>dk_buttons_and_leds.c<\/strong> file and make sure it updates each time you press the button:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/18-pressed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6332\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/18-pressed.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>The <strong>button_pressed()<\/strong> function calls the <strong>k_delayed_work_submit()<\/strong> function on the <strong>buttons_scan<\/strong> queue:\n<pre class=\"\">\tcase STATE_WAITING:\r\n\t\tstate = STATE_SCANNING;\r\n\t\tk_delayed_work_submit(&amp;buttons_scan, 1);\r\n\t\tbreak;<\/pre>\n<p>Use VisualGDB&#8217;s CodeJumps navigation to quickly find the handler for the queue (<strong>buttons_scan_fn()<\/strong>): <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/19-func-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6342\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/19-func-1.png\" alt=\"\" width=\"1180\" height=\"806\" \/><\/a><\/li>\n<li>The <strong>buttons_scan_fn()<\/strong> function gets invoked in a different thread and forwards the event to the Bluetooth LE core. You can set a breakpoint on it and step into the call stack to see how exactly this is done. The notable functions on the call stack are <strong>gatt_notify()<\/strong> that is used to send notification events for all GATT objects, and <strong>bt_conn_send_cb()<\/strong> that physically sends a low-level packet to the network core:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/20-send.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6334\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/20-send.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>Now we will debug code on the network core that receives the packet from the application core. To minimize the chance of Bluetooth LE time-outs while adding\/removing breakpoints, enable the &#8220;<strong>Insert\/remove breakpoints and live variables without stopping the target<\/strong>&#8221; checkbox in VisualGDB Project Properties:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/21-fakestop.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6335\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/21-fakestop.png\" alt=\"\" width=\"1177\" height=\"754\" \/><\/a><\/li>\n<li>Set a breakpoint in <strong>gatt_notify()<\/strong> on the <strong>Application<\/strong> core and press the button, waiting for the breakpoint to trigger (you may need to reconnect nRFConnect for Mobile and re-subscribe to events): <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/22-bkpt1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6336\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/22-bkpt1.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>Start debugging the network core and set a breakpoint in <strong>tx_thread()<\/strong> after the call to <strong>net_buf_get()<\/strong>. Then, resume the application core&#8217;s session. The network core breakpoint will trigger:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/23-netbkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6337\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/23-netbkpt.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a>Note that <strong>net_buf_get()<\/strong> on the network core corresponds to <strong>net_buf_put()<\/strong> called by <strong>bt_conn_send_cb()<\/strong> on the application core.<\/li>\n<li>You can step into <strong>bt_send()<\/strong> to see how the low-level request from the application core gets translated and sent directly to the Bluetooth LE hardware by the network core:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/24-traced.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6338\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/24-traced.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<li>To minimize Bluetooth LE timeouts, try using counter variables with Live Watch instead of breakpoints on the network core as well. They will show which functions got executed without stopping any of the targets: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/25-live.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6339\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/06\/25-live.png\" alt=\"\" width=\"1180\" height=\"805\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create, build and debug a basic project for the multi-core nRF5340 device The nRF5340 device<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[89],"tags":[96,56,192,211],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6314"}],"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=6314"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6314\/revisions"}],"predecessor-version":[{"id":6343,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6314\/revisions\/6343"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=6314"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=6314"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=6314"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}