MCUBoot stuck in BOOT_UPGRADE_TEST swap loop after upgrade

Trying to implement FOTA DFU over BLE.
My application uses my proprietary code (instead of mcumgr) to download signed OTA firmware image to secondary slot (in my case it is located in external flash)
After image download is complete and checksum is verified, application calls

int rc = boot_request_upgrade_multi(0, BOOT_UPGRADE_TEST);
if (rc) {
    printk("failed to request image update\n");
} else {
    printk("Rebooting to complete firmware update\n");
    sys_reboot(SYS_REBOOT_COLD);
}

Upon reboot MCUBoot does what it needs to do, validates image, performs swap between slots and correctly boots downloaded image (which is now in primary slot)
That image, almost immediately upon start (while still in main function ) calls

#if defined(CONFIG_MCUBOOT_IMG_MANAGER)
if (!boot_is_img_confirmed()) {
     printk("Image is not confirmed, so confirm\n");
     int err = boot_write_img_confirmed();
     if (err) {
          printk("Error: couldn't confirm this image: %d\n", err);
     }
} else {
     printk("Image is already confirmed\n");
}
#endif

(I verified that this code is indeed executed)

which causes write image_ok = BOOT_FLAG_SET (1) to be written to primary slot header

After this, I would expect subsequent reboots to NOT perform additional swaps, as the image is confirmed as good, so upon reboot I expect the image that is now in primary slot (which is result of FOTA DFU) to be booted. At least this is how I understood BOOT_UPGRADE_TEST is expected to work.

Unfortunately that is not what is happening...
Subsequent reset causes another swap, as the code in boot_prepare_image_for_update ---> boot_validated_swap_type
keep determining that BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_TEST

Upon code inspection, I see why it happens,
My primary slot state is: magic==GOOD, image_ok==1(SET), copy_done==1(SET)
My secondary slot state is: magic=GOOD, image_ok==3(UNSET), copy_done=3(UNSET)

Table #0 in boot_swap_tables[] matches the state of my primary and secondary slots
.magic_primary_slot = BOOT_MAGIC_ANY,
.magic_secondary_slot = BOOT_MAGIC_GOOD,
.image_ok_primary_slot = BOOT_FLAG_ANY,
.image_ok_secondary_slot = BOOT_FLAG_UNSET,
.copy_done_primary_slot = BOOT_FLAG_ANY,
.swap_type = BOOT_SWAP_TYPE_TEST,

That brings my question: what steps am I missing ? Do I need to alongside calling boot_write_img_confirmed() also mark secondary slot somehow as invalid to avoid swap on next reboot ?
I don't see any examples that do that...
But I don't see how one can get out this forever swap

Parents Reply Children
Related