2018-08-09 09:56:10 +02:00
|
|
|
/*
|
|
|
|
* 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>
|
2018-08-09 10:38:15 +02:00
|
|
|
#include <shell/shell_history.h>
|
2018-08-09 09:56:10 +02:00
|
|
|
#include <shell/shell_fprintf.h>
|
2018-08-09 11:40:02 +02:00
|
|
|
#include <shell/shell_log_backend.h>
|
2018-08-09 09:56:10 +02:00
|
|
|
#include <logging/log_instance.h>
|
|
|
|
#include <logging/log.h>
|
|
|
|
#include <misc/util.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define SHELL_RX_BUFF_SIZE 16
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
#define SHELL_CMD_ROOT_LVL (0u)
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
|
|
|
* @brief Shell API
|
|
|
|
* @defgroup shell_api Shell API
|
|
|
|
* @ingroup shell
|
2018-08-09 09:56:10 +02:00
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct shell_static_entry;
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Shell command descriptor.
|
|
|
|
*/
|
|
|
|
struct shell_cmd_entry {
|
|
|
|
bool is_dynamic;
|
2018-09-24 15:18:52 +02:00
|
|
|
union union_cmd_entry {
|
2018-08-09 09:56:10 +02:00
|
|
|
/*!< 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;
|
|
|
|
|
2018-11-06 15:34:11 +02:00
|
|
|
/**
|
|
|
|
* @brief Initializes a shell command arguments
|
|
|
|
*
|
|
|
|
* @param[in] _mandatory Number of mandatory arguments.
|
|
|
|
* @param[in] _optional Number of optional arguments.
|
|
|
|
*/
|
|
|
|
#define SHELL_ARG(_mandatory, _optional) { \
|
|
|
|
.mandatory = _mandatory, \
|
|
|
|
.optional = _optional, \
|
|
|
|
}
|
|
|
|
|
|
|
|
struct shell_static_args {
|
|
|
|
u8_t mandatory; /*!< Number of mandatory arguments. */
|
|
|
|
u8_t optional; /*!< Number of optional arguments. */
|
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Shell command handler prototype.
|
|
|
|
*/
|
2018-10-01 22:08:59 +02:00
|
|
|
typedef int (*shell_cmd_handler)(const struct shell *shell,
|
|
|
|
size_t argc, char **argv);
|
2018-08-09 09:56:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @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. */
|
2018-11-06 15:34:11 +02:00
|
|
|
const struct shell_static_args *args; /*!< Command arguments. */
|
2018-08-09 09:56:10 +02:00
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-11-06 15:34:11 +02:00
|
|
|
* @brief Macro for defining and adding a root command (level 0) with
|
|
|
|
* arguments.
|
|
|
|
*
|
|
|
|
* @note Each root command shall have unique syntax.
|
|
|
|
*
|
|
|
|
* @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.
|
|
|
|
* @param[in] optional Number of optional arguments.
|
|
|
|
*/
|
|
|
|
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
|
|
|
|
mandatory, optional) \
|
2018-11-26 17:09:56 +01:00
|
|
|
static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
|
2018-11-06 15:34:11 +02:00
|
|
|
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, \
|
2018-11-26 17:09:56 +01:00
|
|
|
.u.entry = &UTIL_CAT(_shell_, syntax) \
|
2018-11-06 15:34:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Macro for defining and adding a root command (level 0) with
|
|
|
|
* arguments.
|
2018-08-09 09:56:10 +02:00
|
|
|
*
|
|
|
|
* @note Each root command shall have unique syntax.
|
|
|
|
*
|
|
|
|
* @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.
|
|
|
|
*/
|
2018-11-06 15:34:11 +02:00
|
|
|
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
|
2018-11-26 17:09:56 +01:00
|
|
|
static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
|
2018-08-09 09:56:10 +02:00
|
|
|
SHELL_CMD(syntax, subcmd, help, handler); \
|
|
|
|
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, \
|
2018-11-26 17:09:56 +01:00
|
|
|
.u.entry = &UTIL_CAT(_shell_, syntax) \
|
2018-08-09 09:56:10 +02:00
|
|
|
}
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Macro for creating a subcommand set. It must be used outside of any
|
|
|
|
* function body.
|
|
|
|
*
|
|
|
|
* @param[in] name Name of the subcommand set.
|
|
|
|
*/
|
|
|
|
#define SHELL_CREATE_STATIC_SUBCMD_SET(name) \
|
|
|
|
static const struct shell_static_entry shell_##name[]; \
|
|
|
|
static const struct shell_cmd_entry name = { \
|
|
|
|
.is_dynamic = false, \
|
|
|
|
.u.entry = shell_##name \
|
|
|
|
}; \
|
|
|
|
static const struct shell_static_entry shell_##name[] =
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Define ending subcommands set.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#define SHELL_SUBCMD_SET_END {NULL}
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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_CREATE_DYNAMIC_CMD(name, get) \
|
|
|
|
static const struct shell_cmd_entry name = { \
|
|
|
|
.is_dynamic = true, \
|
|
|
|
.u.dynamic_get = get \
|
|
|
|
}
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-11-06 15:34:11 +02:00
|
|
|
* @brief Initializes a shell command with arguments
|
2018-08-09 09:56:10 +02:00
|
|
|
*
|
|
|
|
* @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.
|
2018-11-06 15:34:11 +02:00
|
|
|
* @param[in] _mandatory Number of mandatory arguments.
|
|
|
|
* @param[in] _optional Number of optional arguments.
|
2018-08-09 09:56:10 +02:00
|
|
|
*/
|
2018-11-06 15:34:11 +02:00
|
|
|
#define SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, \
|
|
|
|
_mandatory, _optional) { \
|
|
|
|
.syntax = (const char *)STRINGIFY(_syntax), \
|
|
|
|
.subcmd = _subcmd, \
|
|
|
|
.help = (const char *)_help, \
|
|
|
|
.handler = _handler, \
|
|
|
|
.args = _mandatory ? \
|
|
|
|
(&(struct shell_static_args) SHELL_ARG(_mandatory, _optional)) : NULL\
|
2018-08-09 09:56:10 +02:00
|
|
|
}
|
|
|
|
|
2018-11-06 15:34:11 +02:00
|
|
|
/**
|
|
|
|
* @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)
|
|
|
|
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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
|
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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.*/
|
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/** @brief Shell transport event. */
|
2018-08-09 09:56:10 +02:00
|
|
|
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);
|
|
|
|
|
|
|
|
struct shell_transport;
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Unified shell transport interface.
|
|
|
|
*/
|
|
|
|
struct shell_transport_api {
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Function for reconfiguring the transport to work in blocking
|
|
|
|
* mode.
|
|
|
|
*
|
|
|
|
* @param transport Pointer to the transfer instance.
|
|
|
|
* @param blocking If true, the transport 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);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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[in] 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);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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[in] 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);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct shell_transport {
|
|
|
|
const struct shell_transport_api *api;
|
|
|
|
void *ctx;
|
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
|
|
|
* @brief Shell statistics structure.
|
|
|
|
*/
|
2018-08-09 11:40:02 +02:00
|
|
|
struct shell_stats {
|
|
|
|
u32_t log_lost_cnt; /*!< Lost log counter.*/
|
|
|
|
};
|
|
|
|
|
|
|
|
#if CONFIG_SHELL_STATS
|
|
|
|
#define SHELL_STATS_DEFINE(_name) static struct shell_stats _name##_stats
|
|
|
|
#define SHELL_STATS_PTR(_name) (&(_name##_stats))
|
|
|
|
#else
|
|
|
|
#define SHELL_STATS_DEFINE(_name)
|
|
|
|
#define SHELL_STATS_PTR(_name) NULL
|
|
|
|
#endif /* CONFIG_SHELL_STATS */
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @internal @brief Flags for internal shell usage.
|
|
|
|
*/
|
|
|
|
struct shell_flags {
|
|
|
|
u32_t insert_mode :1; /*!< Controls insert mode for text introduction.*/
|
|
|
|
u32_t use_colors :1; /*!< Controls colored syntax.*/
|
|
|
|
u32_t echo :1; /*!< Controls shell echo.*/
|
|
|
|
u32_t processing :1; /*!< Shell is executing process function.*/
|
|
|
|
u32_t tx_rdy :1;
|
|
|
|
u32_t mode_delete :1; /*!< Operation mode of backspace key */
|
2018-10-23 19:17:28 +02:00
|
|
|
u32_t history_exit:1; /*!< Request to exit history mode */
|
2018-11-29 09:08:20 +01:00
|
|
|
u32_t last_nl :8; /*!< Last received new line character */
|
2018-08-09 09:56:10 +02:00
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
BUILD_ASSERT_MSG((sizeof(struct shell_flags) == sizeof(u32_t)),
|
|
|
|
"Structure must fit in 4 bytes");
|
2018-08-09 09:56:10 +02:00
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
|
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @internal @brief Union for internal shell usage.
|
|
|
|
*/
|
|
|
|
union shell_internal {
|
|
|
|
u32_t value;
|
|
|
|
struct shell_flags flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum shell_signal {
|
|
|
|
SHELL_SIGNAL_RXRDY,
|
|
|
|
SHELL_SIGNAL_TXDONE,
|
2018-08-09 11:40:02 +02:00
|
|
|
SHELL_SIGNAL_LOG_MSG,
|
2018-08-09 09:56:10 +02:00
|
|
|
SHELL_SIGNAL_KILL,
|
|
|
|
SHELL_SIGNALS
|
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Shell instance context.
|
|
|
|
*/
|
|
|
|
struct shell_ctx {
|
|
|
|
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;
|
|
|
|
|
|
|
|
/*!< VT100 color and cursor position, terminal width.*/
|
|
|
|
struct shell_vt100_ctx vt100_ctx;
|
|
|
|
|
|
|
|
u16_t cmd_buff_len;/*!< Command length.*/
|
|
|
|
u16_t cmd_buff_pos; /*!< Command buffer cursor position.*/
|
|
|
|
|
|
|
|
u16_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_internal internal; /*!< Internal shell data.*/
|
|
|
|
|
|
|
|
struct k_poll_signal signals[SHELL_SIGNALS];
|
|
|
|
struct k_poll_event events[SHELL_SIGNALS];
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct log_backend_api log_backend_shell_api;
|
|
|
|
|
2018-10-05 10:49:08 +02:00
|
|
|
/**
|
|
|
|
* @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 */
|
|
|
|
};
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Shell instance internals.
|
|
|
|
*/
|
|
|
|
struct shell {
|
2018-09-21 16:41:22 +02:00
|
|
|
char *const prompt; /*!< shell prompt. */
|
2018-08-09 09:56:10 +02:00
|
|
|
|
|
|
|
const struct shell_transport *iface; /*!< Transport interface.*/
|
|
|
|
struct shell_ctx *ctx; /*!< Internal context.*/
|
|
|
|
|
2018-08-09 10:38:15 +02:00
|
|
|
struct shell_history *history;
|
|
|
|
|
2018-10-05 10:49:08 +02:00
|
|
|
const enum shell_flag shell_flag;
|
|
|
|
|
2018-08-09 09:56:10 +02:00
|
|
|
const struct shell_fprintf *fprintf_ctx;
|
|
|
|
|
2018-08-09 11:40:02 +02:00
|
|
|
struct shell_stats *stats;
|
|
|
|
|
|
|
|
const struct shell_log_backend *log_backend;
|
|
|
|
|
2018-08-09 09:56:10 +02:00
|
|
|
LOG_INSTANCE_PTR_DECLARE(log);
|
|
|
|
|
2018-11-19 13:24:25 +01:00
|
|
|
const char *thread_name;
|
2018-08-09 09:56:10 +02:00
|
|
|
struct k_thread *thread;
|
|
|
|
k_thread_stack_t *stack;
|
|
|
|
};
|
|
|
|
|
2018-11-26 17:09:56 +01:00
|
|
|
extern void shell_print_stream(const void *user_ctx, const char *data,
|
|
|
|
size_t data_len);
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Macro for defining a shell instance.
|
|
|
|
*
|
|
|
|
* @param[in] _name Instance name.
|
2018-09-21 16:41:22 +02:00
|
|
|
* @param[in] _prompt Shell prompt string.
|
2018-08-09 09:56:10 +02:00
|
|
|
* @param[in] transport_iface Pointer to the transport interface.
|
|
|
|
* @param[in] log_queue_size Logger processing queue size.
|
2018-10-05 10:49:08 +02:00
|
|
|
* @param[in] _shell_flag Shell output newline sequence.
|
2018-08-09 09:56:10 +02:00
|
|
|
*/
|
2018-09-21 16:41:22 +02:00
|
|
|
#define SHELL_DEFINE(_name, _prompt, transport_iface, \
|
2018-10-05 10:49:08 +02:00
|
|
|
log_queue_size, _shell_flag) \
|
2018-08-09 10:38:15 +02:00
|
|
|
static const struct shell _name; \
|
|
|
|
static struct shell_ctx UTIL_CAT(_name, _ctx); \
|
2018-09-21 16:41:22 +02:00
|
|
|
static char _name##prompt[CONFIG_SHELL_PROMPT_LENGTH + 1] = _prompt; \
|
2018-08-09 10:38:15 +02:00
|
|
|
static u8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE]; \
|
2018-08-09 11:40:02 +02:00
|
|
|
SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer, \
|
|
|
|
CONFIG_SHELL_PRINTF_BUFF_SIZE); \
|
2018-08-09 10:38:15 +02:00
|
|
|
SHELL_HISTORY_DEFINE(_name, 128, 8);/*todo*/ \
|
2018-10-05 10:49:08 +02:00
|
|
|
SHELL_FPRINTF_DEFINE(_name##_fprintf, &_name, _name##_out_buffer, \
|
2018-08-09 10:38:15 +02:00
|
|
|
CONFIG_SHELL_PRINTF_BUFF_SIZE, \
|
|
|
|
true, shell_print_stream); \
|
2018-09-24 15:18:52 +02:00
|
|
|
LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \
|
2018-08-09 11:40:02 +02:00
|
|
|
SHELL_STATS_DEFINE(_name); \
|
2018-08-09 10:38:15 +02:00
|
|
|
static K_THREAD_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE);\
|
|
|
|
static struct k_thread _name##_thread; \
|
|
|
|
static const struct shell _name = { \
|
2018-09-21 16:41:22 +02:00
|
|
|
.prompt = _name##prompt, \
|
2018-08-09 10:38:15 +02:00
|
|
|
.iface = transport_iface, \
|
|
|
|
.ctx = &UTIL_CAT(_name, _ctx), \
|
|
|
|
.history = SHELL_HISTORY_PTR(_name), \
|
2018-10-05 10:49:08 +02:00
|
|
|
.shell_flag = _shell_flag, \
|
2018-08-09 10:38:15 +02:00
|
|
|
.fprintf_ctx = &_name##_fprintf, \
|
2018-08-09 11:40:02 +02:00
|
|
|
.stats = SHELL_STATS_PTR(_name), \
|
|
|
|
.log_backend = SHELL_LOG_BACKEND_PTR(_name), \
|
2018-08-09 10:38:15 +02:00
|
|
|
LOG_INSTANCE_PTR_INIT(log, shell, _name) \
|
2018-11-19 13:24:25 +01:00
|
|
|
.thread_name = STRINGIFY(_name), \
|
2018-08-09 10:38:15 +02:00
|
|
|
.thread = &_name##_thread, \
|
|
|
|
.stack = _name##_stack \
|
2018-08-09 09:56:10 +02:00
|
|
|
}
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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] use_colors Enables colored prints.
|
|
|
|
* @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,
|
|
|
|
bool use_colors, bool log_backend, u32_t init_log_level);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Uninitializes the transport layer and the internal shell state.
|
|
|
|
*
|
|
|
|
* @param shell Pointer to shell instance.
|
|
|
|
*
|
|
|
|
* @return Standard error code.
|
|
|
|
*/
|
|
|
|
int shell_uninit(const struct shell *shell);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Function for starting shell processing.
|
|
|
|
*
|
|
|
|
* @param shell Pointer to the shell instance.
|
|
|
|
*
|
|
|
|
* @return Standard error code.
|
|
|
|
*/
|
|
|
|
int shell_start(const struct shell *shell);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Function for stopping shell processing.
|
|
|
|
*
|
|
|
|
* @param shell Pointer to shell instance.
|
|
|
|
*
|
|
|
|
* @return Standard error code.
|
|
|
|
*/
|
|
|
|
int shell_stop(const struct shell *shell);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
|
|
|
* @brief Terminal default text color for nrf_shell_fprintf function.
|
2018-08-09 09:56:10 +02:00
|
|
|
*/
|
|
|
|
#define SHELL_NORMAL SHELL_VT100_COLOR_DEFAULT
|
2018-09-24 15:18:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Green text color for nrf_shell_fprintf function.
|
|
|
|
*/
|
2018-08-09 09:56:10 +02:00
|
|
|
#define SHELL_INFO SHELL_VT100_COLOR_GREEN
|
2018-09-24 15:18:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Cyan text color for nrf_shell_fprintf function.
|
|
|
|
*/
|
2018-08-09 09:56:10 +02:00
|
|
|
#define SHELL_OPTION SHELL_VT100_COLOR_CYAN
|
2018-09-24 15:18:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Yellow text color for nrf_shell_fprintf function.
|
|
|
|
*/
|
2018-08-09 09:56:10 +02:00
|
|
|
#define SHELL_WARNING SHELL_VT100_COLOR_YELLOW
|
2018-09-24 15:18:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Red text color for nrf_shell_fprintf function.
|
|
|
|
*/
|
2018-08-09 09:56:10 +02:00
|
|
|
#define SHELL_ERROR SHELL_VT100_COLOR_RED
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @brief Printf-like function which sends formatted data stream to the shell.
|
|
|
|
* This function shall not be used outside of the shell command context.
|
|
|
|
*
|
|
|
|
* @param[in] shell Pointer to the shell instance.
|
|
|
|
* @param[in] color Printf color.
|
|
|
|
* @param[in] p_fmt Format string.
|
|
|
|
* @param[in] ... List of parameters to print.
|
|
|
|
*/
|
|
|
|
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
|
|
|
const char *p_fmt, ...);
|
|
|
|
|
2018-11-08 12:34:52 +02:00
|
|
|
/**
|
|
|
|
* @brief Print info message to the shell.
|
|
|
|
*
|
|
|
|
* This function shall not be used outside of the shell command context.
|
|
|
|
*
|
|
|
|
* @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, ...) \
|
2018-11-26 15:38:23 +01:00
|
|
|
shell_fprintf(_sh, SHELL_INFO, _ft "\n", ##__VA_ARGS__)
|
2018-11-08 12:34:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Print normal message to the shell.
|
|
|
|
*
|
|
|
|
* This function shall not be used outside of the shell command context.
|
|
|
|
*
|
|
|
|
* @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.
|
|
|
|
*
|
|
|
|
* This function shall not be used outside of the shell command context.
|
|
|
|
*
|
|
|
|
* @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, ...) \
|
2018-11-26 15:38:23 +01:00
|
|
|
shell_fprintf(_sh, SHELL_WARNING, _ft "\n", ##__VA_ARGS__)
|
2018-11-08 12:34:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Print error message to the shell.
|
|
|
|
*
|
|
|
|
* This function shall not be used outside of the shell command context.
|
|
|
|
* @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__)
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-08-09 09:56:10 +02:00
|
|
|
* @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);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-09-21 16:41:22 +02:00
|
|
|
* @brief Change displayed shell prompt.
|
|
|
|
*
|
|
|
|
* @param[in] shell Pointer to the shell instance.
|
|
|
|
* @param[in] prompt New shell prompt.
|
|
|
|
*
|
|
|
|
* @return 0 success
|
|
|
|
* @return -1 new string is too long
|
|
|
|
*/
|
|
|
|
int shell_prompt_change(const struct shell *shell, char *prompt);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
2018-11-26 17:09:56 +01:00
|
|
|
* @brief Prints the current command help.
|
2018-08-09 09:56:10 +02:00
|
|
|
*
|
2018-11-26 17:09:56 +01:00
|
|
|
* Function will print a help string with: the currently entered command
|
|
|
|
* and subcommands (if they exist).
|
2018-08-09 09:56:10 +02:00
|
|
|
*
|
2018-11-26 17:09:56 +01:00
|
|
|
* @param[in] shell Pointer to the shell instance.
|
2018-08-09 09:56:10 +02:00
|
|
|
*/
|
2018-11-26 17:09:56 +01:00
|
|
|
void shell_help_print(const struct shell *shell);
|
2018-08-09 09:56:10 +02:00
|
|
|
|
2018-10-02 09:37:19 +02:00
|
|
|
/** @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.
|
|
|
|
*
|
2018-10-02 14:47:20 +02:00
|
|
|
* @param[in] shell Pointer to the shell instance. It can be NULL when
|
|
|
|
* the :option:`CONFIG_SHELL_BACKEND_DUMMY` option is
|
|
|
|
* enabled.
|
2018-10-02 09:37:19 +02:00
|
|
|
* @param[in] cmd Command to be executed.
|
|
|
|
*
|
|
|
|
* @returns Result of the execution
|
|
|
|
*/
|
|
|
|
int shell_execute_cmd(const struct shell *shell, const char *cmd);
|
|
|
|
|
2018-09-24 15:18:52 +02:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
2018-08-09 09:56:10 +02:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* SHELL_H__ */
|