Sysbuild configuration for a updatable section containing firmware image and meta-data for external component

NCS 2.7

NRF52840

Building with sysbuild, MCUBOOT, and 2 different applications (mfg and end-user)

My custom board includes a sensor fusion IMU from bosch.  The firmware that must be loaded for this IMU is ~133 KB.  My initial development effort embedded the imu firmware into the application image.  The resulting update image consumes more than 50% of the flash space, and therefore would require reserving space in the external flash for updates. 

The IMU is an excellent candidate for independent update.  It has a well defined communication interface that remains constant across versions.  It may also only need 1-2 updates over the product lifecycle.  

I modified my static partition to create a ext_fw partition area to contain the external firmware image. 

xt_fw:
  address: 0xc200
  end_address: 0x2F000
  region: flash_primary
  size: 0x22200
app:
  address: 0x2F000
  end_address: 0x94000
  region: flash_primary
  size: 0x65000
mcuboot:
  address: 0x0
  end_address: 0xc000
  placement:
    before:
    - mcuboot_primary
  region: flash_primary
  size: 0xc000
mcuboot_pad:
  address: 0xc000
  end_address: 0xc200
  placement:
    align:
      start: 0x1000
    before:
    - mcuboot_primary_app
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0xc000
  end_address: 0x94000
  orig_span: &id001
  - mcuboot_pad
  - ext_fw
  - app
  region: flash_primary
  size: 0x88000
  span: *id001
mcuboot_primary_app:
  address: 0xc200
  orig_span: &id002
  - ext_fw
  - app
  region: flash_primary
  size: 0x85E00
  span: *id002
mcuboot_secondary:
  address: 0x94000
  end_address: 0xfa000
  placement:
    after:
    - mcuboot_primary
    align:
      start: 0x1000
  region: flash_primary
  share_size:
  - mcuboot_primary
  size: 0x66000
nvs_storage:
  address: 0xfa000
  end_address: 0x100000
  placement:
    align:
      start: 0x1000
    before:
    - end
  region: flash_primary
  size: 0x6000
sram_primary:
  address: 0x20000000
  end_address: 0x20040000
  region: sram_primary
  size: 0x40000

From the board dts,I defined two zephyr memory regions.  One region holds meta data such as the image size, and external firmware image kernel version and a pointer to the firmware image data.  The other memory region holds the firmware image itself.

  

	flash@C200 {
		compatible = "zephyr,memory-region";
		reg = <0xC200 0x100>;
		zephyr,memory-region = "ext_fw_meta";
		status = "okay";
	};
	flash@C300 {
		compatible = "zephyr,memory-region";
		reg = <0xC300 0x22D00>;
		zephyr,memory-region = "ext_fw_data";
		status = "okay";
	};

I'm trying to figure out how to proceed with sysbuild to add another buildable image.

I added a sysbuild.cmake as documented docs.nordicsemi.com/.../index.html:

ExternalZephyrProject_Add(
	APPLICATION xx_bhi360_ext_fw_xx
	SOURCE_DIR ${ZEPHYR_BASE}/../app.git/bhi360_ext_fw
)

When I run the build by adding a build configuration within VS Code NRF Connect Extension I get an error about that the directory is empty:

-- west build: generating a build system
Loading Zephyr module(s) (Zephyr base): sysbuild_default
-- Found Python3: C:/ncs/toolchains/ce3b5ff664/opt/bin/python.exe (found suitable version "3.9.13", minimum required is "3.8") found components: Interpreter 
-- Cache files will be written to: D:/Flipperz/flipper_workspace/zephyr/.cache
-- Found west (found suitable version "1.2.0", minimum required is "0.14.0")
-- Board: thomas_b, qualifiers: nrf52840
Parsing D:/Flipperz/flipper_workspace/zephyr/share/sysbuild/Kconfig
Loaded configuration 'D:/Flipperz/flipper_workspace/app.git/app/build_1/_sysbuild/empty.conf'
Merged configuration 'D:/Flipperz/flipper_workspace/app.git/app/sysbuild.conf'
Configuration saved to 'D:/Flipperz/flipper_workspace/app.git/app/build_1/zephyr/.config'
Kconfig header saved to 'D:/Flipperz/flipper_workspace/app.git/app/build_1/_sysbuild/autoconf.h'
CMake Error at C:/ncs/toolchains/ce3b5ff664/opt/share/cmake-3.21/Modules/ExternalProject.cmake:2866 (message):
  No download info given for 'bhi360_ext_fw' and its source directory:

   D:/Flipperz/flipper_workspace/app.git/app/build_1/bhi360_ext_fw

  is not an existing non-empty directory.  Please specify one of:

   * SOURCE_DIR with an existing non-empty directory
   * DOWNLOAD_COMMAND
   * URL
   * GIT_REPOSITORY
   * SVN_REPOSITORY
   * HG_REPOSITORY
   * CVS_REPOSITORY and CVS_MODULE
