nRF5340 Firmware Update from external NOR QSPI flash

Hi

I have gone through the following link and I have working firmware OTA update with BLE SMP.
https://devzone.nordicsemi.com/guides/nrf-connect-sdk-guides/b/software/posts/ncs-dfu#http_dfu_ext_flash

But my device design also has a cloud connection via nRF9160. Following is the complete connection diagram.

Cloud<==HTTPS==> nRF9160 <== UART ==> nRF5340 <== QSPI ==> NOR flash

My requirement is to receive the firmware update file via HTTPS to nRF9160 and it will be transmitted to nRF5340 and eventually will be written in NOR flash.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
external_flash:
address: 0x0
end_address: 0x200000
region: external_flash
size: 0x200000
mcuboot_secondary:
address: 0x00000
device: mx25r16
end_address: 0xf4000
region: external_flash
size: 0xf4000
littlefs_storage:
address: 0x100000
device: mx25r16
region: external_flash
size: 0x200000
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

My understanding is I will need to enable the QSPI flash access in Mcuboot by adding following lines to the file "/child_image/mcuboot/prj.conf"

Fullscreen
1
2
3
# SPI Flash
CONFIG_SPI=y
CONFIG_NORDIC_QSPI_NOR=y
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Then write the firmware update file "app_update.bin" in the external NOR flash partition "mcuboot_secondary". File packets will be received over UART and then written via flash write operation. Once file write is complete I will need to restart the SOC.
Is my understanding correct? Also, will I need to update any other flag or message to start firmware update on reboot?

Many Thanks

