Multi-Image FOTA on nRF5340 Using External NAND Flash (App + Net Core)

Hi Nordic team,

We’ve implemented a custom firmware update flow for our nRF5340-based device, which supports a robust single-image FOTA process using external NAND flash. The update is downloaded via HTTPS (using fota_download), written to NAND via stream_flash, and installed using MCUboot on the next reboot.

Now we want to extend this flow to support coordinated multi-image updates — specifically App Core and Network Core firmware — with atomic validation and rollback behavior.


Current Setup

  • Device: nRF5340 (custom hardware)

  • Storage: External NAND flash via QSPI

  • Transport: Firmware is downloaded via HTTPS using fota_download

  • Bootloader: MCUboot

  • Flow:

    • Image is stored in NAND (not internal flash)

    • Reboot is triggered via sys_reboot(SYS_REBOOT_COLD)

    • MCUboot detects new image in NAND and swaps it on boot

    • Image is confirmed using boot_write_img_confirmed() if successful

We also have a manual firmware_reswap() function using boot_request_upgrade() for triggering updates when needed, but this is not part of our automated FOTA path.


Multi-Image FOTA Goal

We want to:

  • Download two images (App Core and Net Core) and store both in external NAND

  • Validate both images before allowing any upgrade

  • Only proceed if both are valid

  • Trigger a coordinated update through MCUboot

  • Ensure that if either image fails to install or boot, both are rolled back


Open Questions

  1. MCUboot + External Flash + Multi-Image:
    Can MCUboot handle multi-image updates from external NAND using:

    kconfig
    KopierenBearbeiten
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y CONFIG_NRF53_MULTI_IMAGE_UPDATE=y CONFIG_NRF53_UPGRADE_NETWORK_CORE=y

    Is this officially supported in conjunction with stream_flash and external slots?

  2. Download strategy:
    Would you recommend:

    • Downloading and storing two separate images independently?

    • Or combining them into a single bundle to unpack after download?

  3. Partitioning and mapping:
    What’s the cleanest way to define partition layout (e.g., via pm_static.yml) to store both images in NAND and allow MCUboot to find them?

  4. Image validation:
    What’s the best practice to ensure both images are valid before rebooting?
    Should we compute and compare hashes manually, or use image manager APIs?

  5. Rollback consistency:
    How do we ensure both images are rolled back if one fails post-upgrade?
    Does MCUboot handle this natively in multi-image mode, or do we need additional coordination?

  6. General advice:
    Are there known limitations, recommended patterns, or pitfalls when doing multi-image OTA updates from NAND flash on the nRF5340?


We’re open to customizing parts of this logic ourselves if needed, but would prefer to stick to supported MCUboot patterns where possible.

Thanks in advance for your help and insights!

Best regards,
Lucas