Call Stack (most recent call first):
  C:/ncs/toolchains/ce3b5ff664/opt/share/cmake-3.21/Modules/ExternalProject.cmake:3700 (_ep_add_download_command)
  cmake/modules/sysbuild_extensions.cmake:350 (ExternalProject_Add)
  D:/Flipperz/flipper_workspace/app.git/bhi360_ext_fw/sysbuild.cmake:1 (ExternalZephyrProject_Add)
  cmake/modules/sysbuild_extensions.cmake:670 (include)
  cmake/modules/sysbuild_images.cmake:13 (sysbuild_add_subdirectory)
  cmake/modules/sysbuild_default.cmake:19 (include)
  D:/Flipperz/flipper_workspace/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:75 (include)
  D:/Flipperz/flipper_workspace/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
  D:/Flipperz/flipper_workspace/zephyr/share/sysbuild-package/cmake/SysbuildConfig.cmake:8 (include)
  template/CMakeLists.txt:10 (find_package)


-- 
   *****************************
   * Running CMake for mcuboot *
   *****************************

cmake doesn't seem to be copying the files from app.git/bhi360_ext_fw into the build folder.

Is this a fault in NCS 2.7 sysbuild that might be fixed if I go to a more recent release?

Is there an existing example of using sysbuild to add an additional image?

What configuration will I need to add for mcuboot to be able to update (one-at-a-time) both the application and the ext_fw partition?

  • No the motion fusion IMU does not have NV storage.  The firmware gets loaded at every startup.  The host interface reports whether firmware has been loaded and some version/hash of the image.  If firmware isn't ready or the version/hash don't match the meta data of the image in ext_fw partition, then the driver downloads the data from internal flash to the IMU.  The download takes 30-40 seconds so I try to avoid doing it unless needed.

    I've made progress in getting mcuboot to swap the main application firmware.  I'm implementing this initially with the secondary partitions on the external flash, although this isn't what I really want for the production release. 

    One issue I ran into was a bit surprising.  When performing swap move, mcuboot requires the primary and secondary partition be the nearly the same length, with only the primary being 1 block larger than the secondary.  This seems to be designed around the idea every primary being paired with a corresponding secondary, I suppose so there is always a back-up copy available.  This isn't the way I was intending to use it.  I guess this is necessary because mcuboot doesn't have any information about how much of the secondary partition is actually being used and therefore cannot check if the secondary image would fit into the space of the primary image. 

    I believe it is possible to make mcuboot work with multiple primaries of different sizes and a single secondary, isn't that how updates work with multiple cores?

  • Thanks, I think I have a better understanding of the setup now. MCUboot is generally designed to have one pair of image slots for each firmware image type, which doesn't make sense for the IMU image in this case as it is neither going to be executed or swapped locally. It's made to handle images that are to be run on the same device.

    Our MCUboot fork does include patches that allow the main secondary slot to be reused for MCUboot updates when MCUboot is used as a second stage bootloader, and it should of course be possible to add similar modifications to support your requirements.

    Anthony Ambuehl said:
    This seems to be designed around the idea every primary being paired with a corresponding secondary, I suppose so there is always a back-up copy available

    The CPU will usually be executing code from the primary while the update image is being written to the secondary slot.

Related