Adafruit bootloader + nRF Connect Zephyr Application

Hi,

I have some detailed questions about the Adafruit bootloader and how to get my zephry-compiled binary, and uf2 versions, working with it.

Specifically:
- I have an Adafruit Feather nRF52840 Express
- nRF Connect installation, and therefore a zephyr build environment (under linux)
- An nRF52840-DK board, acting as a segger jlink to the Adafruit nRF52840

I can compile my zephyr app and flash directly to the 0x0000 address and see the application work.

What I want, though, is to have a bootloader, like from Adafruit, which accepts x.uf2 files, so I can upgrade the application later easily. This is where all my problems are, and I could use some help.

My process is:
- erase the nRF52840
- flash the Adafruit nRF52 bootloader
- drag/drop the .uf2 version of my zephyr app

The erase and bootloader flash works fine I think.
But the drag/drop of the .uf2 doesn't lead to a working application. I need help.

Erasing the nRF52840 is this:
JLinkExe -CommandFile erase_command.jls

si 1
speed 4000
device NRF52840_XXAA
connect
erase
exit



Flashing the Adafruit nRf52 bootloader (https://github.com/adafruit/Adafruit_nRF52_Bootloader) is this:

nrfjprog --program _build/build-feather_nrf52840_express/feather_nrf52840_express_bootloader-0.6.4-dirty_nosd.hex --sectoranduicrerase -f nrf52 --reset --verify



Converting my zephyr-built binary is this:

uf2conv.py zephyr.bin -c -b 0x1000 -f 0xADA52840



I chose 0x1000 because reading the source code of the bootloader, I see:

bootloader.c

  if ( is_sd_existed() )
  {
    PRINTF("SoftDevice exist\r\n");
    // App starts after SoftDevice
    app_addr = SD_SIZE_GET(MBR_SIZE);
    fwd_ret = sd_softdevice_vector_table_base_set(app_addr);
  }else
  {
    PRINTF("SoftDevice not exist\r\n");

    // App starts right after MBR
    app_addr = MBR_SIZE;
    sd_mbr_command_t command =
    {
      .command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
      .params.irq_forward_address_set.address = app_addr,
    };

    fwd_ret = sd_mbr_command(&command);
  }

  // unlikely failed to forward vector table, manually set forward address
  if ( fwd_ret != NRF_SUCCESS )
  {
    PRINT_HEX(fwd_ret);

    // MBR use first 4-bytes of SRAM to store foward address
    *(uint32_t *)(0x20000000) = app_addr;
  }

  // jump to app
  bootloader_util_app_start(app_addr);



nrf_mbr.h

#define MBR_SIZE                (0x1000)




So, I upload the converted application, in .uf2 format, by drag/dropping onto the mounted USB drive. The drive accepts it, unmounts itself, and does not re-mount itself.

This indicates to me the program was flashed.
I can confirm this by reading back the flash memory, and I do see my program in its entirety residing at 0x1000.

But why doesn't my program run?

I don't understand enough about the Adafruit bootloader, nor about the zephyr application, to know.

Can someone help me understand what to do differently to get this to work, or to debug what I've tried?

I know my application works when directly flashed to 0x0 (via nRF Connect VSCode plugin).

Any and all help appreciated, thanks!


Doug

Parents
  • We are not the makers of the Adafruit bootloader, so you would have to contact Adafruit for that info. 

    A option you can use is to use the MCUBoot bootloader but it does not support uf2. So the drag and drop feature the Adafruit bootloader has is not something we have. My guess it that the zephyr compiled hex file you have that converts to a uf2 file does not match the memory criteria the Adafruit bootloader is expecting, so it fails understand the application.

    Regards,
    Jonathan

  • Thank you, I appreciate the reply.

    Can you tell me, or point me to information, about the specifics of how the MCUBoot bootloader loads and invokes new application code?

    I am becoming more familiar with the layout of flash.  I assume MCUBoot lives at a given address (where?) and expects my application code to live at a given address (where?).  And invokes it how?

    And what runs MCUBoot?  I've seen some documentation talking about an MBR (master boot record) but I'm not very unclear on what it specifically is, and how it fits into the above picture (if it does at all).

    Thank you for the help.

    Doug

Reply
  • Thank you, I appreciate the reply.

    Can you tell me, or point me to information, about the specifics of how the MCUBoot bootloader loads and invokes new application code?

    I am becoming more familiar with the layout of flash.  I assume MCUBoot lives at a given address (where?) and expects my application code to live at a given address (where?).  And invokes it how?

    And what runs MCUBoot?  I've seen some documentation talking about an MBR (master boot record) but I'm not very unclear on what it specifically is, and how it fits into the above picture (if it does at all).

    Thank you for the help.

    Doug

Children
Related