How to debug MCUboot swap failure after OTA DFU? boot_request_upgrade() has no effect

Hi everyone,

I'm facing an issue where MCUboot doesn't perform a swap after reboot, even though the DFU download to slot 1 completes successfully and boot_request_upgrade() is called.

My devices are in production and had no issues in the paste with BLE DFU update. As we update to 2.9.0 the problems starts. Some devices are not working after BLE DFU and swap back to the old version. We find it out while implementing OTA over LTE-M that the partition not swapping. There seams an issue with my swapping. The goal is to use the external flash for updating, but if the main flash works it will be good enough again.

Context:

I'm doing firmware updates via OTA DFU, and writing the upgrade request like this:

int err = boot_request_upgrade(BOOT_UPGRADE_TEST); // or int err = boot_set_pending(0);

MCUboot debug logs confirm that both the magic and swap info are written:

<dbg> mcuboot_util: boot_write_magic: writing magic; fa_id=6 off=0x77ff0 (0xfbff0)
<dbg> mcuboot_util: boot_write_swap_info: writing swap_info; fa_id=6 off=0x77fd8 (0xfbfd8), swap_type=0x2 image_num=0x0

However, after reboot, the old image from slot 0 is still running — no swap occurs.

I have CONFIG_MCUBOOT_UTIL_LOG_LEVEL_DBG=y enabled, but I’m unsure how to debug MCUboot itself (e.g., with west debug or bt) since getting not output west attach.

Note on Flash Patch:

I also experimented with:

# CONFIG_DISABLE_FLASH_PATCH=y

When I enable this config, the DFU (BLE) no longer works — so I’ve kept it disabled.

prj.conf (partial):

CONFIG_PARTITION_MANAGER_ENABLED=y
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=n
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n
CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y

pm_static.yml (simplified):

mcuboot: 0x00000 - 0x0c000
mcuboot_primary: 0x0c000 - 0x84000
mcuboot_secondary: 0x84000 - 0xfc000
settings_storage: 0xfc000 - 0x100000

My questions:

  1. What could prevent MCUboot from initiating the swap even when magic/swap_info are written? (Could a mismatch in partition maps between MCUboot and the application prevent the swap?)

  2. Is there a correct way to attach to MCUboot for runtime debugging? (e.g., debugging from reset?)

  3. Any known issues with OTA DFU + MCUboot + CONFIG_DISABLE_FLASH_PATCH?

  4. Are there additional configs I should double-check?

  5. How can I verify that MCUboot has the correct view of the flash layout?

Thanks in advance — happy to share more if needed!

