diff --git a/include/shell/shell.h b/include/shell/shell.h index 125e2ef043c..c48907baa4a 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -498,6 +498,9 @@ enum shell_transport_evt { typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt, void *context); + +typedef void (*shell_uninit_cb_t)(const struct shell *shell, int res); + struct shell_transport; /** @@ -655,6 +658,11 @@ struct shell_ctx { /*!< VT100 color and cursor position, terminal width.*/ struct shell_vt100_ctx vt100_ctx; + /*!< Callback called from shell thread context when unitialization is + * completed just before aborting shell thread. + */ + shell_uninit_cb_t uninit_cb; + #if defined CONFIG_SHELL_GETOPT /*!< getopt context for a shell backend. */ struct getopt_state getopt_state; @@ -785,10 +793,11 @@ int shell_init(const struct shell *shell, const void *transport_config, * @brief Uninitializes the transport layer and the internal shell state. * * @param shell Pointer to shell instance. + * @param cb Callback called when uninitialization is completed. * * @return Standard error code. */ -int shell_uninit(const struct shell *shell); +void shell_uninit(const struct shell *shell, shell_uninit_cb_t cb); /** * @brief Function for starting shell processing. diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index e9c8786bdbd..5237d76e1e7 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1233,7 +1233,13 @@ static void shell_signal_handle(const struct shell *shell, static void kill_handler(const struct shell *shell) { - (void)instance_uninit(shell); + int err = instance_uninit(shell); + + if (shell->ctx->uninit_cb) { + shell->ctx->uninit_cb(shell, err); + } + + shell->ctx->tid = NULL; k_thread_abort(k_current_get()); } @@ -1297,6 +1303,10 @@ int shell_init(const struct shell *shell, const void *transport_config, __ASSERT_NO_MSG(shell); __ASSERT_NO_MSG(shell->ctx && shell->iface && shell->default_prompt); + if (shell->ctx->tid) { + return -EALREADY; + } + int err = instance_init(shell, transport_config, use_colors); if (err != 0) { @@ -1315,7 +1325,7 @@ int shell_init(const struct shell *shell, const void *transport_config, return 0; } -int shell_uninit(const struct shell *shell) +void shell_uninit(const struct shell *shell, shell_uninit_cb_t cb) { __ASSERT_NO_MSG(shell); @@ -1323,12 +1333,19 @@ int shell_uninit(const struct shell *shell) struct k_poll_signal *signal = &shell->ctx->signals[SHELL_SIGNAL_KILL]; + shell->ctx->uninit_cb = cb; /* signal kill message */ (void)k_poll_signal_raise(signal, 0); - return 0; + return; + } + + int err = instance_uninit(shell); + + if (cb) { + cb(shell, err); } else { - return instance_uninit(shell); + __ASSERT_NO_MSG(0); } }