No merged.hex file when using ncs v3.3.0 without partition manager

Hello everyone,

I’m currently porting my old projects from NCS version 2.9.0 to 3.3.0.

In doing so, I no longer want to use the outdated Partition Manager; instead, I want to use Zephyr’s default device tree-based memory partitioning.

I converted my project following these instructions and successfully built it.

However, I am now missing the merged.hex and merged_CPUNET.hex files, which combine the bootloader and the application code. I need these files for our production to perform the “initial” programming of the devices.

Is it possible that the current toolchain (v3.3.0) doesn't yet support the merge process?

I also tried the conversion using a new/empty project from DevAcademy (l9/e5)—with the same result.

Parents
  • You have to add this config to your sysbuild.conf:

    SB_CONFIG_MERGED_HEX_FILES=y
  • That results in with NCS 3.4.0:

    "../merged_nrf9160dk_0_14_0_nrf9160.hex"

    is there a way to go back to "merged.hex"?

    Edited:

    Even worser, I don't see the "merged.hex" from before, there are now two 

    merged_nrf9160dk_0_14_0_nrf9160_ns.hex

    merged_nrf9160dk_0_14_0_nrf9160.hex

    I guess, it's now intended to have them merged by the customer ... 

  • Hi.

    I wanted to share some insight after experimenting with this for a while, since it's not exactly straight forward.

    I run a NSIB+Upgradable MCUBoot+Upgradable app, using sysbuild, non-secure board variant, dts-style partition configuration on the nRF54L15, where keys are provisioned to the KMU. This configuration might sound specific, but it's Nordic's recommended configuration for a secure app setup (CRA compliance etc.). This results in 6 separate images, that can be compacted into two (like Achim Kraus experienced) using SB_CONFIG_MERGED_HEX_FILES=y.

    However, using nrfutil device program on each image separately will overwrite the others, so they need to be merged like Achim Kraus stated ({ZEPHYR_BASE}/scripts/build/mergehex.py). However, unlike "west flash", the order of operations with nrfutil device program (and nrfjprog most likely) is essential. KMU provision must be done after nrfutil device program merged.hex, otherwise it will overwrite KMU and NSIB won't boot MCUBoot. Furthermore, after flashing merged.hex it is important to ensure that no reset happens, since that could also cause invalidation of images. I.e. merge, flash, provision.

    The process of merging into a merged.hex can also be automated through CMake, although it is a bit tedious. I hope Nordic provide an easier way to do this in an upcoming SDK release. Since SB_CONFIG_MERGED_HEX_FILES=y adds the board name to the hex name, I found it easier to set SB_CONFIG_MERGED_HEX_FILES=n, and select the images I needed individually. Please see the CMake snippet below (I have this at the end of my sysbuild/CMakeLists.txt) and adjust output directory, input files and PROJECTNR_APP_NAME according to needs:

    # Set the output directory for merged.hex
    set(OUTPUT_DIR "${CMAKE_CURRENT_LIST_DIR}/../built_images")
    # Set build root
    set(BUILD_ROOT "${CMAKE_CURRENT_BINARY_DIR}/..")
    
    # Find python installation
    if(DEFINED WEST_PYTHON AND EXISTS "${WEST_PYTHON}")
      set(MERGEHEX_PYTHON_EXECUTABLE "${WEST_PYTHON}")
    else()
      find_package(Python3 3.10 COMPONENTS Interpreter REQUIRED)
      set(MERGEHEX_PYTHON_EXECUTABLE "${Python3_EXECUTABLE}")
    endif()
    
    # Set images to merge
    set(MERGED_HEX_INPUTS
      ${BUILD_ROOT}/b0/zephyr/zephyr.hex
      ${BUILD_ROOT}/signed_by_b0_mcuboot.hex
      ${BUILD_ROOT}/signed_by_b0_mcuboot_s1_variant.hex
      ${BUILD_ROOT}/PROJECTNR_APP_NAME/zephyr/zephyr.signed.hex
      ${BUILD_ROOT}/app_provision.hex
      ${BUILD_ROOT}/bootconf.hex
    )
    
    # Merge
    add_custom_target(merge_built_images ALL
      COMMAND "${MERGEHEX_PYTHON_EXECUTABLE}" $ENV{ZEPHYR_BASE}/scripts/build/mergehex.py
        -o ${OUTPUT_DIR}/merged.hex --overlap error ${MERGED_HEX_INPUTS}
      DEPENDS ${MERGED_HEX_INPUTS}
      COMMENT "Merging b0 + MCUboot (s0/s1) + application + provisioning + bootconf into ${OUTPUT_DIR}/merged.hex"
    )

