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.

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

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"

# SPI Flash
CONFIG_SPI=y
CONFIG_NORDIC_QSPI_NOR=y

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. 

    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))
          |                                     ^~~~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\device.h:296:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      296 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:85:19: note: in expansion of macro 'DEVICE_DT_GET'
       85 |  mock_flash_dev = DEVICE_DT_GET(DT_NODELABEL(PM_MCUBOOT_PRIMARY_1_DEV));
          |                   ^~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:98:20: error: 'PM_CPUNET_B0N_ADDRESS' undeclared (first use in this function)
       98 |   if (reset_addr > PM_CPUNET_B0N_ADDRESS) {
          |                    ^~~~~~~~~~~~~~~~~~~~~
    [171/289] Building C object zephyr/drivers/pinctrl/CMakeFiles/drivers__pinctrl.dir/pinctrl_nrf.c.obj
    [172/289] Building C object modules/nrf/lib/fatal_error/CMakeFiles/..__nrf__lib__fatal_error.dir/fatal_error.c.obj
    [173/289] Linking C static library zephyr\drivers\flash\libdrivers__flash.a
    [174/289] Building C object modules/nrf/subsys/fw_info/CMakeFiles/..__nrf__subsys__fw_info.dir/fw_info.c.obj
    [175/289] Building C object modules/nrf/drivers/hw_cc310/CMakeFiles/..__nrf__drivers__hw_cc310.dir/hw_cc310.c.obj
    [176/289] Building C object modules/mbedtls/CMakeFiles/modules__mbedtls.dir/zephyr_init.c.obj
    [177/289] Linking C static library zephyr\drivers\serial\libdrivers__serial.a
    [178/289] Building C object modules/mbedtls/CMakeFiles/modules__mbedtls.dir/C_/Users/Dilawar_Ali/ncs/v2.1.2/modules/crypto/mbedtls/library/aes.c.obj
    [179/289] Linking C static library zephyr\drivers\timer\libdrivers__timer.a
    ninja: build stopped: subcommand failed.
    [341/382] Linking C executable zephyr\zephyr_pre0.elf
    
    [345/382] Linking C executable zephyr\zephyr_pre1.elf

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

    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))
          |                                     ^~~~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\zephyr\include\zephyr\device.h:296:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      296 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:85:19: note: in expansion of macro 'DEVICE_DT_GET'
       85 |  mock_flash_dev = DEVICE_DT_GET(DT_NODELABEL(PM_MCUBOOT_PRIMARY_1_DEV));
          |                   ^~~~~~~~~~~~~
    C:\Users\Dilawar_Ali\ncs\v2.1.2\nrf\modules\mcuboot\hooks\nrf53_hooks.c:98:20: error: 'PM_CPUNET_B0N_ADDRESS' undeclared (first use in this function)
       98 |   if (reset_addr > PM_CPUNET_B0N_ADDRESS) {
          |                    ^~~~~~~~~~~~~~~~~~~~~
    [171/289] Building C object zephyr/drivers/pinctrl/CMakeFiles/drivers__pinctrl.dir/pinctrl_nrf.c.obj
    [172/289] Building C object modules/nrf/lib/fatal_error/CMakeFiles/..__nrf__lib__fatal_error.dir/fatal_error.c.obj
    [173/289] Linking C static library zephyr\drivers\flash\libdrivers__flash.a
    [174/289] Building C object modules/nrf/subsys/fw_info/CMakeFiles/..__nrf__subsys__fw_info.dir/fw_info.c.obj
    [175/289] Building C object modules/nrf/drivers/hw_cc310/CMakeFiles/..__nrf__drivers__hw_cc310.dir/hw_cc310.c.obj
    [176/289] Building C object modules/mbedtls/CMakeFiles/modules__mbedtls.dir/zephyr_init.c.obj
    [177/289] Linking C static library zephyr\drivers\serial\libdrivers__serial.a
    [178/289] Building C object modules/mbedtls/CMakeFiles/modules__mbedtls.dir/C_/Users/Dilawar_Ali/ncs/v2.1.2/modules/crypto/mbedtls/library/aes.c.obj
    [179/289] Linking C static library zephyr\drivers\timer\libdrivers__timer.a
    ninja: build stopped: subcommand failed.
    [341/382] Linking C executable zephyr\zephyr_pre0.elf
    
    [345/382] Linking C executable zephyr\zephyr_pre1.elf

Children
  • Do you have CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY set to y?

  • Yes,  "CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y" is set in prj.conf

  • I see that you are using NCS v2.1.2

    Do you get the same issue with NCS v2.2.0?

  • Moving to NCS v2.2.0 is causing lot of compilation issues related to include path. At this moment this is not a feasible solution for me.

    I am trying with NCS v2.1.2. If I disable the secure boot and s1 image configuration by commenting out following lines. Then project compiles fine. But the application is not able to boot up.

    CONFIG_SECURE_BOOT=y
    CONFIG_SB_SIGNING_KEY_FILE="bootloaderKeys/SecureBootPrivateKey_Development.pem"
    
    CONFIG_BUILD_S1_VARIANT=y

    Right now this is my prj.conf 

    CONFIG_BT_RPMSG=n
    CONFIG_NCS_INCLUDE_RPMSG_CHILD_IMAGE=n
    
    CONFIG_BT=y
    CONFIG_BT_DEBUG_LOG=y
    CONFIG_BT_SMP=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_BAS=y
    CONFIG_BT_HRS=n
    
    CONFIG_BT_DIS=y
    
    
    # enable I2C
    CONFIG_I2C=y
    
    #CONFIG_BT_CTLR=y
    #CONFIG_BT_LL_SW_SPLIT=y
    #CONFIG_BT_CTLR_ADVANCED_FEATURES=y
    #CONFIG_BT_CTLR_CONN_RSSI=y
    #CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y
    
    CONFIG_BT_DEVICE_APPEARANCE=833
    
    CONFIG_DEBUG_OPTIMIZATIONS=y
    CONFIG_DEBUG_THREAD_INFO=y
    
    # Config RTT logger
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_UART_CONSOLE=n
    
    # SPI Flash
    CONFIG_SPI=y
    CONFIG_NORDIC_QSPI_NOR=y
    
    # Enable flash operations.
    CONFIG_FLASH=y
    CONFIG_FLASH_MAP=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    
    
    # Enable the LittleFS file system.
    CONFIG_FILE_SYSTEM=y
    CONFIG_FILE_SYSTEM_LITTLEFS=y
    
    # Enable Zephyr application to be booted by MCUboot
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    
    # Enable ADC controller for battery monitoring.
    CONFIG_ADC=y
    
    # fs_dirent structures are big.
    CONFIG_MAIN_STACK_SIZE=8192
    # Let __ASSERT do its job
    CONFIG_DEBUG=y
    
    #Enable RTC0 counter
    CONFIG_COUNTER=y
    CONFIG_COUNTER_RTC0=y
    
    # UART
    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    
    #Enable watchdog Timer
    CONFIG_WATCHDOG=y
    CONFIG_WDT_LOG_LEVEL_DBG=y
    CONFIG_WDT_DISABLE_AT_BOOT=n
    
    
    #- Secure Boot Config -----------------------------------------------------
    
    # 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
    # CONFIG_SB_SIGNING_KEY_FILE="bootloaderKeys/SecureBootPrivateKey_Development.pem"
    
    # Enable Zephyr application to be booted by MCUboot
    # CONFIG_BUILD_S1_VARIANT=y
    
    # Allow for large Bluetooth data packets.
    # CONFIG_BT_L2CAP_TX_MTU=262
    # CONFIG_BT_BUF_ACL_RX_SIZE=256
    
    CONFIG_BT_BUF_ACL_RX_SIZE=251
    CONFIG_BT_BUF_ACL_TX_SIZE=251
    CONFIG_BT_L2CAP_TX_MTU=247
    # CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
    
    # Enable the Bluetooth (unauthenticated) and shell mcumgr transports.
    CONFIG_MCUMGR_SMP_BT=y
    CONFIG_MCUMGR_SMP_BT_AUTHEN=n
    
    # Some command handlers require a large stack.
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    #- End Secure Boot Config -----------------------------------------------------

    This is /child_image/mcuboot/prj.conf

    # MCUboot requires a large stack size, otherwise an MPU fault will occur
    CONFIG_MAIN_STACK_SIZE=10240
    CONFIG_DEBUG_OPTIMIZATIONS=y
    
    # This must be increased to accommodate the bigger images.
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    
    CONFIG_LOG=y
    CONFIG_LOG_MODE_MINIMAL=y 
    ### Ensure Zephyr logging changes don't use more resources
    CONFIG_LOG_DEFAULT_LEVEL=0
    ### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y
    CONFIG_CBPRINTF_NANO=y
    
    
    
    
    
    #---------------------------------------------------------
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0xFF00
    
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
    
    # Enable flash operations.
    CONFIG_FLASH=y
    
    # Ensure an MCUboot-compatible binary is generated.
    CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
    CONFIG_BOOT_SIGNATURE_KEY_FILE="../../bootloaderKeys/McuBootPrivateKey_Development.pem"
    

    this is pm_static.yml

    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
    
    littlefs_storage:
      address: 0x100000
      device: mx25r16
      region: external_flash
      size: 0x100000
      
    

    Can you please help me out to find what am I doing wrong?

    Thanks

  • Are you building the sample in samples/dfu/nrf5340 ?

Related