Parents
  • Hi,

    MCUboot + External Flash + Multi-Image:
    Can MCUboot handle multi-image updates from external NAND using:

    kconfig
    KopierenBearbeiten
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y CONFIG_NRF53_MULTI_IMAGE_UPDATE=y CONFIG_NRF53_UPGRADE_NETWORK_CORE=y

    Is this officially supported in conjunction with stream_flash and external slots?

    Specifically, MCUboot calls nrf53_hooks.c when doing the dual core swapping. Here, it will perform PCD swap to netcore when the data is swapped from mcuboot_secondary to mcuboot_primary.

    I cannnot see any flash operations here, so I guess that will be handled by mcuboot itself. I think MCUboot uses boot_copy_region(), which uses flash_area_write().

    So I guess the answer would be "no, stream_flash is not supported as such".

    Would you recommend:

    • Downloading and storing two separate images independently?

    • Or combining them into a single bundle to unpack after download?

    Our existing solutions stores two separate images (mcuboot_secondary and mcuboot_secondary_1). See https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-9-bootloaders-and-dfu-fota/topic/dfu-for-the-nrf5340/ for an explanation.

    What’s the cleanest way to define partition layout (e.g., via pm_static.yml) to store both images in NAND and allow MCUboot to find them?

    The partition manager has support for multi-image DFU.

    What’s the best practice to ensure both images are valid before rebooting?
    Should we compute and compare hashes manually, or use image manager APIs?

    I dont think i got a specific recommendation here. Just verify, in whatever way you find best.

    How do we ensure both images are rolled back if one fails post-upgrade?
    Does MCUboot handle this natively in multi-image mode, or do we need additional coordination?

    We do not support rollback for nRF5340 multi-image DFU. Ref Simultaneous multi-image DFU with nRF5340 DK.

    Are there known limitations, recommended patterns, or pitfalls when doing multi-image OTA updates from NAND flash on the nRF5340?

    Here is what I can think of:

    nRF5340 multi-image DFU as support status: Experimental
    Rollback is not supported for nRF5340 multi-image DFU.
    We do not have integrated support for NAND flash, so you will have to figure out the NAND part yourself.
    Check out Known Issues in general

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    just to understand what you stated in your last message:

    We do not have integrated support for NAND flash, so you will have to figure out the NAND part yourself.
    Check out Known Issues in general

    i am using nowadays the SDK 2.7.0 and it seems the bug NCSDK-21379 still exists even if it has been removed from the list of known anomalies.

    According to the link here , the bug NCSDK-21379 should be solved from 2.5.3, but it seems not. Could I please have a feedback from you ?

    Thanks in advance !

    Kind regards

    Riccardo 

  • Unfortunally, I do not have anyhting yet. I will try to get back to you tomorrow or friday

  • From what I can tell, the fix I mentioned was added in v2.5.0, but then there has been a lot of changes to the same file between v2.5.0 and v2.7.0, so we cannot see the fix 1-to-1.

    So let me instead take a step back and check what we really are looking at here:

    Riccardo Gaiati said:

    According to the link here , the bug NCSDK-21379 should be solved from 2.5.3, but it seems not. Could I please have a feedback from you ?

    When you said "it seems not", can you explain how you observe this?

  • Good morning Sigurd,

    thanks a lot for the time spending on this. 

    To your question: i test the firmware upgrade on our project after moving to SDK 2.7.0. At the moment, i am using a single mcuboot slot, so the app and net core update is not simultaneous.

    The problem occurred at the moment of the netcore upgrade. This happens aswell on the sdk 2.1.1 where we introduced the fix mentioned in the link you sent me. I open a couple of tickets in the past regarding this problem.

    Actually i was trying to be kind when i said "it seems not". In reality, from my tests and analysis, the problem has not been addressed. You can see it from the screen-shot i posted in my previous message where i compare the original loader.c file with the fixed one.

    In the original file loader.c at line 1400, secondary_fa->fa_off contains the start offset from the beginning of the external flash memory and the hdr pointer is accessing this address, which does not exist within the memory address of the nrf5340. Despite that, i could see, during debugging, that the firmware was hanging forever within the function pcd_network_core_update(net_core_fw_addr, fw_size)

    Kind regards

    Riccardo 

Reply
  • Good morning Sigurd,

    thanks a lot for the time spending on this. 

    To your question: i test the firmware upgrade on our project after moving to SDK 2.7.0. At the moment, i am using a single mcuboot slot, so the app and net core update is not simultaneous.

    The problem occurred at the moment of the netcore upgrade. This happens aswell on the sdk 2.1.1 where we introduced the fix mentioned in the link you sent me. I open a couple of tickets in the past regarding this problem.

    Actually i was trying to be kind when i said "it seems not". In reality, from my tests and analysis, the problem has not been addressed. You can see it from the screen-shot i posted in my previous message where i compare the original loader.c file with the fixed one.

    In the original file loader.c at line 1400, secondary_fa->fa_off contains the start offset from the beginning of the external flash memory and the hdr pointer is accessing this address, which does not exist within the memory address of the nrf5340. Despite that, i could see, during debugging, that the firmware was hanging forever within the function pcd_network_core_update(net_core_fw_addr, fw_size)

    Kind regards

    Riccardo 

Children
No Data
Related