nRF5340: MCUboot "Reset address of image in secondary slot is not in the primary slot" error when attempt a multi-core update (NCS 2.4.1)

Hi,

I am writing the firmware for a custom device based on nRF5340 (currently using NCS 2.4.1) and I working on firmware updates After quite a battle with the various configuration options for the application and MCUboot, mcuboot can update both the application core and the network core in serial recovery mode (I'm using CONFIG_NRF53_MULTI_IMAGE_UPDATE=y). However, trying to update the cores via BLE fails:

- I send the dfu_application.zip file from the build folder to my phone.
- I start the nRF Connect Device Manager (version 1.7.0) on my Samsung S20FE Android phone (running Android 13)
- The device is detected, so I select it and go to the firmware upload page (the second icon on the left in the bottom bar)
- "Select file" -> I select the dfu_application.zip image that I sent to my phone. The app correctly reports both the images (app core and net core) in this zip file.
- "Start" -> "Confirm only" (according to https://github.com/NordicSemiconductor/Android-nRF-Connect-Device-Manager , "Devices based on nRF5340 SoC support only CONFIRM_ONLY mode because the image from the Network Core cannot be read from the Application Core, making it impossible to temporarily save it.")

The application appears to upload one image (I don't know which one because there's no information about that), then resets the device, but then MCUboot reports this error:

*** Booting Zephyr OS build v3.3.99-ncs1-1 ***
I: Starting bootloader
I: Swap type: perm
E: Reset address of image in secondary slot is not in the primary slot
E: Erasing image from secondary slot
I: Swap type: none
I: Bootloader chainload address offset: 0x18000

I don't understand where this is coming from. If I unzip the dfu_application.zip file on my machine and enter serial recovery mode, I'm able to use both .bin files without issues. I am not using any static partitions (the partition manager defines and uses its own partitions). Also, the device doesn't run anything else at the moment, it just advertises over Bluetooth (using the code that I copied verbatim from zephyr/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c) and then enters an infinite "while (1) k_msleep(1000);" loop.

The partition manager report looks like this:

external_flash (0x800000 - 8192kB):
+------------------------------------------------+
| 0x0: mcuboot_secondary (0xe8000 - 928kB) |
| 0xe8000: mcuboot_secondary_1 (0x40000 - 256kB) |
| 0x128000: littlefs_storage (0x100000 - 1024kB) |
| 0x228000: external_flash (0x5d8000 - 5984kB) |
+------------------------------------------------+

flash_primary (0x100000 - 1024kB):
+--------------------------------------------------+
| 0x0: mcuboot (0x15800 - 86kB) |
| 0x15800: EMPTY_0 (0x2800 - 10kB) |
+---0x18000: mcuboot_primary (0xe8000 - 928kB)-----+
| 0x18000: mcuboot_pad (0x200 - 512B) |
+---0x18200: mcuboot_primary_app (0xe7e00 - 927kB)-+
| 0x18200: app (0xe7e00 - 927kB) |
+--------------------------------------------------+

otp (0x2fc - 764B):
+------------------------------+
| 0xff8100: otp (0x2fc - 764B) |
+------------------------------+

ram_flash (0x40000 - 256kB):
+------------------------------------------+
| 0x0: mcuboot_primary_1 (0x40000 - 256kB) |
| 0x40000: ram_flash (0x0 - 0B) |
+------------------------------------------+

sram_primary (0x80000 - 512kB):
+-----------------------------------------------+
| 0x20000000: pcd_sram (0x2000 - 8kB) |
| 0x20002000: sram_primary (0x6e000 - 440kB) |
| 0x20070000: rpmsg_nrf53_sram (0x10000 - 64kB) |
+-----------------------------------------------+

CPUNET flash_primary (0x40000 - 256kB):
+--------------------------------------------+
+---0x1000000: b0n_container (0x8800 - 34kB)-+
| 0x1000000: b0n (0x8580 - 33kB) |
| 0x1008580: provision (0x280 - 640B) |
+---0x1008800: app (0x37800 - 222kB)---------+
| 0x1008800: hci_rpmsg (0x37800 - 222kB) |
+--------------------------------------------+

CPUNET sram_primary (0x10000 - 64kB):
+-------------------------------------------+
| 0x21000000: sram_primary (0x10000 - 64kB) |
+-------------------------------------------+

I know that I'm missing something, but I don't know what. Can you please let me know what I'm doing wrong? Thank you.

Parents
  • Main project configuration (prj.conf):

    # Version number
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_MCUBOOT_IMAGE_VERSION="0.6.0+0"

    # General configuration options
    CONFIG_STDOUT_CONSOLE=n
    CONFIG_UART_CONSOLE=n
    CONFIG_CONSOLE=n
    CONFIG_PRINTK=y
    CONFIG_ASSERT=y
    CONFIG_ASSERT_LEVEL=2
    CONFIG_MAIN_STACK_SIZE=8192
    CONFIG_MPU_STACK_GUARD=y
    CONFIG_HW_STACK_PROTECTION=y
    CONFIG_PRINTK_SYNC=y
    CONFIG_GPIO=y
    CONFIG_RING_BUFFER=y
    CONFIG_HEAP_MEM_POOL_SIZE=100000
    CONFIG_REBOOT=y
    CONFIG_SMF=y
    CONFIG_ZBUS=y
    CONFIG_MAIN_THREAD_PRIORITY=10
    CONFIG_THREAD_CUSTOM_DATA=y
    CONFIG_TIMESLICING=n
    CONFIG_THREAD_NAME=y
    # This is need by the BLE NUS service, might have to be increased.
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    CONFIG_BOARD_ENABLE_CPUNET=y
    CONFIG_NRF53_UPGRADE_NETWORK_CORE=y

    CONFIG_PICOLIBC=y
    CONFIG_PICOLIBC_USE_MODULE=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
    CONFIG_CBPRINTF_FULL_INTEGRAL=y
    CONFIG_CBPRINTF_N_SPECIFIER=y
    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_USE_RUNTIME_CONFIGURE=y

    # Storage
    CONFIG_FILE_SYSTEM=y
    CONFIG_FILE_SYSTEM_LITTLEFS=y
    # Needed to make room for ROMFS
    CONFIG_FILE_SYSTEM_MAX_TYPES=3
    CONFIG_FLASH=y
    CONFIG_FLASH_MAP=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_FILE_SYSTEM_MKFS=y
    CONFIG_FILE_SYSTEM_MAX_FILE_NAME=32
    CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
    # The next definition is interpreted in HEX for some insane reason
    CONFIG_PM_PARTITION_SIZE_LITTLEFS=100000
    # Use partition manager even for single image builds
    CONFIG_PM_SINGLE_IMAGE=y

    # Logging
    CONFIG_LOG=y
    CONFIG_LOG_OUTPUT=y
    CONFIG_LOG_MODE_IMMEDIATE=y
    CONFIG_LOG_RUNTIME_FILTERING=y
    CONFIG_LOG_BACKEND_UART=n
    CONFIG_LOG_PRINTK=n
    CONFIG_POLL=y
    CONFIG_FS_LOG_LEVEL_OFF=y

    # USB configuration options
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PID=0x0002
    CONFIG_USB_CDC_ACM_RINGBUF_SIZE=512
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_CDC_ACM_LOG_LEVEL_WRN=y
    CONFIG_UART_LINE_CTRL=y

    # Bluetooth
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="GSatMicro v2"
    CONFIG_BT_LOG_LEVEL_INF=y
    # TODO: this will probably have to change
    CONFIG_BT_MAX_CONN=2
    CONFIG_BT_MAX_PAIRED=1
    CONFIG_BT_NUS=y
    CONFIG_BT_RECV_WORKQ_SYS=y
    # The next definition also sets some required config options for the BLE SMP transfer (see below)
    CONFIG_MCUBOOT_USE_ALL_AVAILABLE_RAM=y
    CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y
    CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP=y
    CONFIG_ADD_MCUBOOT_MEDIATE_SIM_FLASH_DTS=y
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

    # SMP configuration, adapter from the smp_svr sample in Zephyr
    CONFIG_NET_BUF=y
    CONFIG_ZCBOR=y
    CONFIG_CRC=y
    CONFIG_BASE64=y
    CONFIG_MCUMGR=y
    CONFIG_MCUMGR_TRANSPORT_UART=n
    CONFIG_STREAM_FLASH=y
    CONFIG_THREAD_MONITOR=y
    CONFIG_MCUMGR_GRP_OS=y
    CONFIG_MCUMGR_GRP_FS=y
    CONFIG_MCUMGR_GRP_STAT=n
    CONFIG_MCUMGR_GRP_SHELL=n
    # taskstat needs a few more configuration options to display more thread-related data
    CONFIG_MCUMGR_GRP_OS_TASKSTAT=y
    CONFIG_MCUMGR_GRP_OS_TASKSTAT_ONLY_SUPPORTED_STATS=y
    CONFIG_THREAD_STACK_INFO=y
    CONFIG_INIT_STACKS=y
    CONFIG_MCUMGR_GRP_OS_TASKSTAT_STACK_INFO=y
    CONFIG_IMG_MANAGER=y
    CONFIG_MCUMGR_GRP_IMG=y
    # Enable the Bluetooth mcumgr transport (unauthenticated).
    CONFIG_MCUMGR_TRANSPORT_BT=y
    CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=n
    CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y
    # Enable the mcumgr Packet Reassembly feature over Bluetooth and its configuration dependencies.
    CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y
    CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=2475
    # Needed by Bluetooh
    CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=4608
  • MCUboot configuration (child_image/mcuboot.conf):

    # Generic configuration options. Try to keep the size to a minimum.
    CONFIG_SIZE_OPTIMIZATIONS=y
    CONFIG_GPIO=y
    CONFIG_I2C=n
    CONFIG_SPI=n
    CONFIG_HW_STACK_PROTECTION=n
    CONFIG_PM=n
    CONFIG_ERRNO=n
    CONFIG_FPROTECT=y
    CONFIG_PRINTK=y
    CONFIG_MAIN_STACK_SIZE=10240
    # TODO: CC3xx is currently not used for nrf53? That doesn't sound right?
    CONFIG_HW_CC3XX=n
    CONFIG_NRF_CC3XX_PLATFORM=n
    # Required for kernel operation
    CONFIG_CLOCK_CONTROL=y
    CONFIG_SYS_CLOCK_EXISTS=y
    CONFIG_SERIAL=y
    CONFIG_RESET_ON_FATAL_ERROR=n
    CONFIG_MINIMAL_LIBC=y
    CONFIG_CBPRINTF_COMPLETE=y
    CONFIG_BOOT_BANNER=y
    # Next two options are needed to get any console output from mcuboot
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y

    # Logging
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    CONFIG_LOG_MODE_MINIMAL=y

    # Flash/QSPI options (mostly taken from the Thingy53 configuration)
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
    CONFIG_FLASH=y
    CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y

    # MCUBoot options
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    CONFIG_BOOT_SERIAL_DETECT_DELAY=1000
    CONFIG_BOOT_ERASE_PROGRESSIVELY=y
    CONFIG_BOOT_SERIAL_NO_APPLICATION=y
    CONFIG_BOOT_MAX_LINE_INPUT_LEN=8192
    CONFIG_BOOT_SERIAL_MAX_RECEIVE_SIZE=4096
    # TODO: check if this is correct
    CONFIG_BOOT_MAX_IMG_SECTORS=2048

    # Default bootloader partition size is way too small for our use case.
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=15800
    # The next two optoins are needed for downgrade protection (see developer.nordicsemi.com/.../fw_update.html
    # The first one is also needed for simultaneous multi-image DFU (see developer.nordicsemi.com/.../nrf5340.html
    CONFIG_BOOT_UPGRADE_ONLY=y
    CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=y

    # Simultaneous multi-image update
    CONFIG_NRF53_MULTI_IMAGE_UPDATE=y
    CONFIG_UPDATEABLE_IMAGE_NUMBER=2
    CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y
    CONFIG_FLASH_SIMULATOR=y
    CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
    CONFIG_FLASH_SIMULATOR_STATS=n

    # USB
    CONFIG_USB_DEVICE_REMOTE_WAKEUP=n
    CONFIG_USB_CDC_ACM=y
  • UPDATE: found the error. It was a matter of configuration, only it was not a bad/missing configuration optoin, but an option which wasn't placed correctly. Turns out that CONFIG_UPDATEABLE_IMAGE_NUMBER=2 needs to be set in the main app configuration, NOT only in the MCUboot configuration! If you set it only in the MCUboot configuration, everything still compiles, but you get errors like this. I feel like this should be mentioned somewhere explicitly, because it's REALLY not obvious. Or (and probably better) an warning/error should be issued at build time if the value of CONFIG_UPDATEABLE_IMAGE_NUMBER is different in the main app and in MCUboot.

Reply
  • UPDATE: found the error. It was a matter of configuration, only it was not a bad/missing configuration optoin, but an option which wasn't placed correctly. Turns out that CONFIG_UPDATEABLE_IMAGE_NUMBER=2 needs to be set in the main app configuration, NOT only in the MCUboot configuration! If you set it only in the MCUboot configuration, everything still compiles, but you get errors like this. I feel like this should be mentioned somewhere explicitly, because it's REALLY not obvious. Or (and probably better) an warning/error should be issued at build time if the value of CONFIG_UPDATEABLE_IMAGE_NUMBER is different in the main app and in MCUboot.

Children
No Data
Related