shell: make flag modification atomic
Add Z_SHELL_SET_FLAG_ATOMIC macro to use technique from shell_process() to atomically set and return the previous value. Change all void z_flag_*_set() functions to bool z_flag_*_set() and use macro to return previous value after setting. Modify shell_process() to use this modified z_flag_processing_set() function. Reorder flags to keep last_nl on byte boundary. Add public setters for insert_mode, echo, and mode_delete for completeness. Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
This commit is contained in:
parent
7981d2344a
commit
75a74bfad2
3 changed files with 149 additions and 43 deletions
|
@ -613,8 +613,8 @@ struct shell_flags {
|
|||
uint32_t tx_rdy :1;
|
||||
uint32_t mode_delete :1; /*!< Operation mode of backspace key */
|
||||
uint32_t history_exit:1; /*!< Request to exit history mode */
|
||||
uint32_t cmd_ctx :1; /*!< Shell is executing command */
|
||||
uint32_t last_nl :8; /*!< Last received new line character */
|
||||
uint32_t cmd_ctx :1; /*!< Shell is executing command */
|
||||
uint32_t print_noinit:1; /*!< Print request from not initialized shell*/
|
||||
};
|
||||
|
||||
|
@ -1036,29 +1036,68 @@ int shell_execute_cmd(const struct shell *shell, const char *cmd);
|
|||
int shell_set_root_cmd(const char *cmd);
|
||||
|
||||
/**
|
||||
* @brief Allow application to control whether terminal output uses colored
|
||||
* syntax.
|
||||
* @brief Allow application to control text insert mode.
|
||||
* Value is modified atomically and the previous value is returned.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] use_colors Color mode.
|
||||
* @param[in] val Insert mode.
|
||||
*
|
||||
* @retval 0 if set.
|
||||
* @retval 0 or 1: previous value
|
||||
* @retval -EINVAL if shell is NULL.
|
||||
*/
|
||||
int shell_use_colors_set(const struct shell *shell, bool use_colors);
|
||||
int shell_insert_mode_set(const struct shell *shell, bool val);
|
||||
|
||||
/**
|
||||
* @brief Allow application to control whether terminal output uses colored
|
||||
* syntax.
|
||||
* Value is modified atomically and the previous value is returned.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] val Color mode.
|
||||
*
|
||||
* @retval 0 or 1: previous value
|
||||
* @retval -EINVAL if shell is NULL.
|
||||
*/
|
||||
int shell_use_colors_set(const struct shell *shell, bool val);
|
||||
|
||||
/**
|
||||
* @brief Allow application to control whether user input is echoed back.
|
||||
* Value is modified atomically and the previous value is returned.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] val Echo mode.
|
||||
*
|
||||
* @retval 0 or 1: previous value
|
||||
* @retval -EINVAL if shell is NULL.
|
||||
*/
|
||||
int shell_echo_set(const struct shell *shell, bool val);
|
||||
|
||||
/**
|
||||
* @brief Allow application to control whether user input is obscured with
|
||||
* asterisks -- useful for implementing passwords.
|
||||
* Value is modified atomically and the previous value is returned.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] obscure Obscure mode.
|
||||
*
|
||||
* @retval 0 if set.
|
||||
* @retval 0 or 1: previous value.
|
||||
* @retval -EINVAL if shell is NULL.
|
||||
*/
|
||||
int shell_obscure_set(const struct shell *shell, bool obscure);
|
||||
|
||||
/**
|
||||
* @brief Allow application to control whether the delete key backspaces or
|
||||
* deletes.
|
||||
* Value is modified atomically and the previous value is returned.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] val Delete mode.
|
||||
*
|
||||
* @retval 0 or 1: previous value
|
||||
* @retval -EINVAL if shell is NULL.
|
||||
*/
|
||||
int shell_mode_delete_set(const struct shell *shell, bool val);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -1377,13 +1377,8 @@ void shell_process(const struct shell *shell)
|
|||
__ASSERT_NO_MSG(shell);
|
||||
__ASSERT_NO_MSG(shell->ctx);
|
||||
|
||||
union shell_internal internal;
|
||||
|
||||
internal.value = 0U;
|
||||
internal.flags.processing = 1U;
|
||||
|
||||
(void)atomic_or((atomic_t *)&shell->ctx->internal.value,
|
||||
internal.value);
|
||||
/* atomically set the processing flag */
|
||||
z_flag_processing_set(shell, true);
|
||||
|
||||
switch (shell->ctx->state) {
|
||||
case SHELL_STATE_UNINITIALIZED:
|
||||
|
@ -1398,10 +1393,8 @@ void shell_process(const struct shell *shell)
|
|||
break;
|
||||
}
|
||||
|
||||
internal.value = 0xFFFFFFFF;
|
||||
internal.flags.processing = 0U;
|
||||
(void)atomic_and((atomic_t *)&shell->ctx->internal.value,
|
||||
internal.value);
|
||||
/* atomically clear the processing flag */
|
||||
z_flag_processing_set(shell, false);
|
||||
}
|
||||
|
||||
/* This function mustn't be used from shell context to avoid deadlock.
|
||||
|
@ -1560,26 +1553,49 @@ int shell_execute_cmd(const struct shell *shell, const char *cmd)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
int shell_use_colors_set(const struct shell *shell, bool use_colors)
|
||||
int shell_insert_mode_set(const struct shell *shell, bool val)
|
||||
{
|
||||
if (shell == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
z_flag_use_colors_set(shell, use_colors);
|
||||
|
||||
return 0;
|
||||
return (int)z_flag_insert_mode_set(shell, val);
|
||||
}
|
||||
|
||||
int shell_obscure_set(const struct shell *shell, bool obscure)
|
||||
int shell_use_colors_set(const struct shell *shell, bool val)
|
||||
{
|
||||
if (shell == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
z_flag_obscure_set(shell, obscure);
|
||||
return (int)z_flag_use_colors_set(shell, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
int shell_echo_set(const struct shell *shell, bool val)
|
||||
{
|
||||
if (shell == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (int)z_flag_echo_set(shell, val);
|
||||
}
|
||||
|
||||
int shell_obscure_set(const struct shell *shell, bool val)
|
||||
{
|
||||
if (shell == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (int)z_flag_obscure_set(shell, val);
|
||||
}
|
||||
|
||||
int shell_mode_delete_set(const struct shell *shell, bool val)
|
||||
{
|
||||
if (shell == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (int)z_flag_mode_delete_set(shell, val);
|
||||
}
|
||||
|
||||
static int cmd_help(const struct shell *shell, size_t argc, char **argv)
|
||||
|
|
|
@ -60,14 +60,33 @@ static inline void z_cursor_next_line_move(const struct shell *shell)
|
|||
z_shell_raw_fprintf(shell->fprintf_ctx, "\n");
|
||||
}
|
||||
|
||||
#define Z_SHELL_SET_FLAG_ATOMIC(_shell_, _flag_, _val_, _ret_) \
|
||||
do { \
|
||||
union shell_internal _internal_; \
|
||||
atomic_t *_dst_ = (atomic_t *)&(_shell_)->ctx->internal.value; \
|
||||
_internal_.value = 0U; \
|
||||
_internal_.flags._flag_ = 1U; \
|
||||
if (_val_) { \
|
||||
_internal_.value = atomic_or(_dst_, \
|
||||
_internal_.value); \
|
||||
} else { \
|
||||
_internal_.value = atomic_and(_dst_, \
|
||||
~_internal_.value); \
|
||||
} \
|
||||
_ret_ = (_internal_.flags._flag_ != 0); \
|
||||
} while (0)
|
||||
|
||||
static inline bool z_flag_insert_mode_get(const struct shell *shell)
|
||||
{
|
||||
return shell->ctx->internal.flags.insert_mode == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_insert_mode_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_insert_mode_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.insert_mode = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, insert_mode, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_use_colors_get(const struct shell *shell)
|
||||
|
@ -75,9 +94,12 @@ static inline bool z_flag_use_colors_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.use_colors == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_use_colors_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_use_colors_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.use_colors = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, use_colors, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_echo_get(const struct shell *shell)
|
||||
|
@ -85,9 +107,12 @@ static inline bool z_flag_echo_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.echo == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_echo_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_echo_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.echo = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, echo, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_obscure_get(const struct shell *shell)
|
||||
|
@ -95,9 +120,12 @@ static inline bool z_flag_obscure_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.obscure == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_obscure_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_obscure_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.obscure = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, obscure, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_processing_get(const struct shell *shell)
|
||||
|
@ -105,14 +133,25 @@ static inline bool z_flag_processing_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.processing == 1;
|
||||
}
|
||||
|
||||
static inline bool z_flag_processing_set(const struct shell *shell, bool val)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, processing, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_tx_rdy_get(const struct shell *shell)
|
||||
{
|
||||
return shell->ctx->internal.flags.tx_rdy == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_tx_rdy_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_tx_rdy_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.tx_rdy = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, tx_rdy, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_mode_delete_get(const struct shell *shell)
|
||||
|
@ -120,9 +159,12 @@ static inline bool z_flag_mode_delete_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.mode_delete == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_mode_delete_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_mode_delete_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.mode_delete = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, mode_delete, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_history_exit_get(const struct shell *shell)
|
||||
|
@ -130,9 +172,12 @@ static inline bool z_flag_history_exit_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.history_exit == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_history_exit_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_history_exit_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.history_exit = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, history_exit, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool z_flag_cmd_ctx_get(const struct shell *shell)
|
||||
|
@ -140,9 +185,12 @@ static inline bool z_flag_cmd_ctx_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.cmd_ctx == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_cmd_ctx_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_cmd_ctx_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.cmd_ctx = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, cmd_ctx, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint8_t z_flag_last_nl_get(const struct shell *shell)
|
||||
|
@ -160,9 +208,12 @@ static inline bool z_flag_print_noinit_get(const struct shell *shell)
|
|||
return shell->ctx->internal.flags.print_noinit == 1;
|
||||
}
|
||||
|
||||
static inline void z_flag_print_noinit_set(const struct shell *shell, bool val)
|
||||
static inline bool z_flag_print_noinit_set(const struct shell *shell, bool val)
|
||||
{
|
||||
shell->ctx->internal.flags.print_noinit = val ? 1 : 0;
|
||||
bool ret;
|
||||
|
||||
Z_SHELL_SET_FLAG_ATOMIC(shell, print_noinit, val, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void z_shell_op_cursor_vert_move(const struct shell *shell, int32_t delta);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue