Building a hex and UF2 file for the Adafruit nRF52840 Feather Express with Visual Studio Code

Hi,

I'd like to generate code for the Adafruit nRF42850 Feather Express board using Visual Studio Code, and then transfer that code using the existing bootloader (that comes pre-loaded with the Feather board). I realise I can flash code using a Segger J-link, but I'm trying to update the application code only without overwriting the bootloader, SoftDevice, etc.

Info

  • Windows 10
  • I've setup the development toolchain for Visual Studio Code by following these instructions
    • Installed nRF Connect for Desktop v3.10.0
    • From nRF Connect for Desktop > Installed the Toolchain Manager App > nRF Connect SDK v1.8.0
    • Install installed the Programmer App
  • The nRF Connect extension for Visual Studio Code is installed correctly, and I'm able to compile example code.

I'm trying to compile a blinky example. In VS Code

  • From the nRF Connect extension tab > Create a new application from sample
  • Freestanding application
  • SDK,Toolchain and Application location fields all point to valid locations
  • Use template zephyr/samples/basic/blinky
  • Add Build Configuration adafruit_feather_nrf52840

When I press Build, this application builds without error, and the program hex file is generated at \project-folder\blinky\build\zephyr\zephyr.hex.

What I would like to do at this stage, is convert the HEX file to a UF2 file, so it is compatible with the pre-loaded Adafruit bootloader. This is not a problem, I can do that with this python script and the command 

uf2conv.py zephyr.hex -c -f 0xADA52840

But when I mount the Feather as a removable drive (double-click reset button) and transfer the UF2 file, it crashes, indicating that the hex file is invalid.

Problem

The problem is (I think) that the adafruit_feather_nrf52840 board configuration doesn't have the correct memory map. In other words it generates code that begins at flash address 0x00000000 which would override code (in this case the SoftDevice section).

The memory map of the Adafruit nrf52840 Feather Express indicates that the application code should begin at 0x26000.

More Info

I used the nRF Connect for Desktop Programmer App to examine the memory layout of the generated code at \project-folder\blinky\build\zephyr\zephyr.hex. It shows only one (yellow) MBR or Application section.

When I look at a valid hex file such as ble_app_hrs_pca10056_s140.hex from the nrf52840-dk-hrm-demo I see multiple sections.

  
This hex file (when converted to UF2) can be flashed successfully to the Adafruit Feather using it's default bootloader.

I examined the adafruit_feather_nrf52840.dts file used to create the zephyr.hex file and see the following partition info:

#include <nordic/nrf52840_qiaa.dtsi>
#include "feather_connector.dtsi"

/ {
	model = "Adafruit Feather nRF52840 Express";
	compatible = "adafruit,feather-nrf52840";

	chosen {
		zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
		zephyr,bt-mon-uart = &uart0;
		zephyr,bt-c2h-uart = &uart0;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
	};
	
	...
	
	&flash0 {

    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		boot_partition: partition@0 {
    			label = "mcuboot";
    			reg = <0x000000000 0x0000C000>;
    		};
    		slot0_partition: partition@c000 {
    			label = "image-0";
    			reg = <0x0000C000 0x00067000>;
    		};
    		slot1_partition: partition@73000 {
    			label = "image-1";
    			reg = <0x00073000 0x00067000>;
    		};
    		scratch_partition: partition@da000 {
    			label = "image-scratch";
    			reg = <0x000da000 0x0001e000>;
    		};
    
    		/*
    		 * The flash starting at 0x000f8000 and ending at
    		 * 0x000fffff is reserved for use by the application.
    		 */
    
    		/* Storage partition will be used by FCB/NFFS/NVS if enabled. */
    		storage_partition: partition@f8000 {
    			label = "storage";
    			reg = <0x000f8000 0x00008000>;
    		};
    	};
    };

I notice that the &flash0 partition information doesn't match the Adafruit Feather board, so I created a new build configuration with the correct partition information (although I'm not sure if this is the correct way to address the problem?).

New memory map in adafruit_feather_nrf52840_custom.dts

...

	chosen {
		zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
		zephyr,bt-mon-uart = &uart0;
		zephyr,bt-c2h-uart = &uart0;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &application;
	};
	
...

    &flash0 {
    
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		soft_device: partition@0 {
    			label = "soft-device";
    			reg = <0x000000000 0x26000>;
    		};
    		application: partition@26000 {
    			label = "application";
    			reg = <0x26000 0xC7000>;
    		};
    		user_data: partition@ED000 {
    			label = "user-data";
    			reg = <0xED000 0x7000>;
    		};
    		bootloader: partition@F4000 {
    			label = "bootloader";
    			reg = <0xF4000 0xC000>;
    		};
    	};
    };

This was reflected in the VS Code IDE.

I then recompiled the blinky example application using this new board configuration file, and again examined the hex file in the nRF Connect Application App. What I expected to see was perhaps one (green) application section, that did not start from 0x00000000. Instead, I only saw the same thing as before, with one small yellow section:

So I guess my questions are:

  1. Have I properly understood the problem?
  2. Does it even make sense to be using using zephyr example code? The blinky app looks pretty generic.
  3. What is the VS Code adafruit_nrf52480_feather build configuration file intended for? Is this something created/maintained by Nordic?
  4. What am I missing?
  5. Do I need to be looking at adding more build VS Code build tasks, or modifying the makefile, or something else entirely?

I hope I've given enough information so you can assist.

Thanks!

Chris

  • Hi Chris, 
    I'm not very familiar with the nRF52840 Feather express so you may need to double check with Adafruit. But there is a fundamental difference here is that the bootloader for nRF52840 was made for nRF5 SDK (using softdevice). And what you are trying to build is with nRF Connect SDK (Zephyr). There is no softdevice when building with Zephyr, the stack is integrated with the application. 

    It's possible to modify the start address of the Zephyr application to the same address as if it's using softdevice (0x26000) but I don't see much point doing that because you won't be able to use the softdevice. My suggestion is to completely remove softdevice, MBR, Bootloader and flash the Zephyr application directly using a programmer. 

    Please note that nRF Connect SDK has its own bootloader (MCUBoot) and it's not compatible with the legacy bootloader. 

  • Hi,

    Ahh, I see. There are two SDKs. It looks like nRF Connect with Zephyr is the more recent of the two.

    Thanks for the info.

    Cheers,

    Chris

  • Hi Chris,

    I hope you were able to get your problem resolved. I can't contribute anything to the solution but I wanted to congratulate you on your problem statement. Yours was, by far, the best explanation of a problem that I have seen presented in this forum.

    Good coding,

    Bill

Related