This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DFU from external flash using SPI NOR

Hi,

I am attempting to get the zephyr usb dfu sample located at ncs/zephyr/samples/usb/dfu to work using external flash. I am using the nrf52833 on a custom board in combination with mx25r32 flash chip on ncs version 2.4.0.

Firstly, I have been able to get the dfu working with no issues when I don't configure the project to use external flash. I build the project with the default usb device name, flash it and see that it shows up as a usb device. Then I change the name, rebuild the project and use dfu-util to send app_update.bin to the image 1 slot of the device. I reboot the device, it swaps in the new image and I see my newly named usb device show up. Unfortunately, I need the extra internal flash space as my application is larger than 250 kb.

I then make the following changes to the prj.conf file located at ncs/bootloader/mcuboot/boot/zephyr/prj.conf

CONFIG_MULTITHREADING=y
CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_PM_EXTERNAL_FLASH=y
CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R32"
CONFIG_PM_EXTERNAL_FLASH_BASE=0
CONFIG_PM_EXTERNAL_FLASH_SIZE=0x73000

I then make the following change to the pm.yml located at the same place

mcuboot_secondary:
    region: external_flash
    size: CONFIG_PM_EXTERNAL_FLASH_SIZE

I also add the following to the prj.conf file in the usb dfu sample

CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_PM_EXTERNAL_FLASH=y
CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R32"
CONFIG_PM_EXTERNAL_FLASH_BASE=0
CONFIG_PM_EXTERNAL_FLASH_SIZE=0x73000

Once I make these changes, everything builds fine and I see the new application size is basically doubled, which to me means that it is in fact configured correctly for storing the secondary image on external flash. I repeat the steps to get a new image on the device just as a I did before and everything seems to work fine. However, when I reboot the device the new usb device is never seen. I see the bootloader try to swap the new image in but it then says that there is no valid firmware image in the primary slot.

I also run into the same issue when I use SMP over BLE. The image is successfully added and the mcumgr image list command even shows that there are two firmware images on the device. But when I reboot, the bootloader tries to swap in the new image but then fails to validate it. 

Am I doing something wrong or is this only supposed to work with QSPI?

The external flash works fine on its own as I have the NVS system stored there and I am able to use it without any issues.

Parents Reply Children
  • I'm still trying to figure this out, unfortunately. The DFU controller says "the image is not in a pending state" once the transfer is finished in my case, so I did not reach the FW activation step in MCUboot as you did.

    Do you have an easy way of reading back the flash on your flash device to see if it matches the binary you uploaded (app_update.bin)? Maybe this could help explain why the validation fails. SPI flash has been used successfully with mcuboot on the nRF9160, so it supposed to work.

    I will discuss this issue with the developers on Monday to try to speed this up.

  • Update: The app failed to write the 16-byte MAGIC number because the byte array was kept in FLASH memory, and the SPI EasyDMA can only access data in RAM.  I belive this is what caused the update to fail for me.

    The original byte array declaration in mcuboot.c with the 'const' qualifier which causes it to only be placed in FLASH:

    static const uint32_t boot_img_magic[4] = {
    	0xf395c277,
    	0x7fefd260,
    	0x0f505235,
    	0x8079b62c,
    };

    And here is after I removed 'const' to get it loaded to RAM:

    static uint32_t boot_img_magic[4] = {
    	0xf395c277,
    	0x7fefd260,
    	0x0f505235,
    	0x8079b62c,
    };

    Please try to include this fix and see if you get the same result.

  • Hi, I had to work on something else for a bit so I apologize for the delayed response. I have picked this up again and made the changes in your above post to the file zephyr/subsys/dfu/boot/mcuboot.c. I did not see any change and something is still going wrong in the bootloader. For some reason, I am also not getting log output in the bootloader, so I don't have much to show here. Going to try to get that working so I can give more information. 

    I did verify that everything was still working when I do not use external flash. Note, I am following the sample and not using mcumgr to do the dfu but rather dfu-util using the command dfu-util --alt 0 --download build/zephyr/app_update.bin. The example says to use --alt 1 but for some reason that does not work for me. 

  • Hi,

    I only tested with BLE using the nRF connect android app, so I will try set up a test with dfu-util as well to see if I run into the same issue. But I can't promise that I will get time for that tomorrow, it might have to wait til next week. 

    dhump3 said:
    I did verify that everything was still working when I do not use external flash.

     This helps narrow it down, thanks.

  • Update: I have gone back to mcumgr to try and get more information on the images. I first flash an image of version 0.2.0 and then I get this output when I run mcumgr image list:

    Images:
     image=0 slot=0
        version: 0.2.0
        bootable: true
        flags: active confirmed
        hash: 1a55d38e4c3fff9c68e13274b534664a06e976726b7081812d2698b21fb4105e

    I then upload an image of version 0.3.0 to the secondary slot of the device and get this output:

    Images:
     image=0 slot=0
        version: 0.2.0
        bootable: true
        flags: active confirmed
        hash: 1a55d38e4c3fff9c68e13274b534664a06e976726b7081812d2698b21fb4105e
      image=0 slot=1
        version: 0.3.0
        bootable: true
        flags: 
        hash: adf638ddfb17699d45d2b4fe6c340db5ab4f7504655f3a728982d087cd345dd8

    I then test the new image and get the following output from the bootloader:

    *** Booting Zephyr OS build v2.4.0-ncs1  **
    [00:00:00.253,601] <inf> mcuboot: Starting bootloader
    [00:00:00.254,364] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.254,364] <inf> mcuboot: Boot source: none
    [00:00:00.255,004] <inf> mcuboot: Swap type: test
    [00:00:22.608,764] <err> mcuboot: Image in the primary slot is not valid!
    [00:00:22.608,764] <err> mcuboot: Unable to find bootable image

    At this point the device is pretty much bricked, so I just end up flashing the version 0.3.0 image via nrfjprog to device. I decided to re run the image list command to see what was going on and get this:

    Images:
     image=0 slot=0
        version: 0.3.0
        bootable: true
        flags: active confirmed
        hash: adf638ddfb17699d45d2b4fe6c340db5ab4f7504655f3a728982d087cd345dd8
     image=0 slot=1
        version: 0.2.0
        bootable: true
        flags:
        hash: 2ef9a81cbe11a728a774bedb3ffeb7c66a01b8823693a82b166fa66cf1d26c74

    It seems it actually did try to swap the images as image 0.2.0 is now in slot 1. However the hash is completely different which must mean something went wrong in the swapping of the images. Just to see what happens, I then test the slot 1 image (0.2.0) and get this output from the bootloader:

    *** Booting Zephyr OS build v2.4.0-ncs1  **
    [00:00:00.253,631] <inf> mcuboot: Starting bootloader
    [00:00:00.254,394] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.254,394] <inf> mcuboot: Boot source: none
    [00:00:00.255,035] <inf> mcuboot: Swap type: test
    [00:00:09.016,571] <err> mcuboot: Image in the secondary slot is not valid!
    Mcuboot recognizes the secondary image is invalid, deletes it and then it boots up the primary slot. Running image list now gives me:

    Images:
     image=0 slot=0
        version: 0.3.0
        bootable: true
        flags: active confirmed
        hash: adf638ddfb17699d45d2b4fe6c340db5ab4f7504655f3a728982d087cd345dd8
    Split status: N/A (0)

    I'm not entirely sure whats going on here but hopefully this extra detail can help narrow down the issue.

Related