Reply
  • Hi.

    I wanted to share some insight after experimenting with this for a while, since it's not exactly straight forward.

    I run a NSIB+Upgradable MCUBoot+Upgradable app, using sysbuild, non-secure board variant, dts-style partition configuration on the nRF54L15, where keys are provisioned to the KMU. This configuration might sound specific, but it's Nordic's recommended configuration for a secure app setup (CRA compliance etc.). This results in 6 separate images, that can be compacted into two (like Achim Kraus experienced) using SB_CONFIG_MERGED_HEX_FILES=y.

    However, using nrfutil device program on each image separately will overwrite the others, so they need to be merged like Achim Kraus stated ({ZEPHYR_BASE}/scripts/build/mergehex.py). However, unlike "west flash", the order of operations with nrfutil device program (and nrfjprog most likely) is essential. KMU provision must be done after nrfutil device program merged.hex, otherwise it will overwrite KMU and NSIB won't boot MCUBoot. Furthermore, after flashing merged.hex it is important to ensure that no reset happens, since that could also cause invalidation of images. I.e. merge, flash, provision.

    The process of merging into a merged.hex can also be automated through CMake, although it is a bit tedious. I hope Nordic provide an easier way to do this in an upcoming SDK release. Since SB_CONFIG_MERGED_HEX_FILES=y adds the board name to the hex name, I found it easier to set SB_CONFIG_MERGED_HEX_FILES=n, and select the images I needed individually. Please see the CMake snippet below (I have this at the end of my sysbuild/CMakeLists.txt) and adjust output directory, input files and PROJECTNR_APP_NAME according to needs:

    # Set the output directory for merged.hex
    set(OUTPUT_DIR "${CMAKE_CURRENT_LIST_DIR}/../built_images")
    # Set build root
    set(BUILD_ROOT "${CMAKE_CURRENT_BINARY_DIR}/..")
    
    # Find python installation
    if(DEFINED WEST_PYTHON AND EXISTS "${WEST_PYTHON}")
      set(MERGEHEX_PYTHON_EXECUTABLE "${WEST_PYTHON}")
    else()
      find_package(Python3 3.10 COMPONENTS Interpreter REQUIRED)
      set(MERGEHEX_PYTHON_EXECUTABLE "${Python3_EXECUTABLE}")
    endif()
    
    # Set images to merge
    set(MERGED_HEX_INPUTS
      ${BUILD_ROOT}/b0/zephyr/zephyr.hex
      ${BUILD_ROOT}/signed_by_b0_mcuboot.hex
      ${BUILD_ROOT}/signed_by_b0_mcuboot_s1_variant.hex
      ${BUILD_ROOT}/PROJECTNR_APP_NAME/zephyr/zephyr.signed.hex
      ${BUILD_ROOT}/app_provision.hex
      ${BUILD_ROOT}/bootconf.hex
    )
    
    # Merge
    add_custom_target(merge_built_images ALL
      COMMAND "${MERGEHEX_PYTHON_EXECUTABLE}" $ENV{ZEPHYR_BASE}/scripts/build/mergehex.py
        -o ${OUTPUT_DIR}/merged.hex --overlap error ${MERGED_HEX_INPUTS}
      DEPENDS ${MERGED_HEX_INPUTS}
      COMMENT "Merging b0 + MCUboot (s0/s1) + application + provisioning + bootconf into ${OUTPUT_DIR}/merged.hex"
    )

Children
No Data
Related