MCUBoot active slot and version over SMP

Hello,

I work on a board with nRF9160 and nRF52840.
I can perform firmware update of both application and mcuboot for nRF52840 (using serial recovery mode) from the nRF9160 over SMP.

My question is:
How nRF9160 can get information from nRF52840 in serial recovery mode over SMP about the active mcuboot slot, so we know which build (S0/S1) we should use for the next mcuboot update. Also, how the nRF9160 can get the currently used mcuboot image version from nRF52840 in serial recovery mode.

  • Hello,

    The following function is used to get images data in file boot_serial.c in function bs_list to send it as response to cmd_read_image_list request:

    static inline uint32_t __flash_area_ids_for_slot(int img, int slot)
    {
        static const int all_slots[] = {
    	ALL_AVAILABLE_SLOTS
    	MCUBOOT_S0_S1_SLOTS
        };
        return all_slots[img * 2 + slot];
    };


    If I understand it correctly, it gives data of the following images:
    Image 0, slot 0: PM_MCUBOOT_PRIMARY_ID (application image in primary slot)
    Image 0, slot 1: PM_MCUBOOT_SECONDARY_ID (mcuboot or application image in secondary slot)
    Image 1, slot 0: PM_S1_ID (if S0 is used) / PM_S0_ID (if S1 is used)
    Image 1, slot 1: PM_MCUBOOT_SECONDARY_ID (mcuboot or application image in secondary slot)

    Based on these images, I do not have the information about the active mcuboot image (its version) and the active mcuboot slot. Correct me if my understanding is incorrect.

    Also, why is PM_MCUBOOT_SECONDARY_ID sent twice - as image 0 slot 1 and image 1 slot 1?

  • Maybe dfu_target_smp_image_list_get() would be better:

    https://github.com/nrfconnect/sdk-nrf/blob/v2.9.0/subsys/dfu/dfu_target/src/dfu_target_smp.c#L296

    Snippet that shows how to read version info:

    	struct mcumgr_image_state image_list = {0};
    	struct mcumgr_image_data *list;
    	size_t ver_len;
    	int ret = dfu_target_smp_image_list_get(&image_list);
    
    	if (ret) {
    		LOG_WRN("Failed to read SMP image list, error: %d", ret);
    		return -ENODATA;
    	}
    
    	/* Set the return value in case no active image is found */
    	ret  = -ENODEV;
    
    	list = image_list.image_list;
    	for (int i = 0; i < image_list.image_list_length; ++i, ++list) {
    		LOG_DBG("%s Image(%d) slot(%d)",
    			list->flags.active ? "Primary" : "Secondary",
    			list->img_num,
    			list->slot_num);
    		LOG_DBG("  Version: %s", list->version);
    		LOG_DBG("  Bootable(%d) Pending(%d) Confirmed(%d)",
    			list->flags.bootable, list->flags.pending, list->flags.confirmed);
    
    		if (list->flags.active) {
    			ver_len = strlen(list->version);
    			if (ver_len >= sizeof(smp_ver)) {
    				return -ENOBUFS;
    			}
    			memcpy(smp_ver, list->version, ver_len + 1);
    			ret = 0;
    		}
    	}
    
    	return ret;

  • The dfu_target_smp_image_list_get() is the function that I use on the nRF9160 side to read image list from the nRF52840 when it is in mcuboot. The problem is with bs_list function that is used to handle the request sent using dfu_target_smp_image_list_get().

    So my question remains the same as in my previous post.

    To be more precise, I don't have a problem reading current application image and its version. The problem is with reading the current mcuboot version and the active mcuboot slot.

  • The following change in bs_list function in boot_serial.c file makes it possible to read over SMP both mcuboot images in S0 and S1 and the application image:

    From this:

    area_id = flash_area_id_from_multi_image_slot(image_index, slot);

    To this:

                if(image_index == 1)
                {
                    if(slot == 0) area_id = PM_S0_ID;
                    else          area_id = PM_S1_ID;
                }
                else 
                {
                    area_id = flash_area_id_from_multi_image_slot(image_index, slot);
                }

    With this change, the bs_list will respond to request sent from nRF91 using dfu_target_smp_image_list_get() with the following images:

    Image 0, slot 0: PM_MCUBOOT_PRIMARY_ID
    Image 0, slot 1: PM_MCUBOOT_SECONDARY_ID
    Image 1, slot 0: PM_S0_ID
    Image 1, slot 1: PM_S1_ID

    which solves both issues I mentioned before.

    I'd like to ask if that change can possibly break anything for me? Or maybe that's what bs_list should respond with in the first place?

    Regards,
    Filip

Related