When logging is using immediate mode then logging messages can be processed from any context, including interrupt context. z_shell_fprintf was asserting in that case since it allowed to be called from interrupt context only when logging was in panic mode. However, shell works in the same way when logging is in immediate mode as in panic mode. Renamed internal shell flag from panic_mode to sync_mode. Flag is also set when shell log backend is started in synchronous mode (immediate logging) which prevents assertion. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
1178 lines
36 KiB
C
1178 lines
36 KiB
C
/*
|
|
* Copyright (c) 2018 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef SHELL_H__
|
|
#define SHELL_H__
|
|
|
|
#include <zephyr.h>
|
|
#include <shell/shell_types.h>
|
|
#include <shell/shell_history.h>
|
|
#include <shell/shell_fprintf.h>
|
|
#include <shell/shell_log_backend.h>
|
|
#include <logging/log_instance.h>
|
|
#include <logging/log.h>
|
|
#include <sys/util.h>
|
|
|
|
#if defined CONFIG_SHELL_GETOPT
|
|
#include <shell/shell_getopt.h>
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
|
|
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
|
|
#endif
|
|
|
|
#ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE
|
|
#define CONFIG_SHELL_PRINTF_BUFF_SIZE 0
|
|
#endif
|
|
|
|
#ifndef CONFIG_SHELL_HISTORY_BUFFER
|
|
#define CONFIG_SHELL_HISTORY_BUFFER 0
|
|
#endif
|
|
|
|
#define Z_SHELL_CMD_ROOT_LVL (0u)
|
|
|
|
#define SHELL_HEXDUMP_BYTES_IN_LINE 16
|
|
|
|
/**
|
|
* @brief Flag indicates that optional arguments will be treated as one,
|
|
* unformatted argument.
|
|
*
|
|
* By default, shell is parsing all arguments, treats all spaces as argument
|
|
* separators unless they are within quotation marks which are removed in that
|
|
* case. If command rely on unformatted argument then this flag shall be used
|
|
* in place of number of optional arguments in command definition to indicate
|
|
* that only mandatory arguments shall be parsed and remaining command string is
|
|
* passed as a raw string.
|
|
*/
|
|
#define SHELL_OPT_ARG_RAW (0xFE)
|
|
|
|
/**
|
|
* @brief Flag indicateding that number of optional arguments is not limited.
|
|
*/
|
|
#define SHELL_OPT_ARG_CHECK_SKIP (0xFF)
|
|
|
|
/**
|
|
* @brief Flag indicating maximum number of optional arguments that can be
|
|
* validated.
|
|
*/
|
|
#define SHELL_OPT_ARG_MAX (0xFD)
|
|
|
|
/**
|
|
* @brief Shell API
|
|
* @defgroup shell_api Shell API
|
|
* @ingroup shell
|
|
* @{
|
|
*/
|
|
|
|
struct getopt_state;
|
|
struct shell_static_entry;
|
|
|
|
/**
|
|
* @brief Shell dynamic command descriptor.
|
|
*
|
|
* @details Function shall fill the received shell_static_entry structure
|
|
* with requested (idx) dynamic subcommand data. If there is more than
|
|
* one dynamic subcommand available, the function shall ensure that the
|
|
* returned commands: entry->syntax are sorted in alphabetical order.
|
|
* If idx exceeds the available dynamic subcommands, the function must
|
|
* write to entry->syntax NULL value. This will indicate to the shell
|
|
* module that there are no more dynamic commands to read.
|
|
*/
|
|
typedef void (*shell_dynamic_get)(size_t idx,
|
|
struct shell_static_entry *entry);
|
|
|
|
/**
|
|
* @brief Shell command descriptor.
|
|
*/
|
|
struct shell_cmd_entry {
|
|
bool is_dynamic;
|
|
union union_cmd_entry {
|
|
/*!< Pointer to function returning dynamic commands.*/
|
|
shell_dynamic_get dynamic_get;
|
|
|
|
/*!< Pointer to array of static commands. */
|
|
const struct shell_static_entry *entry;
|
|
} u;
|
|
};
|
|
|
|
struct shell;
|
|
|
|
struct shell_static_args {
|
|
uint8_t mandatory; /*!< Number of mandatory arguments. */
|
|
uint8_t optional; /*!< Number of optional arguments. */
|
|
};
|
|
|
|
/**
|
|
* @brief Get by index a device that matches .
|
|
*
|
|
* This can be used, for example, to identify I2C_1 as the second I2C
|
|
* device.
|
|
*
|
|
* Devices that failed to initialize or do not have a non-empty name
|
|
* are excluded from the candidates for a match.
|
|
*
|
|
* @param idx the device number starting from zero.
|
|
*
|
|
* @param prefix optional name prefix used to restrict candidate
|
|
* devices. Indexing is done relative to devices with names that
|
|
* start with this text. Pass null if no prefix match is required.
|
|
*/
|
|
const struct device *shell_device_lookup(size_t idx,
|
|
const char *prefix);
|
|
|
|
/**
|
|
* @brief Shell command handler prototype.
|
|
*
|
|
* @param shell Shell instance.
|
|
* @param argc Arguments count.
|
|
* @param argv Arguments.
|
|
*
|
|
* @retval 0 Successful command execution.
|
|
* @retval 1 Help printed and command not executed.
|
|
* @retval -EINVAL Argument validation failed.
|
|
* @retval -ENOEXEC Command not executed.
|
|
*/
|
|
typedef int (*shell_cmd_handler)(const struct shell *shell,
|
|
size_t argc, char **argv);
|
|
|
|
/**
|
|
* @brief Shell dictionary command handler prototype.
|
|
*
|
|
* @param shell Shell instance.
|
|
* @param argc Arguments count.
|
|
* @param argv Arguments.
|
|
* @param data Pointer to the user data.
|
|
*
|
|
* @retval 0 Successful command execution.
|
|
* @retval 1 Help printed and command not executed.
|
|
* @retval -EINVAL Argument validation failed.
|
|
* @retval -ENOEXEC Command not executed.
|
|
*/
|
|
typedef int (*shell_dict_cmd_handler)(const struct shell *shell, size_t argc,
|
|
char **argv, void *data);
|
|
|
|
/*
|
|
* @brief Shell static command descriptor.
|
|
*/
|
|
struct shell_static_entry {
|
|
const char *syntax; /*!< Command syntax strings. */
|
|
const char *help; /*!< Command help string. */
|
|
const struct shell_cmd_entry *subcmd; /*!< Pointer to subcommand. */
|
|
shell_cmd_handler handler; /*!< Command handler. */
|
|
struct shell_static_args args; /*!< Command arguments. */
|
|
};
|
|
|
|
/**
|
|
* @brief Macro for defining and adding a root command (level 0) with required
|
|
* number of arguments.
|
|
*
|
|
* @note Each root command shall have unique syntax. If a command will be called
|
|
* with wrong number of arguments shell will print an error message and command
|
|
* handler will not be called.
|
|
*
|
|
* @param[in] syntax Command syntax (for example: history).
|
|
* @param[in] subcmd Pointer to a subcommands array.
|
|
* @param[in] help Pointer to a command help string.
|
|
* @param[in] handler Pointer to a function handler.
|
|
* @param[in] mandatory Number of mandatory arguments includig command name.
|
|
* @param[in] optional Number of optional arguments.
|
|
*/
|
|
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
|
|
mandatory, optional) \
|
|
static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
|
|
SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \
|
|
static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \
|
|
__attribute__ ((section("." \
|
|
STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \
|
|
__attribute__((used)) = { \
|
|
.is_dynamic = false, \
|
|
.u = {.entry = &UTIL_CAT(_shell_, syntax)} \
|
|
}
|
|
|
|
/**
|
|
* @brief Macro for defining and adding a conditional root command (level 0)
|
|
* with required number of arguments.
|
|
*
|
|
* @see SHELL_CMD_ARG_REGISTER for details.
|
|
*
|
|
* Macro can be used to create a command which can be conditionally present.
|
|
* It is and alternative to \#ifdefs around command registration and command
|
|
* handler. If command is disabled handler and subcommands are removed from
|
|
* the application.
|
|
*
|
|
* @param[in] flag Compile time flag. Command is present only if flag
|
|
* exists and equals 1.
|
|
* @param[in] syntax Command syntax (for example: history).
|
|
* @param[in] subcmd Pointer to a subcommands array.
|
|
* @param[in] help Pointer to a command help string.
|
|
* @param[in] handler Pointer to a function handler.
|
|
* @param[in] mandatory Number of mandatory arguments includig command name.
|
|
* @param[in] optional Number of optional arguments.
|
|
*/
|
|
#define SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, \
|
|
mandatory, optional) \
|
|
COND_CODE_1(\
|
|
flag, \
|
|
(\
|
|
SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
|
|
mandatory, optional) \
|
|
), \
|
|
(\
|
|
static shell_cmd_handler dummy_##syntax##_handler __unused = \
|
|
handler;\
|
|
static const struct shell_cmd_entry *dummy_subcmd_##syntax \
|
|
__unused = subcmd\
|
|
)\
|
|
)
|
|
/**
|
|
* @brief Macro for defining and adding a root command (level 0) with
|
|
* arguments.
|
|
*
|
|
* @note All root commands must have different name.
|
|
*
|
|
* @param[in] syntax Command syntax (for example: history).
|
|
* @param[in] subcmd Pointer to a subcommands array.
|
|
* @param[in] help Pointer to a command help string.
|
|
* @param[in] handler Pointer to a function handler.
|
|
*/
|
|
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
|
|
SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, 0, 0)
|
|
|
|
/**
|
|
* @brief Macro for defining and adding a conditional root command (level 0)
|
|
* with arguments.
|
|
*
|
|
* @see SHELL_COND_CMD_ARG_REGISTER.
|
|
*
|
|
* @param[in] flag Compile time flag. Command is present only if flag
|
|
* exists and equals 1.
|
|
* @param[in] syntax Command syntax (for example: history).
|
|
* @param[in] subcmd Pointer to a subcommands array.
|
|
* @param[in] help Pointer to a command help string.
|
|
* @param[in] handler Pointer to a function handler.
|
|
*/
|
|
#define SHELL_COND_CMD_REGISTER(flag, syntax, subcmd, help, handler) \
|
|
SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, 0, 0)
|
|
|
|
/**
|
|
* @brief Macro for creating a subcommand set. It must be used outside of any
|
|
* function body.
|
|
*
|
|
* Example usage:
|
|
* SHELL_STATIC_SUBCMD_SET_CREATE(
|
|
* foo,
|
|
* SHELL_CMD(abc, ...),
|
|
* SHELL_CMD(def, ...),
|
|
* SHELL_SUBCMD_SET_END
|
|
* )
|
|
*
|
|
* @param[in] name Name of the subcommand set.
|
|
* @param[in] ... List of commands created with @ref SHELL_CMD_ARG or
|
|
* or @ref SHELL_CMD
|
|
*/
|
|
#define SHELL_STATIC_SUBCMD_SET_CREATE(name, ...) \
|
|
static const struct shell_static_entry shell_##name[] = { \
|
|
__VA_ARGS__ \
|
|
}; \
|
|
static const struct shell_cmd_entry name = { \
|
|
.is_dynamic = false, \
|
|
.u = { .entry = shell_##name } \
|
|
}
|
|
|
|
/**
|
|
* @brief Define ending subcommands set.
|
|
*
|
|
*/
|
|
#define SHELL_SUBCMD_SET_END {NULL}
|
|
|
|
/**
|
|
* @brief Macro for creating a dynamic entry.
|
|
*
|
|
* @param[in] name Name of the dynamic entry.
|
|
* @param[in] get Pointer to the function returning dynamic commands array
|
|
*/
|
|
#define SHELL_DYNAMIC_CMD_CREATE(name, get) \
|
|
static const struct shell_cmd_entry name = { \
|
|
.is_dynamic = true, \
|
|
.u = { .dynamic_get = get } \
|
|
}
|
|
|
|
/**
|
|
* @brief Initializes a shell command with arguments.
|
|
*
|
|
* @note If a command will be called with wrong number of arguments shell will
|
|
* print an error message and command handler will not be called.
|
|
*
|
|
* @param[in] syntax Command syntax (for example: history).
|
|
* @param[in] subcmd Pointer to a subcommands array.
|
|
* @param[in] help Pointer to a command help string.
|
|
* @param[in] handler Pointer to a function handler.
|
|
* @param[in] mand Number of mandatory arguments includig command name.
|
|
* @param[in] opt Number of optional arguments.
|
|
*/
|
|
#define SHELL_CMD_ARG(syntax, subcmd, help, handler, mand, opt) \
|
|
SHELL_EXPR_CMD_ARG(1, syntax, subcmd, help, handler, mand, opt)
|
|
|
|
/**
|
|
* @brief Initializes a conditional shell command with arguments.
|
|
*
|
|
* @see SHELL_CMD_ARG. Based on the flag, creates a valid entry or an empty
|
|
* command which is ignored by the shell. It is an alternative to \#ifdefs
|
|
* around command registration and command handler. However, empty structure is
|
|
* present in the flash even if command is disabled (subcommands and handler are
|
|
* removed). Macro internally handles case if flag is not defined so flag must
|
|
* be provided without any wrapper, e.g.: SHELL_COND_CMD_ARG(CONFIG_FOO, ...)
|
|
*
|
|
* @param[in] flag Compile time flag. Command is present only if flag
|
|
* exists and equals 1.
|
|
* @param[in] syntax Command syntax (for example: history).
|
|
* @param[in] subcmd Pointer to a subcommands array.
|
|
* @param[in] help Pointer to a command help string.
|
|
* @param[in] handler Pointer to a function handler.
|
|
* @param[in] mand Number of mandatory arguments includig command name.
|
|
* @param[in] opt Number of optional arguments.
|
|
*/
|
|
#define SHELL_COND_CMD_ARG(flag, syntax, subcmd, help, handler, mand, opt) \
|
|
SHELL_EXPR_CMD_ARG(IS_ENABLED(flag), syntax, subcmd, help, \
|
|
handler, mand, opt)
|
|
|
|
/**
|
|
* @brief Initializes a conditional shell command with arguments if expression
|
|
* gives non-zero result at compile time.
|
|
*
|
|
* @see SHELL_CMD_ARG. Based on the expression, creates a valid entry or an
|
|
* empty command which is ignored by the shell. It should be used instead of
|
|
* @ref SHELL_COND_CMD_ARG if condition is not a single configuration flag,
|
|
* e.g.:
|
|
* SHELL_EXPR_CMD_ARG(IS_ENABLED(CONFIG_FOO) &&
|
|
* IS_ENABLED(CONFIG_FOO_SETTING_1), ...)
|
|
*
|
|
* @param[in] _expr Expression.
|
|
* @param[in] _syntax Command syntax (for example: history).
|
|
* @param[in] _subcmd Pointer to a subcommands array.
|
|
* @param[in] _help Pointer to a command help string.
|
|
* @param[in] _handler Pointer to a function handler.
|
|
* @param[in] _mand Number of mandatory arguments includig command name.
|
|
* @param[in] _opt Number of optional arguments.
|
|
*/
|
|
#define SHELL_EXPR_CMD_ARG(_expr, _syntax, _subcmd, _help, _handler, \
|
|
_mand, _opt) \
|
|
{ \
|
|
.syntax = (_expr) ? (const char *)STRINGIFY(_syntax) : "", \
|
|
.help = (_expr) ? (const char *)_help : NULL, \
|
|
.subcmd = (const struct shell_cmd_entry *)((_expr) ? \
|
|
_subcmd : NULL), \
|
|
.handler = (shell_cmd_handler)((_expr) ? _handler : NULL), \
|
|
.args = { .mandatory = _mand, .optional = _opt} \
|
|
}
|
|
|
|
/**
|
|
* @brief Initializes a shell command.
|
|
*
|
|
* @param[in] _syntax Command syntax (for example: history).
|
|
* @param[in] _subcmd Pointer to a subcommands array.
|
|
* @param[in] _help Pointer to a command help string.
|
|
* @param[in] _handler Pointer to a function handler.
|
|
*/
|
|
#define SHELL_CMD(_syntax, _subcmd, _help, _handler) \
|
|
SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, 0, 0)
|
|
|
|
/**
|
|
* @brief Initializes a conditional shell command.
|
|
*
|
|
* @see SHELL_COND_CMD_ARG.
|
|
*
|
|
* @param[in] _flag Compile time flag. Command is present only if flag
|
|
* exists and equals 1.
|
|
* @param[in] _syntax Command syntax (for example: history).
|
|
* @param[in] _subcmd Pointer to a subcommands array.
|
|
* @param[in] _help Pointer to a command help string.
|
|
* @param[in] _handler Pointer to a function handler.
|
|
*/
|
|
#define SHELL_COND_CMD(_flag, _syntax, _subcmd, _help, _handler) \
|
|
SHELL_COND_CMD_ARG(_flag, _syntax, _subcmd, _help, _handler, 0, 0)
|
|
|
|
/**
|
|
* @brief Initializes shell command if expression gives non-zero result at
|
|
* compile time.
|
|
*
|
|
* @see SHELL_EXPR_CMD_ARG.
|
|
*
|
|
* @param[in] _expr Compile time expression. Command is present only if
|
|
* expression is non-zero.
|
|
* @param[in] _syntax Command syntax (for example: history).
|
|
* @param[in] _subcmd Pointer to a subcommands array.
|
|
* @param[in] _help Pointer to a command help string.
|
|
* @param[in] _handler Pointer to a function handler.
|
|
*/
|
|
#define SHELL_EXPR_CMD(_expr, _syntax, _subcmd, _help, _handler) \
|
|
SHELL_EXPR_CMD_ARG(_expr, _syntax, _subcmd, _help, _handler, 0, 0)
|
|
|
|
/* Internal macro used for creating handlers for dictionary commands. */
|
|
#define Z_SHELL_CMD_DICT_HANDLER_CREATE(_data, _handler) \
|
|
static int UTIL_CAT(cmd_dict_, GET_ARG_N(1, __DEBRACKET _data))( \
|
|
const struct shell *shell, size_t argc, char **argv) \
|
|
{ \
|
|
return _handler(shell, argc, argv, \
|
|
(void *)GET_ARG_N(2, __DEBRACKET _data)); \
|
|
}
|
|
|
|
/* Internal macro used for creating dictionary commands. */
|
|
#define SHELL_CMD_DICT_CREATE(_data) \
|
|
SHELL_CMD_ARG(GET_ARG_N(1, __DEBRACKET _data), NULL, NULL, \
|
|
UTIL_CAT(cmd_dict_, GET_ARG_N(1, __DEBRACKET _data)), 1, 0)
|
|
|
|
/**
|
|
* @brief Initializes shell dictionary commands.
|
|
*
|
|
* This is a special kind of static commands. Dictionary commands can be used
|
|
* every time you want to use a pair: (string <-> corresponding data) in
|
|
* a command handler. The string is usually a verbal description of a given
|
|
* data. The idea is to use the string as a command syntax that can be prompted
|
|
* by the shell and corresponding data can be used to process the command.
|
|
*
|
|
* @param[in] _name Name of the dictionary subcommand set
|
|
* @param[in] _handler Command handler common for all dictionary commands.
|
|
* @see shell_dict_cmd_handler
|
|
* @param[in] ... Dictionary pairs: (command_syntax, value). Value will be
|
|
* passed to the _handler as user data.
|
|
*
|
|
* Example usage:
|
|
* static int my_handler(const struct shell *shell,
|
|
* size_t argc, char **argv, void *data)
|
|
* {
|
|
* int val = (int)data;
|
|
*
|
|
* shell_print(shell, "(syntax, value) : (%s, %d)", argv[0], val);
|
|
* return 0;
|
|
* }
|
|
*
|
|
* SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, my_handler,
|
|
* (value_0, 0), (value_1, 1), (value_2, 2), (value_3, 3)
|
|
* );
|
|
* SHELL_CMD_REGISTER(dictionary, &sub_dict_cmds, NULL, NULL);
|
|
*/
|
|
#define SHELL_SUBCMD_DICT_SET_CREATE(_name, _handler, ...) \
|
|
FOR_EACH_FIXED_ARG(Z_SHELL_CMD_DICT_HANDLER_CREATE, (), \
|
|
_handler, __VA_ARGS__) \
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(_name, \
|
|
FOR_EACH(SHELL_CMD_DICT_CREATE, (,), __VA_ARGS__), \
|
|
SHELL_SUBCMD_SET_END \
|
|
)
|
|
|
|
/**
|
|
* @internal @brief Internal shell state in response to data received from the
|
|
* terminal.
|
|
*/
|
|
enum shell_receive_state {
|
|
SHELL_RECEIVE_DEFAULT,
|
|
SHELL_RECEIVE_ESC,
|
|
SHELL_RECEIVE_ESC_SEQ,
|
|
SHELL_RECEIVE_TILDE_EXP
|
|
};
|
|
|
|
/**
|
|
* @internal @brief Internal shell state.
|
|
*/
|
|
enum shell_state {
|
|
SHELL_STATE_UNINITIALIZED,
|
|
SHELL_STATE_INITIALIZED,
|
|
SHELL_STATE_ACTIVE,
|
|
SHELL_STATE_PANIC_MODE_ACTIVE, /*!< Panic activated.*/
|
|
SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/
|
|
};
|
|
|
|
/** @brief Shell transport event. */
|
|
enum shell_transport_evt {
|
|
SHELL_TRANSPORT_EVT_RX_RDY,
|
|
SHELL_TRANSPORT_EVT_TX_RDY
|
|
};
|
|
|
|
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);
|
|
|
|
/** @brief Bypass callback.
|
|
*
|
|
* @param shell Shell instance.
|
|
* @param data Raw data from transport.
|
|
* @param len Data length.
|
|
*/
|
|
typedef void (*shell_bypass_cb_t)(const struct shell *shell,
|
|
uint8_t *data,
|
|
size_t len);
|
|
|
|
struct shell_transport;
|
|
|
|
/**
|
|
* @brief Unified shell transport interface.
|
|
*/
|
|
struct shell_transport_api {
|
|
/**
|
|
* @brief Function for initializing the shell transport interface.
|
|
*
|
|
* @param[in] transport Pointer to the transfer instance.
|
|
* @param[in] config Pointer to instance configuration.
|
|
* @param[in] evt_handler Event handler.
|
|
* @param[in] context Pointer to the context passed to event
|
|
* handler.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int (*init)(const struct shell_transport *transport,
|
|
const void *config,
|
|
shell_transport_handler_t evt_handler,
|
|
void *context);
|
|
|
|
/**
|
|
* @brief Function for uninitializing the shell transport interface.
|
|
*
|
|
* @param[in] transport Pointer to the transfer instance.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int (*uninit)(const struct shell_transport *transport);
|
|
|
|
/**
|
|
* @brief Function for enabling transport in given TX mode.
|
|
*
|
|
* Function can be used to reconfigure TX to work in blocking mode.
|
|
*
|
|
* @param transport Pointer to the transfer instance.
|
|
* @param blocking_tx If true, the transport TX is enabled in blocking
|
|
* mode.
|
|
*
|
|
* @return NRF_SUCCESS on successful enabling, error otherwise (also if
|
|
* not supported).
|
|
*/
|
|
int (*enable)(const struct shell_transport *transport,
|
|
bool blocking_tx);
|
|
|
|
/**
|
|
* @brief Function for writing data to the transport interface.
|
|
*
|
|
* @param[in] transport Pointer to the transfer instance.
|
|
* @param[in] data Pointer to the source buffer.
|
|
* @param[in] length Source buffer length.
|
|
* @param[out] cnt Pointer to the sent bytes counter.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int (*write)(const struct shell_transport *transport,
|
|
const void *data, size_t length, size_t *cnt);
|
|
|
|
/**
|
|
* @brief Function for reading data from the transport interface.
|
|
*
|
|
* @param[in] p_transport Pointer to the transfer instance.
|
|
* @param[in] p_data Pointer to the destination buffer.
|
|
* @param[in] length Destination buffer length.
|
|
* @param[out] cnt Pointer to the received bytes counter.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int (*read)(const struct shell_transport *transport,
|
|
void *data, size_t length, size_t *cnt);
|
|
|
|
/**
|
|
* @brief Function called in shell thread loop.
|
|
*
|
|
* Can be used for backend operations that require longer execution time
|
|
*
|
|
* @param[in] transport Pointer to the transfer instance.
|
|
*/
|
|
void (*update)(const struct shell_transport *transport);
|
|
|
|
};
|
|
|
|
struct shell_transport {
|
|
const struct shell_transport_api *api;
|
|
void *ctx;
|
|
};
|
|
|
|
/**
|
|
* @brief Shell statistics structure.
|
|
*/
|
|
struct shell_stats {
|
|
atomic_t log_lost_cnt; /*!< Lost log counter.*/
|
|
};
|
|
|
|
#ifdef CONFIG_SHELL_STATS
|
|
#define Z_SHELL_STATS_DEFINE(_name) static struct shell_stats _name##_stats
|
|
#define Z_SHELL_STATS_PTR(_name) (&(_name##_stats))
|
|
#else
|
|
#define Z_SHELL_STATS_DEFINE(_name)
|
|
#define Z_SHELL_STATS_PTR(_name) NULL
|
|
#endif /* CONFIG_SHELL_STATS */
|
|
|
|
/**
|
|
* @internal @brief Flags for shell backend configuration.
|
|
*/
|
|
struct shell_backend_config_flags {
|
|
uint32_t insert_mode :1; /*!< Controls insert mode for text introduction */
|
|
uint32_t echo :1; /*!< Controls shell echo */
|
|
uint32_t obscure :1; /*!< If echo on, print asterisk instead */
|
|
uint32_t mode_delete :1; /*!< Operation mode of backspace key */
|
|
uint32_t use_colors :1; /*!< Controls colored syntax */
|
|
uint32_t use_vt100 :1; /*!< Controls VT100 commands usage in shell */
|
|
};
|
|
|
|
BUILD_ASSERT((sizeof(struct shell_backend_config_flags) == sizeof(uint32_t)),
|
|
"Structure must fit in 4 bytes");
|
|
|
|
/**
|
|
* @internal @brief Default backend configuration.
|
|
*/
|
|
#define SHELL_DEFAULT_BACKEND_CONFIG_FLAGS \
|
|
{ \
|
|
.insert_mode = 0, \
|
|
.echo = 1, \
|
|
.obscure = 0, \
|
|
.mode_delete = 1, \
|
|
.use_colors = 1, \
|
|
.use_vt100 = 1, \
|
|
};
|
|
|
|
struct shell_backend_ctx_flags {
|
|
uint32_t processing :1; /*!< Shell is executing process function */
|
|
uint32_t tx_rdy :1;
|
|
uint32_t history_exit :1; /*!< Request to exit history mode */
|
|
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 */
|
|
uint32_t sync_mode :1; /*!< Shell in synchronous mode */
|
|
};
|
|
|
|
BUILD_ASSERT((sizeof(struct shell_backend_ctx_flags) == sizeof(uint32_t)),
|
|
"Structure must fit in 4 bytes");
|
|
|
|
/**
|
|
* @internal @brief Union for internal shell usage.
|
|
*/
|
|
union shell_backend_cfg {
|
|
atomic_t value;
|
|
struct shell_backend_config_flags flags;
|
|
};
|
|
|
|
/**
|
|
* @internal @brief Union for internal shell usage.
|
|
*/
|
|
union shell_backend_ctx {
|
|
uint32_t value;
|
|
struct shell_backend_ctx_flags flags;
|
|
};
|
|
|
|
enum shell_signal {
|
|
SHELL_SIGNAL_RXRDY,
|
|
SHELL_SIGNAL_LOG_MSG,
|
|
SHELL_SIGNAL_KILL,
|
|
SHELL_SIGNAL_TXDONE, /* TXDONE must be last one before SHELL_SIGNALS */
|
|
SHELL_SIGNALS
|
|
};
|
|
|
|
/**
|
|
* @brief Shell instance context.
|
|
*/
|
|
struct shell_ctx {
|
|
const char *prompt; /*!< shell current prompt. */
|
|
|
|
enum shell_state state; /*!< Internal module state.*/
|
|
enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/
|
|
|
|
/*!< Currently executed command.*/
|
|
struct shell_static_entry active_cmd;
|
|
|
|
/* New root command. If NULL shell uses default root commands. */
|
|
const struct shell_static_entry *selected_cmd;
|
|
|
|
/*!< 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;
|
|
|
|
/*!< When bypass is set, all incoming data is passed to the callback. */
|
|
shell_bypass_cb_t bypass;
|
|
|
|
#if defined CONFIG_SHELL_GETOPT
|
|
/*!< getopt context for a shell backend. */
|
|
struct getopt_state getopt_state;
|
|
#endif
|
|
|
|
uint16_t cmd_buff_len; /*!< Command length.*/
|
|
uint16_t cmd_buff_pos; /*!< Command buffer cursor position.*/
|
|
|
|
uint16_t cmd_tmp_buff_len; /*!< Command length in tmp buffer.*/
|
|
|
|
/*!< Command input buffer.*/
|
|
char cmd_buff[CONFIG_SHELL_CMD_BUFF_SIZE];
|
|
|
|
/*!< Command temporary buffer.*/
|
|
char temp_buff[CONFIG_SHELL_CMD_BUFF_SIZE];
|
|
|
|
/*!< Printf buffer size.*/
|
|
char printf_buff[CONFIG_SHELL_PRINTF_BUFF_SIZE];
|
|
|
|
volatile union shell_backend_cfg cfg;
|
|
volatile union shell_backend_ctx ctx;
|
|
|
|
struct k_poll_signal signals[SHELL_SIGNALS];
|
|
|
|
/*!< Events that should be used only internally by shell thread.
|
|
* Event for SHELL_SIGNAL_TXDONE is initialized but unused.
|
|
*/
|
|
struct k_poll_event events[SHELL_SIGNALS];
|
|
|
|
struct k_mutex wr_mtx;
|
|
k_tid_t tid;
|
|
};
|
|
|
|
extern const struct log_backend_api log_backend_shell_api;
|
|
|
|
/**
|
|
* @brief Flags for setting shell output newline sequence.
|
|
*/
|
|
enum shell_flag {
|
|
SHELL_FLAG_CRLF_DEFAULT = (1<<0), /* Do not map CR or LF */
|
|
SHELL_FLAG_OLF_CRLF = (1<<1) /* Map LF to CRLF on output */
|
|
};
|
|
|
|
/**
|
|
* @brief Shell instance internals.
|
|
*/
|
|
struct shell {
|
|
const char *default_prompt; /*!< shell default prompt. */
|
|
|
|
const struct shell_transport *iface; /*!< Transport interface.*/
|
|
struct shell_ctx *ctx; /*!< Internal context.*/
|
|
|
|
struct shell_history *history;
|
|
|
|
const enum shell_flag shell_flag;
|
|
|
|
const struct shell_fprintf *fprintf_ctx;
|
|
|
|
struct shell_stats *stats;
|
|
|
|
const struct shell_log_backend *log_backend;
|
|
|
|
LOG_INSTANCE_PTR_DECLARE(log);
|
|
|
|
const char *thread_name;
|
|
struct k_thread *thread;
|
|
k_thread_stack_t *stack;
|
|
};
|
|
|
|
extern void z_shell_print_stream(const void *user_ctx, const char *data,
|
|
size_t data_len);
|
|
/**
|
|
* @brief Macro for defining a shell instance.
|
|
*
|
|
* @param[in] _name Instance name.
|
|
* @param[in] _prompt Shell default prompt string.
|
|
* @param[in] _transport_iface Pointer to the transport interface.
|
|
* @param[in] _log_queue_size Logger processing queue size.
|
|
* @param[in] _log_timeout Logger thread timeout in milliseconds on full
|
|
* log queue. If queue is full logger thread is
|
|
* blocked for given amount of time before log
|
|
* message is dropped.
|
|
* @param[in] _shell_flag Shell output newline sequence.
|
|
*/
|
|
#define SHELL_DEFINE(_name, _prompt, _transport_iface, \
|
|
_log_queue_size, _log_timeout, _shell_flag) \
|
|
static const struct shell _name; \
|
|
static struct shell_ctx UTIL_CAT(_name, _ctx); \
|
|
static uint8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE]; \
|
|
Z_SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer, \
|
|
CONFIG_SHELL_PRINTF_BUFF_SIZE, \
|
|
_log_queue_size, _log_timeout); \
|
|
Z_SHELL_HISTORY_DEFINE(_name##_history, CONFIG_SHELL_HISTORY_BUFFER); \
|
|
Z_SHELL_FPRINTF_DEFINE(_name##_fprintf, &_name, _name##_out_buffer, \
|
|
CONFIG_SHELL_PRINTF_BUFF_SIZE, \
|
|
true, z_shell_print_stream); \
|
|
LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \
|
|
Z_SHELL_STATS_DEFINE(_name); \
|
|
static K_KERNEL_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \
|
|
static struct k_thread _name##_thread; \
|
|
static const STRUCT_SECTION_ITERABLE(shell, _name) = { \
|
|
.default_prompt = _prompt, \
|
|
.iface = _transport_iface, \
|
|
.ctx = &UTIL_CAT(_name, _ctx), \
|
|
.history = IS_ENABLED(CONFIG_SHELL_HISTORY) ? \
|
|
&_name##_history : NULL, \
|
|
.shell_flag = _shell_flag, \
|
|
.fprintf_ctx = &_name##_fprintf, \
|
|
.stats = Z_SHELL_STATS_PTR(_name), \
|
|
.log_backend = Z_SHELL_LOG_BACKEND_PTR(_name), \
|
|
LOG_INSTANCE_PTR_INIT(log, shell, _name) \
|
|
.thread_name = STRINGIFY(_name), \
|
|
.thread = &_name##_thread, \
|
|
.stack = _name##_stack \
|
|
}
|
|
|
|
/**
|
|
* @brief Function for initializing a transport layer and internal shell state.
|
|
*
|
|
* @param[in] shell Pointer to shell instance.
|
|
* @param[in] transport_config Transport configuration during initialization.
|
|
* @param[in] cfg_flags Initial backend configuration flags.
|
|
* Shell will copy this data.
|
|
* @param[in] log_backend If true, the console will be used as logger
|
|
* backend.
|
|
* @param[in] init_log_level Default severity level for the logger.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int shell_init(const struct shell *shell, const void *transport_config,
|
|
struct shell_backend_config_flags cfg_flags,
|
|
bool log_backend, uint32_t init_log_level);
|
|
|
|
/**
|
|
* @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.
|
|
*/
|
|
void shell_uninit(const struct shell *shell, shell_uninit_cb_t cb);
|
|
|
|
/**
|
|
* @brief Function for starting shell processing.
|
|
*
|
|
* @param shell Pointer to the shell instance.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int shell_start(const struct shell *shell);
|
|
|
|
/**
|
|
* @brief Function for stopping shell processing.
|
|
*
|
|
* @param shell Pointer to shell instance.
|
|
*
|
|
* @return Standard error code.
|
|
*/
|
|
int shell_stop(const struct shell *shell);
|
|
|
|
/**
|
|
* @brief Terminal default text color for shell_fprintf function.
|
|
*/
|
|
#define SHELL_NORMAL SHELL_VT100_COLOR_DEFAULT
|
|
|
|
/**
|
|
* @brief Green text color for shell_fprintf function.
|
|
*/
|
|
#define SHELL_INFO SHELL_VT100_COLOR_GREEN
|
|
|
|
/**
|
|
* @brief Cyan text color for shell_fprintf function.
|
|
*/
|
|
#define SHELL_OPTION SHELL_VT100_COLOR_CYAN
|
|
|
|
/**
|
|
* @brief Yellow text color for shell_fprintf function.
|
|
*/
|
|
#define SHELL_WARNING SHELL_VT100_COLOR_YELLOW
|
|
|
|
/**
|
|
* @brief Red text color for shell_fprintf function.
|
|
*/
|
|
#define SHELL_ERROR SHELL_VT100_COLOR_RED
|
|
|
|
/**
|
|
* @brief printf-like function which sends formatted data stream to the shell.
|
|
*
|
|
* This function can be used from the command handler or from threads, but not
|
|
* from an interrupt context.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] color Printed text color.
|
|
* @param[in] fmt Format string.
|
|
* @param[in] ... List of parameters to print.
|
|
*/
|
|
void __printf_like(3, 4) shell_fprintf(const struct shell *shell,
|
|
enum shell_vt100_color color,
|
|
const char *fmt, ...);
|
|
|
|
/**
|
|
* @brief vprintf-like function which sends formatted data stream to the shell.
|
|
*
|
|
* This function can be used from the command handler or from threads, but not
|
|
* from an interrupt context. It is similar to shell_fprintf() but takes a
|
|
* va_list instead of variable arguments.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] color Printed text color.
|
|
* @param[in] fmt Format string.
|
|
* @param[in] args List of parameters to print.
|
|
*/
|
|
void shell_vfprintf(const struct shell *shell, enum shell_vt100_color color,
|
|
const char *fmt, va_list args);
|
|
|
|
/**
|
|
* @brief Print a line of data in hexadecimal format.
|
|
*
|
|
* Each line shows the offset, bytes and then ASCII representation.
|
|
*
|
|
* For example:
|
|
*
|
|
* 00008010: 20 25 00 20 2f 48 00 08 80 05 00 20 af 46 00
|
|
* | %. /H.. ... .F. |
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] offset Offset to show for this line.
|
|
* @param[in] data Pointer to data.
|
|
* @param[in] len Length of data.
|
|
*/
|
|
void shell_hexdump_line(const struct shell *shell, unsigned int offset,
|
|
const uint8_t *data, size_t len);
|
|
|
|
/**
|
|
* @brief Print data in hexadecimal format.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] data Pointer to data.
|
|
* @param[in] len Length of data.
|
|
*/
|
|
void shell_hexdump(const struct shell *shell, const uint8_t *data, size_t len);
|
|
|
|
/**
|
|
* @brief Print info message to the shell.
|
|
*
|
|
* See @ref shell_fprintf.
|
|
*
|
|
* @param[in] _sh Pointer to the shell instance.
|
|
* @param[in] _ft Format string.
|
|
* @param[in] ... List of parameters to print.
|
|
*/
|
|
#define shell_info(_sh, _ft, ...) \
|
|
shell_fprintf(_sh, SHELL_INFO, _ft "\n", ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Print normal message to the shell.
|
|
*
|
|
* See @ref shell_fprintf.
|
|
*
|
|
* @param[in] _sh Pointer to the shell instance.
|
|
* @param[in] _ft Format string.
|
|
* @param[in] ... List of parameters to print.
|
|
*/
|
|
#define shell_print(_sh, _ft, ...) \
|
|
shell_fprintf(_sh, SHELL_NORMAL, _ft "\n", ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Print warning message to the shell.
|
|
*
|
|
* See @ref shell_fprintf.
|
|
*
|
|
* @param[in] _sh Pointer to the shell instance.
|
|
* @param[in] _ft Format string.
|
|
* @param[in] ... List of parameters to print.
|
|
*/
|
|
#define shell_warn(_sh, _ft, ...) \
|
|
shell_fprintf(_sh, SHELL_WARNING, _ft "\n", ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Print error message to the shell.
|
|
*
|
|
* See @ref shell_fprintf.
|
|
*
|
|
* @param[in] _sh Pointer to the shell instance.
|
|
* @param[in] _ft Format string.
|
|
* @param[in] ... List of parameters to print.
|
|
*/
|
|
#define shell_error(_sh, _ft, ...) \
|
|
shell_fprintf(_sh, SHELL_ERROR, _ft "\n", ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Process function, which should be executed when data is ready in the
|
|
* transport interface. To be used if shell thread is disabled.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
*/
|
|
void shell_process(const struct shell *shell);
|
|
|
|
/**
|
|
* @brief Change displayed shell prompt.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] prompt New shell prompt.
|
|
*
|
|
* @return 0 Success.
|
|
* @return -EINVAL Pointer to new prompt is not correct.
|
|
*/
|
|
int shell_prompt_change(const struct shell *shell, const char *prompt);
|
|
|
|
/**
|
|
* @brief Prints the current command help.
|
|
*
|
|
* Function will print a help string with: the currently entered command
|
|
* and subcommands (if they exist).
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
*/
|
|
void shell_help(const struct shell *shell);
|
|
|
|
/* @brief Command's help has been printed */
|
|
#define SHELL_CMD_HELP_PRINTED (1)
|
|
|
|
#if defined CONFIG_SHELL_GETOPT
|
|
/**
|
|
* @brief Parses the command-line arguments.
|
|
*
|
|
* It is based on FreeBSD implementation.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] argc Arguments count.
|
|
* @param[in] argv Arguments.
|
|
* @param[in] ostr String containing the legitimate option characters.
|
|
*
|
|
* @return If an option was successfully found, function returns
|
|
* the option character.
|
|
* @return If options have been detected that is not in @p ostr
|
|
* function will return '?'.
|
|
* If function encounters an option with a missing
|
|
* argument, then the return value depends on the first
|
|
* character in optstring: if it is ':', then ':' is
|
|
* returned; otherwise '?' is returned.
|
|
* @return -1 If all options have been parsed.
|
|
*/
|
|
int shell_getopt(const struct shell *shell, int argc, char *const argv[],
|
|
const char *ostr);
|
|
|
|
/**
|
|
* @brief Returns shell_getopt state.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
*
|
|
* @return Pointer to struct getopt_state.
|
|
*/
|
|
struct getopt_state *shell_getopt_state_get(const struct shell *shell);
|
|
#endif /* CONFIG_SHELL_GETOPT */
|
|
|
|
/** @brief Execute command.
|
|
*
|
|
* Pass command line to shell to execute.
|
|
*
|
|
* Note: This by no means makes any of the commands a stable interface, so
|
|
* this function should only be used for debugging/diagnostic.
|
|
*
|
|
* This function must not be called from shell command context!
|
|
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* It can be NULL when the
|
|
* @kconfig{CONFIG_SHELL_BACKEND_DUMMY} option is enabled.
|
|
* @param[in] cmd Command to be executed.
|
|
*
|
|
* @return Result of the execution
|
|
*/
|
|
int shell_execute_cmd(const struct shell *shell, const char *cmd);
|
|
|
|
/** @brief Set root command for all shell instances.
|
|
*
|
|
* It allows setting from the code the root command. It is an equivalent of
|
|
* calling select command with one of the root commands as the argument
|
|
* (e.g "select log") except it sets command for all shell instances.
|
|
*
|
|
* @param cmd String with one of the root commands or null pointer to reset.
|
|
*
|
|
* @retval 0 if root command is set.
|
|
* @retval -EINVAL if invalid root command is provided.
|
|
*/
|
|
int shell_set_root_cmd(const char *cmd);
|
|
|
|
/** @brief Set bypass callback.
|
|
*
|
|
* Bypass callback is called whenever data is received. Shell is bypassed and
|
|
* data is passed directly to the callback. Use null to disable bypass functionality.
|
|
*
|
|
* @param[in] shell Pointer to the shell instance.
|
|
* @param[in] bypass Bypass callback or null to disable.
|
|
*/
|
|
void shell_set_bypass(const struct shell *shell, shell_bypass_cb_t bypass);
|
|
|
|
/**
|
|
* @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] val Insert mode.
|
|
*
|
|
* @retval 0 or 1: previous value
|
|
* @retval -EINVAL if shell is NULL.
|
|
*/
|
|
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 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);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* SHELL_H__ */
|