From 898a59eb80d3bb86207e79f01748a540c33d9d9e Mon Sep 17 00:00:00 2001 From: Hunter Searle Date: Tue, 25 Apr 2023 17:59:19 -0500 Subject: [PATCH] Shell: Edit shell to store/retrieve return values This change to the shell API enables the user to retrieve the return code of the most recently run shell command. This is useful both for users wanting specific information beyond the print statements in a command, but especially for automated users that prefer a simple return code to parsing human readable text. This was tested using all default shell commands, as well as eeprom, flash, and i2c, where specific errors could be forced. In all cases, the correct return value was returned by the new retval command. Signed-off-by: Hunter Searle --- include/zephyr/shell/shell.h | 10 ++++++++++ subsys/shell/Kconfig | 8 ++++++++ subsys/shell/shell.c | 11 ++++++++++- subsys/shell/shell_cmds.c | 12 ++++++++++++ subsys/shell/shell_ops.h | 5 +++++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 662de2607cb..3a29b46c10c 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -823,6 +823,7 @@ struct shell_ctx { struct k_mutex wr_mtx; k_tid_t tid; + int ret_val; }; extern const struct log_backend_api log_backend_shell_api; @@ -1239,6 +1240,15 @@ int shell_obscure_set(const struct shell *sh, bool obscure); */ int shell_mode_delete_set(const struct shell *sh, bool val); +/** + * @brief Retrieve return value of most recently executed shell command. + * + * @param[in] sh Pointer to the shell instance + * + * @retval return value of previous command + */ +int shell_get_return_value(const struct shell *sh); + /** * @} */ diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index 5ec89ce50fc..d155622e7bb 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -251,6 +251,14 @@ config SHELL_AUTOSTART help If enabled, shell will be automatically started. +config SHELL_CMDS_RETURN_VALUE + bool "Retval command" + depends on SHELL_CMDS + default y + help + This option enables the retval command. It is used to retrieve + the return value from the most recently executed command. + source "subsys/shell/modules/Kconfig" endif # SHELL diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 25dcdad3129..e1f6424dbb3 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1001,7 +1001,7 @@ static void state_collect(const struct shell *sh) z_cursor_next_line_move(sh); } else { /* Command execution */ - (void)execute(sh); + sh->ctx->ret_val = execute(sh); } /* Function responsible for printing prompt * on received NL. @@ -1670,6 +1670,15 @@ int shell_use_vt100_set(const struct shell *sh, bool val) return (int)z_flag_use_vt100_set(sh, val); } +int shell_get_return_value(const struct shell *sh) +{ + if (sh == NULL) { + return -EINVAL; + } + + return z_shell_get_return_value(sh); +} + int shell_echo_set(const struct shell *sh, bool val) { if (sh == NULL) { diff --git a/subsys/shell/shell_cmds.c b/subsys/shell/shell_cmds.c index ee08eb77736..4454fb31b17 100644 --- a/subsys/shell/shell_cmds.c +++ b/subsys/shell/shell_cmds.c @@ -10,6 +10,7 @@ #include "shell_vt100.h" #define SHELL_MSG_CMD_NOT_SUPPORTED "Command not supported.\n" +#define SHELL_HELP_RETVAL "Print return value of most recent command" #define SHELL_HELP_CLEAR "Clear screen." #define SHELL_HELP_BACKENDS "List active shell backends.\n" #define SHELL_HELP_BACKSPACE_MODE "Toggle backspace key mode.\n" \ @@ -402,6 +403,15 @@ static int cmd_resize(const struct shell *sh, size_t argc, char **argv) return 0; } +static int cmd_get_retval(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + shell_print(sh, "%d", shell_get_return_value(sh)); + return 0; +} + static bool no_args(const struct shell_static_entry *entry) { return (entry->args.mandatory == 1) && (entry->args.optional == 0); @@ -498,3 +508,5 @@ SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_RESIZE, resize, &m_sub_resize, SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_SELECT, select, NULL, SHELL_HELP_SELECT, cmd_select, 2, SHELL_OPT_ARG_CHECK_SKIP); +SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_RETURN_VALUE, retval, NULL, + SHELL_HELP_RETVAL, cmd_get_retval, 1, 0); diff --git a/subsys/shell/shell_ops.h b/subsys/shell/shell_ops.h index 39b66014360..59c4d8f738c 100644 --- a/subsys/shell/shell_ops.h +++ b/subsys/shell/shell_ops.h @@ -185,6 +185,11 @@ static inline uint8_t z_flag_last_nl_get(const struct shell *sh) return sh->ctx->ctx.flags.last_nl; } +static inline int z_shell_get_return_value(const struct shell *sh) +{ + return sh->ctx->ret_val; +} + static inline void z_flag_last_nl_set(const struct shell *sh, uint8_t val) { sh->ctx->ctx.flags.last_nl = val;