Skip to content

Commit aafd4d5

Browse files
committed
[nrf fromlist] mgmt: Handle slot version equality
If slots have equal version, but a secondary slot is the active one, the next boot will switch to the primary slot. Expose this through SMP commands by marking the primary slot as pending. Upstream PR #: 98441 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent be5d777 commit aafd4d5

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

297313
out:
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

Comments
 (0)