From 0225ea7ab0a018e7434b33c01303bef9d7fbd994 Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Thu, 18 Mar 2021 11:05:01 +0100 Subject: [PATCH] shell: Add callback to shell_uninit function Shell uninitialization is not synchronous, it is deferred to shell thread so resources used by the shell (e.g. transport resource like uart) cannot be used until it is completed. Added callback which notifies when all resources are released and shell is uninitialized. Callback is called from shell thread just before it is aborted. Signed-off-by: Krzysztof Chruscinski --- include/shell/shell.h | 11 ++++++++++- subsys/shell/shell.c | 25 +++++++++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) 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); } }