Parents
  • Hi,

    What could prevent MCUboot from initiating the swap even when magic/swap_info are written? (Could a mismatch in partition maps between MCUboot and the application prevent the swap?)

    Here's a couple of thoughts 

    1. Mismatch in size between primary and secondary (both of your partitions are similar if my math checks out)
    2. That you don't enough room for swapping (NCSDK-20567 in https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/known_issues.html note that there are two instances of 20567 in this list)
    3. That the image is rejected due to either
      1. That the update image is not signed with the same key that MCUboot has (injection protection)
      2. That the update image is rejected due to versioning not being newer than the current version (downgrade protection)

    Item 3 is typically occurring after the image has been swapped, so based on your description I don't think that this is the case.

    Is there a correct way to attach to MCUboot for runtime debugging? (e.g., debugging from reset?)

     Trying to debug with MCUBOOT enabled fails to boot. and  B0 secure bootloader logging with RTT not working. might be helpful as well as https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-2-debugging/ 

    Any known issues with OTA DFU + MCUboot + CONFIG_DISABLE_FLASH_PATCH?

    Not that I'm aware of, i.e nothing stated in the known issues page and I can't think of any conflicts based on the description https://docs.nordicsemi.com/bundle/ncs-latest/page/kconfig/index.html#CONFIG_DISABLE_FLASH_PATCH 

    Are there additional configs I should double-check?

    https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-8-bootloaders-and-dfu-fota/ there could be some pointers here

    How can I verify that MCUboot has the correct view of the flash layout?

    MCUboot uses the pm_static.yml that you build it with, so verify it by comparing the partition manager report, i.e west build -t partition_manager_report, up against the generated build partition map that you can find within build/mcuboot/ and/or build/<your_app>

    Kind regards,
    Andreas

  • Thanks Andreas, 

    tried all things - but don't get it working!

  • Hi,

    Could you please post more details? Do you get any build logs, device logs or anything when you're trying the various items? 

    Oh, are you certain that the image is uploaded?

    And thirdly; do you mark the new image to be confirmed for update? This should be more described in steps in for instance the Bootloader and DFU lesson here  https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-9-bootloaders-and-dfu-fota/topic/exercise-1-dfu-over-uart/ 

    1. Using mcumgr CLI
    You can confirm the currently running image with the following command (no hash needed for the running image): mcumgr <connection-options> image confirm ""
    Or, to confirm a specific image by its hash: mcumgr <connection-options> image confirm <hash>

    Confirming the image ensures that the bootloader will not revert to the previous image on subsequent resets. If you do not confirm, the device will revert to the previous image after a reset. This is especially important in dual-slot configurations where images are swapped during DFU. The confirmed flag will be set for the image once this is done Verifying and testing the image.
    2. In Application Code
    You can also confirm the image programmatically after verifying that the new firmware is working as expected. This is typically done by calling the boot_write_img_confirmed() function in your application code:
    #include <bootutil/bootutil.h>
    
    if (!boot_is_img_confirmed()) {
    int err = boot_write_img_confirmed();
    if (err == 0) {
    // Image successfully confirmed
    } else {
    // Handle error
    }
    }
    This approach is useful if you want the device to self-confirm after passing certain checks (e.g., after a successful BLE connection or other validation) MCUboot test and confirm with DFU Target library.
    3. DFU Target Sample
    If you are using the DFU Target sample, you can use the shell command: dfu_target mcuboot_confirm

    This will mark the update as confirmed. If you skip this step, the device will revert to the previous image on the next reboot DFU Target Sample - Testing.

    Kind regards,

    Andreas

  • SEGGER J-Link V7.94i - Real time terminal output
    SEGGER J-Link (unknown) V1.0, SN=1050238934
    Process: JLinkExe
    *** Booting My Application v0.2.3-stable-4ac746336259 ***
    *** Using nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    *** Golioth Firmware SDK v0.18.0 ***
    [00:00:00.059,814] <inf> edge_app: GPIO 2V4 already set 0xFFFFFFFA
    [00:00:00.059,844] <inf> edge_app: Starting application...
    [00:00:00.059,844] <inf> edge_app: Build time: Jul  7 2025 20:47:26
    [00:00:00.059,875] <inf> edge_app: Version: 0.2.3
    [00:00:00.059,906] <inf> edge_app: SerialNo edfb3e72
    [00:00:00.066,833] <inf> fs_nvs: 4 Sectors of 4096 bytes
    [00:00:00.066,833] <inf> fs_nvs: alloc wra: 0, fe8
    [00:00:00.066,833] <inf> fs_nvs: data wra: 0, 0
    [00:00:00.066,894] <inf> edge_app: SIMCOM module initalised
    [00:00:00.066,925] <inf> edge_app: Golioth psk_id:
    [00:00:00.066,955] <inf> edge_app: Golioth psk:
    [00:00:00.067,016] <inf> led_app: led init done
    [00:00:00.567,138] <inf> app_button: Set up 0m
    m
    
    0m
    
    [00:00:02.059,936] <inf> app_networking: Waiting for network registration...
    [00:00:13.560,150] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,180] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,272] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,302] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,363] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,394] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,455] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,485] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,546] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,577] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,638] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,668] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.660,614] <err> modem_chat: Failed to transmit 2 bytes. (-1)
    [00:00:23.560,272] <wrn> modem_chat: simcom_sim7080_init_chat_script: timed out
    [00:00:36.973,876] <inf> modem_at_shell: pipe connected
    [00:00:36.973,968] <inf> modem_at_shell: opening pipe
    [00:00:37.006,561] <inf> modem_at_shell: pipe opened
    [00:00:37.006,652] <inf> modem_at_shell: chat attached
    [00:00:49.060,729] <inf> app_networking: Registered (roaming) via LTE
    [00:00:49.061,370] <inf> app_networking: Waiting for network connection...
    [00:00:49.257,049] <inf> app_networking: IP up NET_EVENT_DNS_SERVER_ADD
    [00:00:49.257,049] <inf> app_networking: IP up NET_EVENT_L4_CONNECTED
    [00:00:49.257,080] <inf> app_networking: Connected to network
    [00:00:49.296,386] <inf> app_networking: IP up NET_EVENT_L4_CONNECTED
    [00:00:49.296,417] <inf> app_networking: Connected to network
    [00:00:50.257,843] <inf> app_sntp: Sending SNTP IPv4 request...
    [00:00:51.440,399] <inf> app_sntp: status: 0
    [00:00:51.440,429] <inf> app_sntp: time since Epoch: high word: 0, low word: 1751914119
    [00:00:51.440,521] <inf> app_sntp: Time received from 0
    
    [00:00:51.440,551] <inf> app_sntp: Current time after sync:: 1751914119000
    [00:00:51.441,070] <inf> golioth_mbox: Mbox created, bufsize: 1232, num_items: 10, item_size: 112
    [00:00:56.568,572] <inf> golioth_coap_client_zephyr: Connected to server 0
    [00:00:56.568,603] <inf> golioth_coap_client_zephyr: Golioth CoAP client connected
    [00:00:56.568,603] <inf> lte_data_thread: golioth Connected
    [00:00:56.568,695] <inf> golioth_coap_client_zephyr: Entering CoAP I/O loop
    [00:00:56.688,964] <inf> app_networking: RSSI: -81
    [00:00:56.689,025] <inf> app_networking: IMEI: 860016042893276
    [00:00:58.266,174] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:00:58.266,204] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:00:58.266,265] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:00:58.266,296] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:00:58.411,132] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:00:58.411,163] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:00:58.411,254] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:00:58.411,285] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:00:58.602,142] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:00:58.602,203] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:00:58.602,233] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:00:58.602,325] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:00:59.835,235] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:00:59.835,266] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:00:59.835,327] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:00:59.835,388] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:00:59.975,158] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:00:59.975,189] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:00:59.975,280] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:00:59.975,311] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:01:00.374,908] <inf> lte_data_thread: New manifest received
    [00:01:00.375,000] <inf> lte_data_thread: New firmware version available: 0.3.0 (current: 0.2.3)
    [00:01:00.377,929] <inf> lte_data_thread: Starting OTA download: 0.2.3 -> 0.3.0
    [00:01:02.163,085] <inf> lte_data_thread: OTA download started successfully
    [00:01:02.163,116] <inf> lte_data_thread: Waiting for OTA to complete...
    [00:01:05.616,455] <inf> lte_data_thread: Received block 0/20
    [00:01:05.616,546] <inf> mcuboot_util: Image index: 0, Swap type: none
    [00:01:05.616,577] <inf> golioth_fw_zephyr: swap type: none
    [00:01:07.725,402] <inf> lte_data_thread: Received block 1/20
    [00:01:11.790,405] <inf> lte_data_thread: Received block 2/20
    [00:01:15.811,889] <inf> lte_data_thread: Received block 3/20
    [00:01:17.965,026] <inf> lte_data_thread: Received block 4/20
    [00:01:21.919,433] <inf> lte_data_thread: Received block 5/20
    [00:01:26.047,454] <inf> lte_data_thread: Received block 6/20
    [00:01:28.256,591] <inf> lte_data_thread: Received block 7/20
    [00:01:32.127,532] <inf> lte_data_thread: Received block 8/20
    [00:01:36.367,858] <inf> lte_data_thread: Received block 9/20
    [00:01:38.399,353] <inf> lte_data_thread: Received block 10/20
    [00:01:40.445,373] <inf> lte_data_thread: Received block 11/20
    [00:01:42.479,309] <inf> lte_data_thread: Received block 12/20
    [00:01:46.159,332] <inf> lte_data_thread: Received block 13/20
    [00:01:48.639,343] <inf> lte_data_thread: Received block 14/20
    [00:01:50.686,157] <inf> lte_data_thread: Received block 15/20
    [00:01:54.799,407] <inf> lte_data_thread: Received block 16/20
    [00:01:58.924,774] <inf> lte_data_thread: Received block 17/20
    [00:02:00.925,476] <inf> lte_data_thread: Received block 18/20
    [00:02:02.945,678] <inf> lte_data_thread: Received block 19/20
    [00:02:04.725,463] <inf> lte_data_thread: Received block 20/20
    [00:02:04.849,090] <inf> lte_data_thread: OTA download complete for 'main'. Verifying and requesting upgrade...
    [00:02:04.849,121] <inf> lte_data_thread: OTA1 download complete for 'main'. Verifying and requesting upgrade...
    [00:02:04.883,514] <dbg> mcuboot_util: boot_write_magic: writing magic; fa_id=6 off=0x77ff0 (0xfbff0)
    [00:02:04.884,124] <dbg> mcuboot_util: boot_write_swap_info: writing swap_info; fa_id=6 off=0x77fd8 (0xfbfd8), swap_type=0x2 image_num=0x0
    [00:02:04.884,613] <inf> lte_data_thread: OT2 download complete for 'main'. Verifying and requesting upgrade...
    [00:02:04.884,674] <inf> lte_data_thread: Boot upgrade requested successfully - releasing semaphore for reboot
    [00:02:04.884,826] <inf> golioth_coap_client_zephyr: Attempting to stop client
    [00:02:04.884,948] <inf> golioth_coap_client_zephyr: Stop request
    [00:02:04.884,948] <inf> golioth_coap_client_zephyr: Ending session
    *** Booting My Application v0.2.3-stable-4ac746336259 ***
    *** Using nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    *** Golioth Firmware SDK v0.18.0 ***
    [00:00:00.059,600] <inf> edge_app: GPIO 2V4 already set 0xFFFFFFFA
    [00:00:00.059,600] <inf> edge_app: Starting application...
    [00:00:00.059,631] <inf> edge_app: Build time: Jul  7 2025 20:47:26
    [00:00:00.059,661] <inf> edge_app: Version: 0.2.3
    [00:00:00.059,661] <inf> edge_app: SerialNo edfb3e72
    [00:00:00.066,101] <inf> fs_nvs: 4 Sectors of 4096 bytes
    [00:00:00.066,131] <inf> fs_nvs: alloc wra: 0, fe8
    [00:00:00.066,131] <inf> fs_nvs: data wra: 0, 0
    [00:00:00.066,192] <inf> edge_app: SIMCOM module initalised
    [00:00:00.066,223] <inf> edge_app: Golioth psk_id:
    [00:00:00.066,253] <inf> edge_app: Golioth psk:
    [00:00:00.066,284] <inf> led_app: led init done
    [00:00:00.566,406] <inf> app_button: Set up button at gpio@50000300 pin 4
    
    [00:00:00.566,467] <inf> littlefs: LittleFS version 2.9, disk version 2.1
    [00:00:00.568,511] <inf> littlefs: FS at mx25r6435f@0:0x0 is 2048 0x1000-byte blocks with 512 cycle
    [00:00:00.568,511] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
    [00:00:00.576,232] <inf> data_archive: bsize = 16 ; frsize = 4096 ; blocks = 2048 ; bfree = 2044
    [00:00:00.580,108] <inf> edge_app: Data archive initialized (Code: 0)
    [00:00:00.580,322] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 
                                                2d 79 a1 c8 6a 40 b7 3c  f6 74 f9 0b 22 d3 c4 80 |-y..j@.< .t.."...
                                                74 72 82 ba                                      |tr..             
    [00:00:00.582,489] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
    [00:00:00.582,519] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
    [00:00:00.582,550] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 45.41337 Build 3074452168
    [00:00:00.583,343] <inf> bt_hci_core: Identity: FE:72:34:2F:0F:6E (random)
    [00:00:00.583,374] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x106b, manufacturer 0x0059
    [00:00:00.583,404] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x106b
    [00:00:00.583,435] <inf> ble_server: Bluetooth initialized
    [00:00:00.583,465] <wrn> ble_server: Failed to set device name (-12)
    [00:00:00.584,289] <inf> ble_data_thread: Starting BLE write thread...
    [00:00:02.059,722] <inf> app_networking: Waiting for network registration...
    [00:00:13.559,936] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.559,967] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,058] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,089] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,150] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,180] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,241] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,272] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,333] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,363] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.560,424] <wrn> modem_backend_uart_async: Receive stopped for reasons: 4
    [00:00:13.560,455] <wrn> modem_backend_uart_async: Receive stopped for reasons: 8
    [00:00:13.660,400] <err> modem_chat: Failed to transmit 2 bytes. (-1)
    [00:00:23.560,058] <wrn> modem_chat: simcom_sim7080_init_chat_script: timed out
    [00:00:37.733,093] <inf> modem_at_shell: pipe connected
    [00:00:37.733,184] <inf> modem_at_shell: opening pipe
    [00:00:37.765,869] <inf> modem_at_shell: pipe opened
    [00:00:37.765,960] <inf> modem_at_shell: chat attached
    [00:00:57.060,577] <inf> app_networking: Registered (roaming) via LTE
    [00:00:57.061,309] <inf> app_networking: Waiting for network connection...
    [00:00:57.274,230] <inf> app_networking: IP up NET_EVENT_DNS_SERVER_ADD
    [00:00:57.274,230] <inf> app_networking: IP up NET_EVENT_L4_CONNECTED
    [00:00:57.274,291] <inf> app_networking: Connected to network
    [00:00:57.327,606] <inf> app_networking: IP up NET_EVENT_L4_CONNECTED
    [00:00:57.327,606] <inf> app_networking: Connected to network
    [00:00:58.275,146] <inf> app_sntp: Sending SNTP IPv4 request...
    [00:01:02.610,321] <inf> app_sntp: status: 0
    [00:01:02.610,351] <inf> app_sntp: time since Epoch: high word: 0, low word: 1751914266
    [00:01:02.610,443] <inf> app_sntp: Time received from 0
    
    [00:01:02.610,473] <inf> app_sntp: Current time after sync:: 1751914266000
    [00:01:02.610,992] <inf> golioth_mbox: Mbox created, bufsize: 1232, num_items: 10, item_size: 112
    [00:01:08.171,936] <inf> golioth_coap_client_zephyr: Connected to server -1
    [00:01:08.171,936] <err> golioth_coap_client_zephyr: Failed to connect to socket: -11
    [00:01:08.172,851] <err> golioth_coap_client_zephyr: Failed to connect: -11
    [00:01:08.172,882] <wrn> golioth_coap_client_zephyr: Failed to connect: -11
    [00:01:17.823,303] <inf> golioth_coap_client_zephyr: Connected to server 0
    [00:01:17.823,333] <inf> golioth_coap_client_zephyr: Golioth CoAP client connected
    [00:01:17.823,333] <inf> lte_data_thread: golioth Connected
    [00:01:17.823,333] <inf> golioth_coap_client_zephyr: Entering CoAP I/O loop
    [00:01:17.870,178] <inf> app_networking: RSSI: -79
    [00:01:17.870,208] <inf> app_networking: IMEI: 860016042893276
    [00:01:18.828,979] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:01:18.829,010] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:01:18.829,101] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:01:18.829,132] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:01:18.908,966] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:01:18.908,996] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:01:18.909,088] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:01:18.909,118] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:01:19.273,925] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:01:19.273,986] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:01:19.274,047] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:01:19.274,108] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:01:19.404,174] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:01:19.404,296] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:01:19.404,357] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:01:19.404,418] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:01:19.529,907] <inf> app_golioth: Setting on_send_adc_data_setting to 300 s
    [00:01:19.529,998] <inf> app_golioth: Setting SEND_ADC_DATA_ON_NEXT_ONLINE to false
    [00:01:19.530,029] <inf> app_golioth: Setting on_send_adc_record_setting to 360 s
    [00:01:19.530,090] <inf> app_golioth: Setting FORCE_SEND_STATUS to true
    [00:01:20.542,877] <inf> lte_data_thread: New manifest received
    [00:01:20.543,090] <inf> lte_data_thread: New firmware version available: 0.3.0 (current: 0.2.3)
    [00:01:20.543,304] <inf> lte_data_thread: Starting OTA download: 0.2.3 -> 0.3.0
    [00:01:23.078,186] <inf> lte_data_thread: OTA download started successfully
    [00:01:23.078,216] <inf> lte_data_thread: Waiting for OTA to complete...
    [00:01:25.856,231] <inf> lte_data_thread: Received block 0/20
    [00:01:25.856,323] <inf> mcuboot_util: Image index: 0, Swap type: none
    [00:01:25.856,323] <inf> golioth_fw_zephyr: swap type: none
    [00:01:27.854,187] <inf> lte_data_thread: Received block 1/20
    [00:01:29.808,105] <inf> lte_data_thread: Received block 2/20
    [00:01:33.972,839] <inf> lte_data_thread: Received block 3/20
    [00:01:36.014,373] <inf> lte_data_thread: Received block 4/20
    [00:01:38.094,177] <inf> lte_data_thread: Received block 5/20
    [00:01:42.129,180] <inf> lte_data_thread: Received block 6/20
    [00:01:44.335,144] <inf> lte_data_thread: Received block 7/20
    [00:01:48.255,157] <inf> lte_data_thread: Received block 8/20
    [00:01:50.414,154] <inf> lte_data_thread: Received block 9/20
    [00:01:52.464,630] <inf> lte_data_thread: Received block 10/20
    [00:01:56.544,219] <inf> lte_data_thread: Received block 11/20
    [00:01:58.575,286] <inf> lte_data_thread: Received block 12/20
    [00:02:02.774,383] <inf> lte_data_thread: Received block 13/20
    [00:02:06.818,359] <inf> lte_data_thread: Received block 14/20
    [00:02:11.010,314] <inf> lte_data_thread: Received block 15/20
    [00:02:14.928,039] <inf> lte_data_thread: Received block 16/20
    [00:02:19.137,145] <inf> lte_data_thread: Received block 17/20
    [00:02:21.056,365] <inf> lte_data_thread: Received block 18/20
    [00:02:25.134,307] <inf> lte_data_thread: Received block 19/20
    [00:02:26.919,219] <inf> lte_data_thread: Received block 20/20
    [00:02:27.060,119] <inf> lte_data_thread: OTA download complete for 'main'. Verifying and requesting upgrade...
    [00:02:27.060,150] <inf> lte_data_thread: OTA1 download complete for 'main'. Verifying and requesting upgrade...
    [00:02:27.094,543] <dbg> mcuboot_util: boot_write_magic: writing magic; fa_id=6 off=0x77ff0 (0xfbff0)
    [00:02:27.095,123] <dbg> mcuboot_util: boot_write_swap_info: writing swap_info; fa_id=6 off=0x77fd8 (0xfbfd8), swap_type=0x2 image_num=0x0
    [00:02:27.095,642] <inf> lte_data_thread: OT2 download complete for 'main'. Verifying and requesting upgrade...
    [00:02:27.095,672] <inf> lte_data_thread: Boot upgrade requested successfully - releasing semaphore for reboot
    [00:02:27.095,825] <inf> golioth_coap_client_zephyr: Attempting to stop client
    [00:02:27.095,947] <inf> golioth_coap_client_zephyr: Stop request
    [00:02:27.095,947] <inf> golioth_coap_client_zephyr: Ending session
    *** Booting My Application v0.2.3-stable-4ac746336259 ***
    *** Using nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    *** Golioth Firmware SDK v0.18.0 ***
    [00:00:00.059,600] <inf> edge_app: GPIO 2V4 already set 0xFFFFFFFA
    [00:00:00.059,600] <inf> edge_app: Starting application...
    [00:00:00.059,631] <inf> edge_app: Build time: Jul  7 2025 20:47:26
    [00:00:00.059,661] <inf> edge_app: Version: 0.2.3
    [00:00:00.059,661] <inf> edge_app: SerialNo edfb3e72
    [00:00:00.066,101] <inf> fs_nvs: 4 Sectors of 4096 bytes
    [00:00:00.066,101] <inf> fs_nvs: alloc wra: 0, fe8
    [00:00:00.066,131] <inf> fs_nvs: data wra: 0, 0
    [00:00:00.066,192] <inf> edge_app: SIMCOM module initalised
    [00:00:00.066,223] <inf> edge_app: Golioth psk_id:
    [00:00:00.066,253] <inf> edge_app: Golioth psk:
    [00:00:00.066,284] <inf> led_app: led init done
    [00:00:00.566,406] <inf> app_button: Set up button at gpio@50000300 pin 4
    
    [00:00:00.566,467] <inf> littlefs: LittleFS version 2.9, disk version 2.1
    [00:00:00.568,511] <inf> littlefs: FS at mx25r6435f@0:0x0 is 2048 0x1000-byte blocks with 512 cycle
    [00:00:00.568,511] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
    [00:00:00.576,232] <inf> data_archive: bsize = 16 ; frsize = 4096 ; blocks = 2048 ; bfree = 2044
    [00:00:00.580,108] <inf> edge_app: Data archive initialized (Code: 0)
    [00:00:00.580,322] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 
                                                2d 79 a1 c8 6a 40 b7 3c  f6 74 f9 0b 22 d3 c4 80 |-y..j@.< .t.."...
                                                74 72 82 ba                                      |tr..             
    [00:00:00.582,489] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
    [00:00:00.582,519] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
    [00:00:00.582,550] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 45.41337 Build 3074452168
    [00:00:00.583,343] <inf> bt_hci_core: Identity: FE:72:34:2F:0F:6E (random)
    [00:00:00.583,374] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x106b, manufacturer 0x0059
    [00:00:00.583,404] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x106b
    [00:00:00.583,435] <inf> ble_server: Bluetooth initialized
    [00:00:00.583,435] <wrn> ble_server: Failed to set device name (-12)
    [00:00:00.584,289] <inf> ble_data_thread: Starting BLE write thread...
    [00:00:02.059,722] <inf> app_networking: Waiting for network registration...
    

  • I confirmed the firmware update with some basic logic and didn't see any log. The same method works before updating to 2.9.0. I assume the problem starts with migration to sysbuild. 

    The only thing what i see is, which can be indication
    [00:01:25.856,323] <inf> golioth_fw_zephyr: swap type: none

    I don't see a mcu book msg between [00:02:27.095,947] and [00:00:00.059,600]. 


    Regarding the size my firmeware is near the limit from 473kb. but already tried it with a blinky with the same signed key and the same issue!

    My layout on the programm looks wired. (maybe this is a hint)

  • QBSho said:
    I assume the problem starts with migration to sysbuild. 

    Oh, good catch. Do you have a sysbuild.conf? And a sysbuild/mcuboot/ folder? 

    Kind regards,
    Andreas

Reply Children
  • Hello Andreas, 

    sysbuild.conf

    SB_CONFIG_BOOTLOADER_MCUBOOT=y



    sysbuild/mcuboot.overlay
    / {
    aliases {
    mcuboot-button0 = &button1;
    mcuboot-led0 = &red_led;
    };
    };


    sysbuild/mcuboot.conf
    CONFIG_MCUBOOT_LOG_LEVEL_WRN=y
    I have the feeling that the flash_img_buffered_write in the https://docs.zephyrproject.org/apidoc/latest/group__flash__img__api.html didn't write to the slot1 correctly. Because when i open the nrf connect app and checke the flash it only shows slot 0.
    But on the other side when i DFU it works and after confirm only show slot 0 
    BR


  • Hi,

    A couple of items w.r.t your configuraiton

    CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y

    For this config to be active you need to have CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y for both images, i.e SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y in sysbuild.conf 

    I see that you're not intending to use external flash for the update image (SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n), is this correct?

    Secondary:

    Could you verify you have a b0 or not? If you are, then this might be a fix for you https://github.com/nrfconnect/sdk-nrf/pull/22454 

    Could you examine the mcuboot image headers are included in the hex either with https://docs.nordicsemi.com/bundle/ncs-latest/page/mcuboot/imgtool.html or by following the suggestions here: https://devzone.nordicsemi.com/f/nordic-q-a/111974/mcuboot-loses-pending-update-image-in-slot-1-after-reset?ReplyFilter=Answers&ReplySortBy=Answers&ReplySortOrder=Descending 

    Kind regards,
    Andreas

  • set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_LIST_DIR}/configuration/pm_static.yml CACHE INTERNAL "")

    Do you use something as this to load the static partition? Where do you load the "pm_static.yml"?

    In the CMakeLists.txt? Then maybe moving that into sysbuild.cmake helps.

  • 1) CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL
    -> I use external flash for telemetry data not for any mcu relevant thing (no mcuboot on that)

    2) CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y didn't change anything and got a following on SB_ version.
    warning: ignoring malformed line 'SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y'

    3) 
    Where i find out if b0 or not? in the pm_static.yml or partion.yml is no b0.

    4) Double check signed images for both are the same and valid

    I got an error `python3 imgtool.py dumpinfo zepyhr.signed.hex , so i guess it's not included

    _tlv_prot_head = struct.unpack(
    'HH',
    b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])

    the bin output 

    #### Image header (offset: 0x0) ############################
    magic:              0x96f3b83d
    load_addr:          0x0
    hdr_size:           0x200
    protected_tlv_size: 0x0
    img_size:           0x74df8
    flags:              0x0
    version:            0.2.3+0
    ############################################################
    #### Payload (offset: 0x200) ###############################
    |                                                          |
    |              FW image (size: 0x74df8 Bytes)              |
    |                                                          |
    ############################################################
    #### TLV area (offset: 0x74ff8) ############################
    magic:     0x6907
    area size: 0x97
            ---------------------------------------------
            type: SHA256 (0x10)
            len:  0x20
            data: 0xd8 0x32 0x79 0xeb 0x59 0xee 0x14 0x70 
                  0x7b 0x0f 0x80 0xbc 0xde 0x93 0x96 0x3d 
                  0x96 0x19 0x90 0x7b 0x49 0x24 0xcf 0x97 
                  0x4e 0x22 0x70 0x71 0x85 0x06 0x80 0x5b 
            ---------------------------------------------
            type: KEYHASH (0x1)
            len:  0x20
            data: 0xe3 0x04 0x66 0xf6 0xb8 0x47 0x0c 0x1f 
                  0x29 0x07 0x0b 0x17 0xf1 0xe2 0xd3 0xe9 
                  0x4d 0x44 0x5e 0x3f 0x60 0x80 0x87 0xfd 
                  0xc7 0x11 0xe4 0x38 0x2b 0xb5 0x38 0xb6 
            ---------------------------------------------
            type: ECDSASIG (0x22)
            len:  0x47
            data: 0x30 0x45 0x02 0x20 0x63 0x19 0x8b 0xd1 
                  0x92 0x3a 0xdf 0x54 0x90 0xe5 0x80 0x77 
                  0x50 0xb2 0xd1 0xab 0x52 0x8f 0x84 0xf7 
                  0x4e 0xfb 0x45 0x83 0xb9 0x70 0x8d 0xeb 
                  0x3d 0x26 0x9e 0x77 0x02 0x21 0x00 0xcf 
                  0xa8 0xc8 0x28 0x46 0x1b 0xb0 0x39 0xa6 
                  0x0f 0xe1 0x1c 0xc5 0x94 0x40 0x40 0xde 
                  0xd2 0x69 0x72 0x11 0x24 0x07 0x28 0x2a 
                  0xe9 0xdf 0x15 0xd3 0x1c 0x52 0xf0 
    ############################################################
    #### End of Image  #########################################
    dumpinfo has run successfully

    5)
    set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_LIST_DIR}/configuration/pm_static.yml CACHE INTERNAL "")

    I don't set anything here

  • Hi,

    Sorry about the delayed response. Andreas is currently out of the office.

    3. I see you have mcuboot starting at 0x0, this means there no b0 bootloader (NSIB - Nordic secure immutable bootloader) included in this project.

    4. I don't see any obvious problems from the dump

    5. Please check if the generated partitions.yml file in your build output matches your pm_static.yml file just to make sure the pm_static.yml is correctøly applied to the build. 

    Best regards,

    Vidar

Related