diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 30b1654fdfd..91dd73a2d9b 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -26,6 +26,10 @@ extern "C" { #endif +#ifndef CONFIG_SHELL_PROMPT_BUFF_SIZE +#define CONFIG_SHELL_PROMPT_BUFF_SIZE 0 +#endif + #ifndef CONFIG_SHELL_CMD_BUFF_SIZE #define CONFIG_SHELL_CMD_BUFF_SIZE 0 #endif @@ -779,7 +783,11 @@ enum shell_signal { * @brief Shell instance context. */ struct shell_ctx { - const char *prompt; /*!< shell current prompt. */ +#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE + char prompt[CONFIG_SHELL_PROMPT_BUFF_SIZE]; /*!< shell current prompt. */ +#else + const char *prompt; +#endif enum shell_state state; /*!< Internal module state.*/ enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/ diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index 618570af1e2..5921a56bb49 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -55,6 +55,24 @@ config SHELL_BACKSPACE_MODE_DELETE Some terminals send code: 0x08 (backspace) other 0x7F (delete). When this option is set shell will expect 0x7F for backspace key. +config SHELL_PROMPT_CHANGE + bool "Allow prompt change in runtime" + default y if !SHELL_MINIMAL + help + Allow for the modification of the shell prompt at runtime. + Enabling this will allocate additional RAM memory where + the string of the prompt will be stored. + +config SHELL_PROMPT_BUFF_SIZE + int "Shell prompt buffer size" + depends on SHELL_PROMPT_CHANGE + range 2 40 + default 10 if SHELL_MINIMAL + default 20 + help + Maximum prompt size in bytes. One byte is reserved for the string + terminator character. + config SHELL_CMD_BUFF_SIZE int "Shell command buffer size" default 128 if SHELL_MINIMAL diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 9cbd8a7158a..1bd8de70d02 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1208,7 +1208,6 @@ static int instance_init(const struct shell *sh, (sh->shell_flag == SHELL_FLAG_OLF_CRLF)); memset(sh->ctx, 0, sizeof(*sh->ctx)); - sh->ctx->prompt = sh->default_prompt; if (CONFIG_SHELL_CMD_ROOT[0]) { sh->ctx->selected_cmd = root_cmd_find(CONFIG_SHELL_CMD_ROOT); } @@ -1235,7 +1234,13 @@ static int instance_init(const struct shell *sh, CONFIG_SHELL_DEFAULT_TERMINAL_WIDTH; sh->ctx->vt100_ctx.cons.terminal_hei = CONFIG_SHELL_DEFAULT_TERMINAL_HEIGHT; + +#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE + shell_prompt_change(sh, sh->default_prompt); +#else + sh->ctx->prompt = sh->default_prompt; sh->ctx->vt100_ctx.cons.name_len = z_shell_strlen(sh->ctx->prompt); +#endif /* Configure backend according to enabled shell features and backend * specific settings. @@ -1614,15 +1619,35 @@ void shell_hexdump(const struct shell *sh, const uint8_t *data, size_t len) int shell_prompt_change(const struct shell *sh, const char *prompt) { +#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE __ASSERT_NO_MSG(sh); if (prompt == NULL) { return -EINVAL; } - sh->ctx->prompt = prompt; - sh->ctx->vt100_ctx.cons.name_len = z_shell_strlen(prompt); + + static const size_t mtx_timeout_ms = 20; + size_t prompt_length = z_shell_strlen(prompt); + + if (k_mutex_lock(&sh->ctx->wr_mtx, K_MSEC(mtx_timeout_ms))) { + return -EBUSY; + } + + if ((prompt_length + 1 > CONFIG_SHELL_PROMPT_BUFF_SIZE) || (prompt_length == 0)) { + k_mutex_unlock(&sh->ctx->wr_mtx); + return -EINVAL; + } + + strcpy(sh->ctx->prompt, prompt); + + sh->ctx->vt100_ctx.cons.name_len = prompt_length; + + k_mutex_unlock(&sh->ctx->wr_mtx); return 0; +#else + return -EPERM; +#endif } void shell_help(const struct shell *sh)