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.

  • Hi,

    Sorry for the delayed response. Have you had any progress since you posted this? If not, I'll try to set aside time to try it out here. I  belive SPI flash should be supported.

    Also, just to confirm, are you testing with NCS v.1.4.0 (it inclues zephyr v2.4.0 if I recall correctly)

    Best regards,

    Vidar

  • Hi,

    Unfortunately, I have not made any progress on this and feel like I have hit a wall. I am testing with NCS v1.4.0. Is there any other information you would like that you think would be useful? I can try to put some more log statements in the bootloader.

    Thanks 

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

Related