Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ extern "C" {
struct os_mgmt_reset_data {
/** Contains the value of the force parameter. */
bool force;

#if defined(CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE) || defined(__DOXYGEN__)
/** Contains the value of the boot_mode parameter. */
uint8_t boot_mode;
#endif
};

/**
Expand Down
8 changes: 8 additions & 0 deletions subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ config MCUMGR_GRP_OS_RESET_HOOK
and will allow the application to perform any required operations
before accepting or declining the reset request.

config MCUMGR_GRP_OS_RESET_BOOT_MODE
bool "Boot mode"
depends on RETENTION_BOOT_MODE
help
Allows applications to set the boot mode using the retention boot mode module which
allows for booting other images e.g. as part of a bootloader. This is done with an
optional field in the reset command which specifies the value of the boot mode.

endif

config MCUMGR_GRP_OS_TASKSTAT
Expand Down
54 changes: 52 additions & 2 deletions subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,17 @@
#endif
#endif

#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
#include <zephyr/retention/bootmode.h>
#include <limits.h>
#endif

LOG_MODULE_REGISTER(mcumgr_os_grp, CONFIG_MCUMGR_GRP_OS_LOG_LEVEL);

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

K_WORK_DELAYABLE_DEFINE(os_mgmt_reset_work, os_mgmt_reset_work_handler);
static K_WORK_DELAYABLE_DEFINE(os_mgmt_reset_work, os_mgmt_reset_work_handler);
#endif

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

#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
uint32_t boot_mode = BOOT_MODE_TYPE_NORMAL;
#endif

struct os_mgmt_reset_data reboot_data = {
.force = false
};

struct zcbor_map_decode_key_val reset_decode[] = {
ZCBOR_MAP_DECODE_KEY_DECODER("force", zcbor_bool_decode, &reboot_data.force),
#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
ZCBOR_MAP_DECODE_KEY_DECODER("boot_mode", zcbor_uint32_decode, &boot_mode),
#endif
};

/* Since this is a core command, if we fail to decode the data, ignore the error and
* continue with the default parameter of force being false.
* continue with the default parameters.
*/
(void)zcbor_map_decode_bulk(zsd, reset_decode, ARRAY_SIZE(reset_decode), &decoded);

#ifdef CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE
if (zcbor_map_decode_bulk_key_found(reset_decode, ARRAY_SIZE(reset_decode), "boot_mode")) {
if (boot_mode > UCHAR_MAX) {
return MGMT_ERR_EINVAL;
}

reboot_data.boot_mode = (uint8_t)boot_mode;
} else {
reboot_data.boot_mode = BOOT_MODE_TYPE_NORMAL;
}
#endif

status = mgmt_callback_notify(MGMT_EVT_OP_OS_MGMT_RESET, &reboot_data,
sizeof(reboot_data), &err_rc, &err_group);

Expand All @@ -398,6 +423,31 @@ static int os_mgmt_reset(struct smp_streamer *ctxt)
ok = smp_add_cmd_err(zse, err_group, (uint16_t)err_rc);
return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE;
}
#elif defined(CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE)
zcbor_state_t *zsd = ctxt->reader->zs;
size_t decoded;
uint32_t boot_mode;

struct zcbor_map_decode_key_val reset_decode[] = {
ZCBOR_MAP_DECODE_KEY_DECODER("boot_mode", zcbor_uint32_decode, &boot_mode),
};

/* Since this is a core command, if we fail to decode the data, ignore the error and
* continue with the default parameters.
*/
(void)zcbor_map_decode_bulk(zsd, reset_decode, ARRAY_SIZE(reset_decode), &decoded);

if (zcbor_map_decode_bulk_key_found(reset_decode, ARRAY_SIZE(reset_decode), "boot_mode")) {
if (boot_mode > UCHAR_MAX) {
return MGMT_ERR_EINVAL;
}
}
#endif

#if defined(CONFIG_MCUMGR_GRP_OS_RESET_BOOT_MODE)
if (zcbor_map_decode_bulk_key_found(reset_decode, ARRAY_SIZE(reset_decode), "boot_mode")) {
(void)bootmode_set((uint8_t)boot_mode);
}
#endif

#ifdef CONFIG_MULTITHREADING
Expand Down