diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 3d93dca841f..3b0d31b2a6d 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -963,7 +963,7 @@ struct shell_ctx { struct k_event signal_event; - struct k_mutex wr_mtx; + struct k_sem lock_sem; k_tid_t tid; int ret_val; }; diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 63b3274e3bb..fdfd0a92a24 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -562,11 +562,11 @@ static int exec_cmd(const struct shell *sh, size_t argc, const char **argv, /* Unlock thread mutex in case command would like to borrow * shell context to other thread to avoid mutex deadlock. */ - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); ret_val = sh->ctx->active_cmd.handler(sh, argc, (char **)argv); /* Bring back mutex to shell thread. */ - k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER); + z_shell_lock(sh); z_flag_cmd_ctx_set(sh, false); } @@ -1217,7 +1217,7 @@ static int instance_init(const struct shell *sh, history_init(sh); k_event_init(&sh->ctx->signal_event); - k_mutex_init(&sh->ctx->wr_mtx); + k_sem_init(&sh->ctx->lock_sem, 1, 1); if (IS_ENABLED(CONFIG_SHELL_STATS)) { sh->stats->log_lost_cnt = 0; @@ -1342,7 +1342,7 @@ void shell_thread(void *shell_handle, void *arg_log_backend, false, K_FOREVER); - k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER); + z_shell_lock(sh); shell_signal_handle(sh, SHELL_SIGNAL_KILL, kill_handler); shell_signal_handle(sh, SHELL_SIGNAL_RXRDY, shell_process); @@ -1355,7 +1355,7 @@ void shell_thread(void *shell_handle, void *arg_log_backend, sh->iface->api->update(sh->iface); } - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); } } @@ -1420,7 +1420,7 @@ int shell_start(const struct shell *sh) z_shell_log_backend_enable(sh->log_backend, (void *)sh, sh->ctx->log_level); } - if (k_mutex_lock(&sh->ctx->wr_mtx, SHELL_TX_MTX_TIMEOUT) != 0) { + if (!z_shell_trylock(sh, SHELL_TX_MTX_TIMEOUT)) { return -EBUSY; } @@ -1442,7 +1442,7 @@ int shell_start(const struct shell *sh) */ z_shell_backend_rx_buffer_flush(sh); - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); return 0; } @@ -1524,7 +1524,7 @@ void shell_vfprintf(const struct shell *sh, enum shell_vt100_color color, return; } - if (k_mutex_lock(&sh->ctx->wr_mtx, SHELL_TX_MTX_TIMEOUT) != 0) { + if (!z_shell_trylock(sh, SHELL_TX_MTX_TIMEOUT)) { return; } @@ -1537,7 +1537,7 @@ void shell_vfprintf(const struct shell *sh, enum shell_vt100_color color, } z_transport_buffer_flush(sh); - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); } /* These functions mustn't be used from shell context to avoid deadlock: @@ -1664,12 +1664,12 @@ int shell_prompt_change(const struct shell *sh, const char *prompt) size_t prompt_length = z_shell_strlen(prompt); - if (k_mutex_lock(&sh->ctx->wr_mtx, SHELL_TX_MTX_TIMEOUT) != 0) { + if (!z_shell_trylock(sh, SHELL_TX_MTX_TIMEOUT)) { return -EBUSY; } if ((prompt_length + 1 > CONFIG_SHELL_PROMPT_BUFF_SIZE) || (prompt_length == 0)) { - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); return -EINVAL; } @@ -1677,7 +1677,7 @@ int shell_prompt_change(const struct shell *sh, const char *prompt) sh->ctx->vt100_ctx.cons.name_len = prompt_length; - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); return 0; #else @@ -1687,11 +1687,11 @@ int shell_prompt_change(const struct shell *sh, const char *prompt) void shell_help(const struct shell *sh) { - if (k_mutex_lock(&sh->ctx->wr_mtx, SHELL_TX_MTX_TIMEOUT) != 0) { + if (!z_shell_trylock(sh, SHELL_TX_MTX_TIMEOUT)) { return; } shell_internal_help_print(sh); - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); } int shell_execute_cmd(const struct shell *sh, const char *cmd) @@ -1722,11 +1722,11 @@ int shell_execute_cmd(const struct shell *sh, const char *cmd) sh->ctx->cmd_buff_len = cmd_len; sh->ctx->cmd_buff_pos = cmd_len; - if (k_mutex_lock(&sh->ctx->wr_mtx, SHELL_TX_MTX_TIMEOUT) != 0) { + if (!z_shell_trylock(sh, SHELL_TX_MTX_TIMEOUT)) { return -ENOEXEC; } ret_val = execute(sh); - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); cmd_buffer_clear(sh); diff --git a/subsys/shell/shell_log_backend.c b/subsys/shell/shell_log_backend.c index e46876a057c..473bd50bc56 100644 --- a/subsys/shell/shell_log_backend.c +++ b/subsys/shell/shell_log_backend.c @@ -181,7 +181,7 @@ static void process_log_msg(const struct shell *sh, if (k_is_in_isr()) { key = irq_lock(); } else { - k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER); + z_shell_lock(sh); } if (!z_flag_cmd_ctx_get(sh)) { z_shell_cmd_line_erase(sh); @@ -197,7 +197,7 @@ static void process_log_msg(const struct shell *sh, if (k_is_in_isr()) { irq_unlock(key); } else { - k_mutex_unlock(&sh->ctx->wr_mtx); + z_shell_unlock(sh); } } } diff --git a/subsys/shell/shell_ops.h b/subsys/shell/shell_ops.h index c673c974331..a608c17daae 100644 --- a/subsys/shell/shell_ops.h +++ b/subsys/shell/shell_ops.h @@ -381,6 +381,21 @@ void z_shell_vfprintf(const struct shell *sh, enum shell_vt100_color color, */ void z_shell_backend_rx_buffer_flush(const struct shell *sh); +static inline bool z_shell_trylock(const struct shell *sh, k_timeout_t timeout) +{ + return k_sem_take(&sh->ctx->lock_sem, timeout) == 0; +} + +static inline void z_shell_lock(const struct shell *sh) +{ + (void)k_sem_take(&sh->ctx->lock_sem, K_FOREVER); +} + +static inline void z_shell_unlock(const struct shell *sh) +{ + k_sem_give(&sh->ctx->lock_sem); +} + #ifdef __cplusplus } #endif