Parents
  • Hi,

    Yes, your understanding seems correct. Note that this scheme is not officially fully supported yet, but there is a PR here that adds support for this:

    https://github.com/nrfconnect/sdk-nrf/pull/8839

  • I facing the following error while compiling the source code. I am not sure what setting I need to update. 

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    C:/Users/Dilawar_Ali/ncs/v2.1.2/nrf/modules/mcuboot/hooks/nrf53_hooks.c: In function 'boot_read_image_header_hook':
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:28:28: error: 'PM_MCUBOOT_PRIMARY_1_ADDRESS' undeclared (first use in this function); did you mean 'PM_MCUBOOT_PRIMARY_ADDRESS'?
    28 | img_head->ih_load_addr = PM_MCUBOOT_PRIMARY_1_ADDRESS;
    | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    | PM_MCUBOOT_PRIMARY_ADDRESS
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:28:28: note: each undeclared identifier is reported only once for each function it appears in
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:29:27: error: 'PM_CPUNET_APP_SIZE' undeclared (first use in this function)
    29 | img_head->ih_img_size = PM_CPUNET_APP_SIZE;
    | ^~~~~~~~~~~~~~~~~~
    In file included from C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\toolchain\gcc.h:88,
    from C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\toolchain.h:50,
    from C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\sys\__assert.h:11,
    from C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\lib\libc\minimal\include\assert.h:11,
    from C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:7:
    C:/Users/Dilawar_Ali/ncs/v2.1.2/nrf/modules/mcuboot/hooks/nrf53_hooks.c: In function 'network_core_update':
    C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\device.h:96:39: error: '__device_dts_ord_DT_N_NODELABEL_PM_MCUBOOT_PRIMARY_1_DEV_ORD' undeclared (first use in this function)
    96 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
    | ^~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\device.h:276:37: note: in expansion of macro 'DEVICE_NAME_GET'
    276 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_NAME(node_id))
    | ^~~~~~~~~~~~~~~
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Adding changes as per suggested in above links. The issue related to PM_MCUBOOT_PRIMARY_1_ADDRESS is resolved. But now I am facing following error.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    C:/Users/Dilawar_Ali/ncs/v2.2.0/nrf/modules/mcuboot/hooks/nrf53_hooks.c: In function 'boot_read_image_header_hook':
    C:\Users\Dilawar_Ali\ncs\v2.2.0\nrf\modules\mcuboot\hooks\nrf53_hooks.c:29:41: error: 'PM_CPUNET_APP_SIZE' undeclared (first use in this function)
    29 | img_head->ih_img_size = PM_CPUNET_APP_SIZE;
    | ^~~~~~~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.2.0\nrf\modules\mcuboot\hooks\nrf53_hooks.c:29:41: note: each undeclared identifier is reported only once for each function it appears in
    C:/Users/Dilawar_Ali/ncs/v2.2.0/nrf/modules/mcuboot/hooks/nrf53_hooks.c: In function 'network_core_update':
    C:\Users\Dilawar_Ali\ncs\v2.2.0\nrf\modules\mcuboot\hooks\nrf53_hooks.c:98:34: error: 'PM_CPUNET_B0N_ADDRESS' undeclared (first use in this function)
    98 | if (reset_addr > PM_CPUNET_B0N_ADDRESS) {
    | ^~~~~~~~~~~~~~~~~~~~~
    [165/283] Linking C static library zephyr\lib\libc\minimal\liblib__libc__minimal.a
    [166/283] Building C object modules/nrf/lib/fatal_error/CMakeFiles/..__nrf__lib__fatal_error.dir/fatal_error.c.obj
    [167/283] Building C object modules/nrf/subsys/fw_info/CMakeFiles/..__nrf__subsys__fw_info.dir/fw_info.c.obj
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I am trying to compile the Hello World example https://github.com/simon-iversen/sdk-zephyr/tree/serial_dfu_ext_flash_hello_world/samples/hello_world to make the secure boot work with external flash.

    This is the prj.conf

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # nothing here
    # Enable mcumgr.
    CONFIG_MCUMGR=y
    # Enable most core commands.
    CONFIG_MCUMGR_CMD_IMG_MGMT=y
    CONFIG_MCUMGR_CMD_OS_MGMT=y
    CONFIG_SECURE_BOOT=y
    # Ensure an MCUboot-compatible binary is generated.
    CONFIG_BOOTLOADER_MCUBOOT=y
    # Enable the serial mcumgr transport.
    CONFIG_MCUMGR_SMP_UART=y
    # Disable UART Console and enable the RTT console
    CONFIG_UART_CONSOLE=n
    CONFIG_RTT_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This is cihild_image/mcuboot/prj.conf

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # MCUboot requires a large stack size, otherwise an MPU fault will occur
    CONFIG_MAIN_STACK_SIZE=10240
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x10000
    CONFIG_DEBUG_OPTIMIZATIONS=y
    # Enable flash operations
    CONFIG_FLASH=y
    # This must be increased to accommodate the bigger images.
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    #---------------------------------------------------------------------
    CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y
    # The following configurations are required to support simultaneous multi image update
    CONFIG_PCD_APP=n
    CONFIG_UPDATEABLE_IMAGE_NUMBER=2
    CONFIG_FLASH_SIMULATOR=y
    CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
    CONFIG_FLASH_SIMULATOR_STATS=n
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This is pm_static.yml

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    external_flash:
    address: 0x0
    end_address: 0x200000
    region: external_flash
    size: 0x200000
    mcuboot_secondary:
    address: 0x00000
    device: mx25r16
    end_address: 0xFFFFF
    region: external_flash
    size: 0x100000
    mcuboot_primary_1:
    address: 0x0
    size: 0x40000
    device: flash_ctrl
    region: ram_flash
    mcuboot_secondary_1:
    address: 0x100000
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    After build (ended with error) following build/partitions.yml was generated

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    EMPTY_0:
    address: 0x18200
    end_address: 0x1c000
    placement:
    before:
    - s1_pad
    region: flash_primary
    size: 0x3e00
    EMPTY_1:
    address: 0x2c200
    end_address: 0x30000
    placement:
    before:
    - mcuboot_pad
    region: flash_primary
    size: 0x3e00
    app:
    address: 0x30200
    end_address: 0x100000
    region: flash_primary
    size: 0xcfe00
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi,

    Try setting 

    CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y
    Also the discussions in this post here seems relevant for your use-case:
  • setting CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y did not resolve the issue. Still facing the error "error: 'PM_CPUNET_APP_SIZE' undeclared"

    But Setting the CONFIG_BOOT_IMAGE_ACCESS_HOOKS=n and removed the primary_1 and secondary_1 partition. This way I am able to do DFU update for app core from external flash and secure boot enabled.

    I still need assistance to enable netcore image update as well.

  • Dilawar Ali said:
    I still need assistance to enable netcore image update as well.

    There are some known issues with NSIB(secure boot)+MCUBOOT and incompatible with multi image DFU on nRF53, that are getting fixed in the upcoming NCS v2.3.0 release. Relevant PR: https://github.com/nrfconnect/sdk-nrf/pull/9169/files#diff-3618c46f4d0a530f32e99d83263fe217269f73f927f5c110f8aed6db3b8800db

  • After a whole lot of trial and error, I managed to get my firmware to compile with the two-stage bootloader + network core update + mcuboot_secondary on external flash.

    First, I copied partitions.yml into pm_static_<custom-board-name>_cpuapp.yml, and added this to the end:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    mcuboot_primary_1:
    address: 0x0
    device: flash_ctrl
    end_address: 0x40000
    region: ram_flash
    size: 0x40000
    mcuboot_secondary_1:
    address: 0xce000
    device: MX25R64
    end_address: 0x10e000
    region: external_flash
    size: 0x40000
    ram_flash:
    address: 0x40000
    end_address: 0x40000
    region: ram_flash
    size: 0x0
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I added these flags to my prj.conf:

    Fullscreen
    1
    2
    3
    4
    5
    6
    CONFIG_NRF53_UPGRADE_NETWORK_CORE=y
    CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    CONFIG_ADD_MCUBOOT_MEDIATE_SIM_FLASH_DTS=y
    CONFIG_SECURE_BOOT=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I added these flags to my mcuboot.conf:

    Fullscreen
    1
    2
    3
    4
    5
    6
    CONFIG_PCD_APP=y
    CONFIG_UPDATEABLE_IMAGE_NUMBER=2
    CONFIG_FLASH_SIMULATOR=y
    CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
    CONFIG_FLASH_SIMULATOR_STATS=n
    CONFIG_BOOT_UPGRADE_ONLY=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    For some reason, setting CONFIG_BOOT_UPGRADE_ONLY=n makes it explode with the error 'PM_MCUBOOT_PRIMARY_1_ADDRESS' undeclared. If someone knows why this is happening, I'm all ears.

    In a nutshell, I'm pretty sure this is what you have to do to make it work:

    • DO NOT name the static partition file pm_static.yml, name it pm_static_<boardname>_cpuapp.yml
    • CONFIG_BOOT_UPGRADE_ONLY must be set to 'y' for some reason
    • Set ADD_MCUBOOT_MEDIATE_SIM_FLASH_DTS to import the flash simulator into your device tree

    Now to see if it actually runs.

Reply
  • After a whole lot of trial and error, I managed to get my firmware to compile with the two-stage bootloader + network core update + mcuboot_secondary on external flash.

    First, I copied partitions.yml into pm_static_<custom-board-name>_cpuapp.yml, and added this to the end:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    mcuboot_primary_1:
    address: 0x0
    device: flash_ctrl
    end_address: 0x40000
    region: ram_flash
    size: 0x40000
    mcuboot_secondary_1:
    address: 0xce000
    device: MX25R64
    end_address: 0x10e000
    region: external_flash
    size: 0x40000
    ram_flash:
    address: 0x40000
    end_address: 0x40000
    region: ram_flash
    size: 0x0
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I added these flags to my prj.conf:

    Fullscreen
    1
    2
    3
    4
    5
    6
    CONFIG_NRF53_UPGRADE_NETWORK_CORE=y
    CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    CONFIG_ADD_MCUBOOT_MEDIATE_SIM_FLASH_DTS=y
    CONFIG_SECURE_BOOT=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I added these flags to my mcuboot.conf:

    Fullscreen
    1
    2
    3
    4
    5
    6
    CONFIG_PCD_APP=y
    CONFIG_UPDATEABLE_IMAGE_NUMBER=2
    CONFIG_FLASH_SIMULATOR=y
    CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
    CONFIG_FLASH_SIMULATOR_STATS=n
    CONFIG_BOOT_UPGRADE_ONLY=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    For some reason, setting CONFIG_BOOT_UPGRADE_ONLY=n makes it explode with the error 'PM_MCUBOOT_PRIMARY_1_ADDRESS' undeclared. If someone knows why this is happening, I'm all ears.

    In a nutshell, I'm pretty sure this is what you have to do to make it work:

    • DO NOT name the static partition file pm_static.yml, name it pm_static_<boardname>_cpuapp.yml
    • CONFIG_BOOT_UPGRADE_ONLY must be set to 'y' for some reason
    • Set ADD_MCUBOOT_MEDIATE_SIM_FLASH_DTS to import the flash simulator into your device tree

    Now to see if it actually runs.

Children
No Data