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
  • Ok, I understand. I belive I should have the enough information to try replicate the problem on my end, and  I expect to have an update for you tomorrow.

  • 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.

Related