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 <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-03-18 11:05:01 +01:00 committed by Anas Nashif
commit 0225ea7ab0
2 changed files with 31 additions and 5 deletions

View file

@ -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.

View file

@ -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);
}
}