Skip to content

Commit 3849be3

Browse files
committed
[nrf fromtree] mgmt: mcumgr: grp: os_mgmt: Add optional boot mode for reset
Adds an optional boot mode field which can be used to boot into a specific image or mode using MCUmgr's OS mgmt reset command Signed-off-by: Jamie McCrae <[email protected]> (cherry picked from commit 0adcf2e)
1 parent 7830f6c commit 3849be3

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ extern "C" {
2626
struct os_mgmt_reset_data {
2727
/** Contains the value of the force parameter. */
2828
bool force;
29+
30+
#if defined(CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE) || defined(__DOXYGEN__)
31+
/** Contains the value of the boot_mode parameter. */
32+
uint8_t boot_mode;
33+
#endif
2934
};
3035

3136
/**

subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ config MCUMGR_GRP_OS_RESET_HOOK
4343
and will allow the application to perform any required operations
4444
before accepting or declining the reset request.
4545

46+
config MCUMGR_GRP_OS_RESET_BOOT_MODE
47+
bool "Boot mode"
48+
depends on RETENTION_BOOT_MODE
49+
help
50+
Allows applications to set the boot mode using the retention boot mode module which
51+
allows for booting other images e.g. as part of a bootloader. This is done with an
52+
optional field in the reset command which specifies the value of the boot mode.
53+
4654
endif
4755

4856
config MCUMGR_GRP_OS_TASKSTAT

subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,17 @@
5555
#endif
5656
#endif
5757

58+
#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
59+
#include <zephyr/retention/bootmode.h>
60+
#include <limits.h>
61+
#endif
62+
5863
LOG_MODULE_REGISTER(mcumgr_os_grp, CONFIG_MCUMGR_GRP_OS_LOG_LEVEL);
5964

6065
#if defined(CONFIG_REBOOT) && defined(CONFIG_MULTITHREADING)
6166
static void os_mgmt_reset_work_handler(struct k_work *work);
6267

63-
K_WORK_DELAYABLE_DEFINE(os_mgmt_reset_work, os_mgmt_reset_work_handler);
68+
static K_WORK_DELAYABLE_DEFINE(os_mgmt_reset_work, os_mgmt_reset_work_handler);
6469
#endif
6570

6671
/* This is passed to zcbor_map_start/end_endcode as a number of
@@ -373,18 +378,38 @@ static int os_mgmt_reset(struct smp_streamer *ctxt)
373378
int32_t err_rc;
374379
uint16_t err_group;
375380

381+
#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
382+
uint32_t boot_mode = BOOT_MODE_TYPE_NORMAL;
383+
#endif
384+
376385
struct os_mgmt_reset_data reboot_data = {
377386
.force = false
378387
};
379388

380389
struct zcbor_map_decode_key_val reset_decode[] = {
381390
ZCBOR_MAP_DECODE_KEY_DECODER("force", zcbor_bool_decode, &reboot_data.force),
391+
#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
392+
ZCBOR_MAP_DECODE_KEY_DECODER("boot_mode", zcbor_uint32_decode, &boot_mode),
393+
#endif
382394
};
383395

384396
/* Since this is a core command, if we fail to decode the data, ignore the error and
385-
* continue with the default parameter of force being false.
397+
* continue with the default parameters.
386398
*/
387399
(void)zcbor_map_decode_bulk(zsd, reset_decode, ARRAY_SIZE(reset_decode), &decoded);
400+
401+
#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
402+
if (zcbor_map_decode_bulk_key_found(reset_decode, ARRAY_SIZE(reset_decode), "boot_mode")) {
403+
if (boot_mode > UCHAR_MAX) {
404+
return MGMT_ERR_EINVAL;
405+
}
406+
407+
reboot_data.boot_mode = (uint8_t)boot_mode;
408+
} else {
409+
reboot_data.boot_mode = BOOT_MODE_TYPE_NORMAL;
410+
}
411+
#endif
412+
388413
status = mgmt_callback_notify(MGMT_EVT_OP_OS_MGMT_RESET, &reboot_data,
389414
sizeof(reboot_data), &err_rc, &err_group);
390415

@@ -398,6 +423,31 @@ static int os_mgmt_reset(struct smp_streamer *ctxt)
398423
ok = smp_add_cmd_err(zse, err_group, (uint16_t)err_rc);
399424
return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE;
400425
}
426+
#elif defined(CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE)
427+
zcbor_state_t *zsd = ctxt->reader->zs;
428+
size_t decoded;
429+
uint32_t boot_mode;
430+
431+
struct zcbor_map_decode_key_val reset_decode[] = {
432+
ZCBOR_MAP_DECODE_KEY_DECODER("boot_mode", zcbor_uint32_decode, &boot_mode),
433+
};
434+
435+
/* Since this is a core command, if we fail to decode the data, ignore the error and
436+
* continue with the default parameters.
437+
*/
438+
(void)zcbor_map_decode_bulk(zsd, reset_decode, ARRAY_SIZE(reset_decode), &decoded);
439+
440+
if (zcbor_map_decode_bulk_key_found(reset_decode, ARRAY_SIZE(reset_decode), "boot_mode")) {
441+
if (boot_mode > UCHAR_MAX) {
442+
return MGMT_ERR_EINVAL;
443+
}
444+
}
445+
#endif
446+
447+
#if defined(CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE)
448+
if (zcbor_map_decode_bulk_key_found(reset_decode, ARRAY_SIZE(reset_decode), "boot_mode")) {
449+
(void)bootmode_set((uint8_t)boot_mode);
450+
}
401451
#endif
402452

403453
#ifdef CONFIG_MULTITHREADING

0 commit comments

Comments
 (0)