@@ -127,21 +127,30 @@ img_mgmt_state_flags(int query_slot)
127127 int image = query_slot / 2 ; /* We support max 2 images for now */
128128 int active_slot = img_mgmt_active_slot (image );
129129
130- /* In case when MCUboot is configured for DirectXIP slot may only be
131- * active or pending. Slot is marked pending only when version in that slot
132- * is higher than version of active slot.
130+ /* In case when MCUboot is configured for FW loader/updater mode, slots
131+ * can be either active or non-active. There is no concept of pending
132+ * or confirmed slots.
133+ *
134+ * In case when MCUboot is configured for DirectXIP slot may only be
135+ * active or pending.
136+ * Slot is marked as pending when:
137+ * - version in that slot is higher than version of active slot.
138+ * - versions are equal but slot number is lower than the active slot.
133139 */
134140 if (image == img_mgmt_active_image () && query_slot == active_slot ) {
135141 flags = IMG_MGMT_STATE_F_ACTIVE ;
142+ #ifdef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP
136143 } else {
137144 struct image_version sver ;
138145 struct image_version aver ;
139146 int rcs = img_mgmt_read_info (query_slot , & sver , NULL , NULL );
140147 int rca = img_mgmt_read_info (active_slot , & aver , NULL , NULL );
141148
142- if (rcs == 0 && rca == 0 && img_mgmt_vercmp (& aver , & sver ) < 0 ) {
149+ if (rcs == 0 && rca == 0 && (img_mgmt_vercmp (& aver , & sver ) < 0 ) ||
150+ (img_mgmt_vercmp (& aver , & sver ) == 0 && (active_slot > query_slot ))) {
143151 flags = IMG_MGMT_STATE_F_PENDING | IMG_MGMT_STATE_F_PERMANENT ;
144152 }
153+ #endif /* CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP */
145154 }
146155
147156 return flags ;
@@ -285,7 +294,14 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type)
285294 if (active_slot_state == DIRECT_XIP_BOOT_ONCE ) {
286295 lt = NEXT_BOOT_TYPE_TEST ;
287296 }
288- } else if (img_mgmt_vercmp (& aver , & over ) < 0 ) {
297+ } else if ((img_mgmt_vercmp (& aver , & over ) < 0 ) ||
298+ ((img_mgmt_vercmp (& aver , & over ) == 0 ) && (active_slot > other_slot ))) {
299+ /* Check if MCUboot will select the non-active slot during the next boot.
300+ * The logic is as follows:
301+ * - If both slots are valid, a slot with higher version is preferred.
302+ * - If both slots are valid and the versions are equal, a slot with lower number
303+ * is preferred.
304+ */
289305 if (other_slot_state == DIRECT_XIP_BOOT_FOREVER ) {
290306 return_slot = other_slot ;
291307 } else if (other_slot_state == DIRECT_XIP_BOOT_ONCE ) {
@@ -296,7 +312,15 @@ int img_mgmt_get_next_boot_slot(int image, enum img_mgmt_next_boot_type *type)
296312
297313out :
298314#else
299- if (rcs == 0 && rca == 0 && img_mgmt_vercmp (& aver , & over ) < 0 ) {
315+ if (rcs == 0 && rca == 0 &&
316+ ((img_mgmt_vercmp (& aver , & over ) < 0 ) ||
317+ ((img_mgmt_vercmp (& aver , & over ) == 0 ) && (active_slot > other_slot )))) {
318+ /* Check if MCUboot will select the non-active slot during the next boot.
319+ * The logic is as follows:
320+ * - If both slots are valid, a slot with higher version is preferred.
321+ * - If both slots are valid and the versions are equal, a slot with lower number
322+ * is preferred.
323+ */
300324 return_slot = other_slot ;
301325 }
302326#endif /* defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) */
0 commit comments