doc: subsystems: shell: Add documentation.

1. Remove old shell documentation.
2. Create documentation for new shell module.
3. Fix shell.h comments to be able to generate
   API documentation.

Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
Jakub Rzeszutko 2018-09-24 15:18:52 +02:00 committed by Anas Nashif
commit bef64c3b77
9 changed files with 598 additions and 235 deletions

View file

@ -27,3 +27,4 @@ The Zephyr APIs are used the same way on all SoCs and boards.
display_api display_api
misc_api misc_api
logger_api logger_api
shell_api

16
doc/api/shell_api.rst Normal file
View file

@ -0,0 +1,16 @@
.. _shell_api:
Shell system API
#################
.. contents::
:depth: 2
:local:
:backlinks: top
Shell API
**********
.. doxygengroup:: shell_api
:project: Zephyr

View file

@ -1,182 +0,0 @@
.. _shell:
Shell
######
Overview
********
The Shell enables multiple subsystem to use and expose their shell interface
simultaneously.
Each subsystem can support shell functionality dynamically by its Kconfig file,
which enables or disables the shell usage for the subsystem.
Using shell commands
********************
Use one of the following formats:
Help commands
=============
``help``
Prints the list of available modules.
``help MODULE_NAME``
Prints the names of the available commands for the module.
``help MODULE_NAME COMMAND``
Prints help for the module's command (the help describes the available
module commands and required parameters).
Specific module's commands
==========================
A shell interface exposing subsystem features is a shell module, multiple
modules can be available at the same time.
``MODULE_NAME COMMAND``
One of the available modules is "KERNEL", for `Kernel module commands`_.
Information about registering a new module and its commands can be
found in :c:macro:`SHELL_REGISTER` documentation.
Select module commands
======================
``select MODULE_NAME``
Use this command when using the shell only for one module. After entering this
command, you will not need to enter the module name in further commands. If
the selected module has set a default shell prompt during its initialization,
the prompt will be changed to that one. Otherwise, the prompt will be
changed to the selected module's name to reflect the current module in use.
``select``
Clears selected module. Restores prompt as well.
Kernel module commands
======================
When enabled through option :option:`CONFIG_KERNEL_SHELL`, the Kernel
shell module commands display useful kernel-specific information.
You can issue these Kernel module shell commands by specifying
the module and command::
shell> kernel version
or by first selecting the kernel module, and then issuing the specific
command::
shell> select kernel
kernel> version
Here are the Kernel module shell commands:
``version``
Displays the kernel version number
``uptime``
Displays the system uptime in milliseconds
``cycles``
Displays the current time (in cycles), as measured by the system's hardware clock
``threads``
Displays information about the running threads (if
:option:`CONFIG_OBJECT_TRACING` and :option:`CONFIG_THREAD_MONITOR` are
enabled).
``stacks``
Displays size and use information about the main, idle, interrupt and system
workqueue call stacks (if :option:`CONFIG_INIT_STACKS` is enabled)
Other commands
==============
``noprompt``
This command will disable the shell prompt. The shell will still be fully
functional, but the prompt will not be printed each time the shell expects a
new command.
Shell configuration
*******************
There are two levels of configuration: Infrastructure level and Module level.
Infrastructure level
====================
The option :option:`CONFIG_CONSOLE_SHELL` enables the shell subsystem and enable the
default features of the shell subsystem.
Module/Subsystem level
======================
Each subsystem using the shell service should add a unique flag in its Kconfig file.
Example:
CONFIG_NET_SHELL=y
In the subsystem's code, the shell usage depends on this config parameter.
This subsystem specific flag should also depend on :option:`CONFIG_CONSOLE_SHELL` flag.
Configuration steps to add shell functionality to a module
==========================================================
#. Check that :option:`CONFIG_CONSOLE_SHELL` is set to yes.
#. Add the subsystem unique flag to its Kconfig file.
Writing a shell module
**********************
In order to support shell in your subsystem, the application must do the following:
#. Module configuration flag: Declare a new flag in your subsystem Kconfig file.
It should depend on :option:`CONFIG_CONSOLE_SHELL` flag.
#. Module registration to shell: Add your shell identifier and register its
callback functions in the shell database using :c:macro:`SHELL_REGISTER`.
Optionally, you can use one of the following API functions to override default
behavior and settings:
* :c:func:`shell_register_default_module`
* :c:func:`shell_register_prompt_handler`
In case of a sample applications as well as the test environment, you can choose to
set a default module in code level. In this case, the function
:c:func:`shell_register_default_module` should be called after calling SHELL_REGISTER in
application level. If the function
:c:func:`shell_register_prompt_handler` was called as
well, the prompt will be changed to that one. Otherwise, the prompt will be
changed to the selected module's name, in order to reflect the current module in
use.
.. note::
Even if a default module was set in code level, it can be overwritten by
"select" shell command.
You can use :c:func:`shell_register_default_module` in the following cases:
* Use this command in case of using the shell only for one module.
After entering this command, no need to enter module name in further
commands.
* Use this function for shell backward compatibility.
More details on those optional functions can be found in
:ref:`shell_api_functions`.
.. _shell_api_functions:
Shell API Functions
*******************
.. doxygengroup:: _shell_api_functions
:project: Zephyr

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,510 @@
.. _shell:
Shell
######
Overview
********
This module allows you to create and handle a shell with a user-defined command
set. You can use it in examples where more than simple button or LED user
interaction is required. This module is a Unix-like shell with these features:
* Support for multiple instances.
* Advanced cooperation with the :ref:`logger`.
* Support for static and dynamic commands.
* Smart command completion with the :kbd:`Tab` key.
* Built-in commands: :command:`clear`, :command:`shell`, :command:`colors`,
:command:`echo`, :command:`history` and :command:`resize`.
* Viewing recently executed commands using keys: :kbd:`↑` :kbd:`↓`.
* Text edition using keys: :kbd:`←`, :kbd:`→`, :kbd:`Backspace`,
:kbd:`Delete`, :kbd:`End`, :kbd:`Home`, :kbd:`Insert`.
* Support for ANSI escape codes: ``VT100`` and ``ESC[n~`` for cursor control
and color printing.
* Support for multiline commands.
* Built-in handler to display help for the commands.
* Support for wildcards: ``*`` and ``?``.
* Support for meta keys.
* Kconfig configuration to optimize memory usage.
The module can be connected to any transport for command input and output.
At this point, the following transport layers are implemented:
* UART
See the :ref:`shell_api` documentation for more information.
Commands
********
Shell commands are organized in a tree structure and grouped into the following
types:
* Root command (level 0): Gathered and alphabetically sorted in a dedicated
memory section.
* Static subcommand (level > 0): Number and syntax must be known during compile
time. Created in the software module.
* Dynamic subcommand (level > 0): Number and syntax does not need to be known
during compile time. Created in the software module.
Creating commands
=================
Use the following macros for adding shell commands:
* :c:macro:`SHELL_CMD_REGISTER` - Create root command. All root commands must
have different name.
* :c:macro:`SHELL_CMD` - Initialize a command.
* :c:macro:`SHELL_CREATE_STATIC_SUBCMD_SET` - Create a static subcommands
array. Static subcommands must be added in alphabetical order to ensure
correct smart completion.
* :c:macro:`SHELL_SUBCMD_SET_END` - shall be placed as last in
:c:macro:`SHELL_CREATE_STATIC_SUBCMD_SET` macro.
* :c:macro:`SHELL_CREATE_DYNAMIC_CMD` - Create a dynamic subcommands array.
Dynamic subcommands must be returned in alphabetical order to ensure correct
smart completion.
Commands can be created in any file in the system that includes
:file:`include/shell/shell.h`. All created commands are available for all
shell instances.
Static commands
---------------
Example code demonstrating how to create a root command with static
subcommands.
.. image:: images/static_cmd.PNG
:align: center
:alt: Command tree with static commands.
.. code-block:: c
/* Creating subcommands (level 1 command) array for command "demo".
* Subcommands must be added in alphabetical order to ensure correct
* command autocompletion.
*/
SHELL_CREATE_STATIC_SUBCMD_SET(sub_demo)
{
/* Alphabetically sorted. */
SHELL_CMD(params, NULL, "Print params command.",
cmd_demo_params),
SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping),
SHELL_SUBCMD_SET_END /* Array terminated. */
};
/* Creating root (level 0) command "demo" */
SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL);
Example implementation can be found under following location:
:file:`samples/subsys/shell/shell_module/src/main.c`.
Dynamic commands
----------------
Example code demonstrating how to create a root command with static and dynamic
subcommands. At the beginning dynamic command list is empty. New commands
can be added by typing:
.. code-block:: none
dynamic add <new_dynamic_command>
Newly added commands can be prompted or autocompleted with the :kbd:`Tab` key.
.. image:: images/dynamic_cmd.PNG
:align: center
:alt: Command tree with static and dynamic commands.
.. code-block:: c
/* Buffer for 10 dynamic commands */
static char dynamic_cmd_buffer[10][50];
/* commands counter */
static u8_t dynamic_cmd_cnt;
/* Function returning command dynamically created
* in dynamic_cmd_buffer.
*/
static void dynamic_cmd_get(size_t idx,
struct shell_static_entry *entry)
{
if (idx < dynamic_cmd_cnt) {
/* m_dynamic_cmd_buffer must be sorted alphabetically
* to ensure correct Shell autocompletion
*/
entry->syntax = dynamic_cmd_buffer[idx];
entry->handler = NULL;
entry->subcmd = NULL;
entry->help = "Show dynamic command name.";
} else {
/* if there are no more dynamic commands available
* syntax must be set to NULL.
*/
entry->syntax = NULL;
}
}
SHELL_CREATE_DYNAMIC_CMD(m_sub_dynamic_set, dynamic_cmd_get);
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_dynamic)
{
SHELL_CMD(add, NULL,"Add new command to dynamic_cmd_buffer and"
" sort them alphabetically.",
cmd_dynamic_add),
SHELL_CMD(execute, &m_sub_dynamic_set,
"Execute a command.", cmd_dynamic_execute),
SHELL_CMD(remove, &m_sub_dynamic_set,
"Remove a command from dynamic_cmd_buffer.",
cmd_dynamic_remove),
SHELL_CMD(show, NULL,
"Show all commands in dynamic_cmd_buffer.",
cmd_dynamic_show),
SHELL_SUBCMD_SET_END
};
SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic,
"Demonstrate dynamic command usage.", cmd_dynamic);
Example implementation can be found under following location:
:file:`samples/subsys/shell/shell_module/src/dynamic_cmd.c`.
Commands execution
==================
Each command or subcommand may have a handler. The shell executes the handler
that is found deepest in the command tree and further subcommands (without a
handler) are passed as arguments. Characters within parentheses are treated
as one argument. If shell wont find a handler it will display an error message.
Command handler
----------------
Simple command handler implementation:
.. code-block:: c
static void cmd_handler(const struct shell *shell, size_t argc,
char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL,
"Print simple text.\r\n");
shell_fprintf(shell, SHELL_WARNING,
"Print warning text.\r\n");
shell_fprintf(shell, SHELL_ERROR,
"Print error text.\r\n");
}
.. warning::
Do not use function :cpp:func:`shell_fprintf` outside of the command
handler because this might lead to incorrect text display on the
screen. If any text should be displayed outside of the command context,
then use the :ref:`logger`.
Command help
------------
Every user-defined command, subcommand, or option can have its own help
description. The help for commands and subcommands can be created with
respective macros: :c:macro:`SHELL_CMD_REGISTER` and :c:macro:`SHELL_CMD`.
In addition, you can define options for commands or subcommands using the
macro :c:macro:`SHELL_OPT`. By default, each and every command or subcommand
has these two options implemented: ``-h`` and ``--help``.
In order to add help functionality to a command or subcommand, you must
implement the help handler by either calling :cpp:func:`shell_cmd_precheck`
or pair of functions :cpp:func:`shell_help_requested` and
:cpp:func:`shell_help_print`. The former is more convenient as it also
checks for valid arguments count.
.. code-block:: c
static void cmd_dummy_1(const struct shell *shell, size_t argc,
char **argv)
{
ARG_UNUSED(argv);
/* Function shell_cmd_precheck will do one of below actions:
* 1. print help if command called with -h or --help
* 2. print error message if argc > 2
*
* Each of these actions can be deactivated in Kconfig.
*/
if (!shell_cmd_precheck(shell, (argc <= 2), NULL, 0) {
return;
}
shell_fprintf(shell, SHELL_NORMAL,
"Command called with no -h or --help option."
"\r\n");
}
static void cmd_dummy_2(const struct shell *shell, size_t argc,
char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
if (hell_help_requested(shell) {
shell_help_print(shell, NULL, 0);
return;
}
shell_fprintf(shell, SHELL_NORMAL,
"Command called with no -h or --help option."
"\r\n");
}
Command options
---------------
When possible, use subcommands instead of options. Options apply mainly in the
case when an argument with ``-`` or ``--`` is requested. The main benefit of
using subcommands is that they can be prompted or completed with the :kbd:`Tab`
key. In addition, subcommands can have their own handler, which limits the
usage of ``if - else if`` statements combination with the ``strcmp`` function
in command handler.
.. code-block:: c
static void cmd_with_options(const struct shell *shell, size_t argc,
char **argv)
{
/* Dummy options showing options usage */
static const struct shell_getopt_option opt[] = {
SHELL_OPT(
"--test",
"-t",
"test option help string"
),
SHELL_OPT(
"--dummy",
"-d",
"dummy option help string"
)
};
/* If command will be called with -h or --help option
* all declared options will be listed in the help message
*/
if (!shell_cmd_precheck(shell, (argc <= 2), opt,
sizeof(opt)/sizeof(opt[1]))) {
return;
}
/* checking if command was called with test option */
if (!strcmp(argv[1], "-t") || !strcmp(argv[1], "--test")) {
shell_fprintf(shell, SHELL_NORMAL, "Command called with -t"
" or --test option.\r\n");
return;
}
/* checking if command was called with dummy option */
if (!strcmp(argv[1], "-d") || !strcmp(argv[1], "--dummy")) {
shell_fprintf(shell, SHELL_NORMAL, "Command called with -d"
" or --dummy option.\r\n");
return;
}
shell_fprintf(shell, SHELL_WARNING,
"Command called with no valid option.\r\n");
}
Parent commands
---------------
In the subcommand handler, you can access both the parameters passed to
commands or the parent commands, depending on how you index ``argv``.
* When indexing ``argv`` with positive numbers, you can access the parameters.
* When indexing ``argv`` with negative numbers, you can access the parent
commands.
* The subcommand to which the handler belongs has the ``argv`` value of 0.
.. code-block:: c
static void cmd_handler(const struct shell *shell, size_t argc,
char **argv)
{
ARG_UNUSED(argc);
/* If it is a subcommand handler parent command syntax
* can be found using argv[-1].
*/
shell_fprintf(shell, SHELL_NORMAL,
"This command has a parent command: %s\r\n",
argv[-1]);
/* Print this command syntax */
shell_fprintf(shell, SHELL_NORMAL,
"This command syntax is: %s\r\n",
argv[0]);
/* Print first argument */
shell_fprintf(shell, SHELL_NORMAL,
"This command has an argument: %s\r\n",
argv[1]);
}
Built-in commands
=================
* :command:`clear` - Clears the screen.
* :command:`history` - Shows the recently entered commands.
* :command:`resize` - Must be executed when terminal width is different than 80
characters or after each change of terminal width. It ensures proper
multiline text display and :kbd:`←`, :kbd:`→`, :kbd:`End`, :kbd:`Home` keys
handling. Currently this command works only with UART flow control switched
on. It can be also called with a subcommand:
* :command:`default` - Shell will send terminal width = 80 to the
terminal and assume successful delivery.
* :command:`shell` - Root command with useful shell-related subcommands like:
* :command:`echo` - Toggles shell echo.
* :command:`colors` - Toggles colored syntax. This might be helpful in
case of Bluetooth shell to limit the amount of transferred bytes.
* :command:`stats` - Shows shell statistics.
Wildcards
*********
The shell module can handle wildcards. Wildcards are interpreted correctly
when expanded command and its subcommands do not have a handler. For example,
if you want to set logging level to ``err`` for the ``app`` and ``app_test``
modules you can execute the following command:
.. code-block:: none
log enable err a*
.. image:: images/wildcard.png
:align: center
:alt: Wildcard usage example
Meta keys
*********
The shell module supports the following meta keys:
.. list-table:: Implemented meta keys
:widths: 10 40
:header-rows: 1
* - Meta keys
- Action
* - ctrl + a
- Moves the cursor to the beginning of the line.
* - ctrl + c
- Preserves the last command on the screen and starts a new command in
a new line.
* - ctrl + e
- Moves the cursor to the end of the line.
* - ctrl + l
- Clears the screen and leaves the currently typed command at the top of
the screen.
* - ctrl + u
- Clears the currently typed command.
* - ctrl + w
- Removes the word or part of the word to the left of the cursor. Words
separated by period instead of space are treated as one word.
Usage
*****
Use the :c:macro:`SHELL_DEFINE` macro to create an instance of the shell.
Pass the expected newline character to this macro: either ``\r`` or ``\n``,
otherwise the shell will not respond correctly to the :kbd:`Enter` key.
The following code shows a simple use case of this library:
.. code-block:: c
/* Defining shell backend */
SHELL_UART_DEFINE(shell_transport_uart);
/* Creating shell instance */
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, '\r', 10);
void main(void)
{
(void)shell_init(&uart_shell, NULL, true, true, LOG_LEVEL_INF);
}
static void cmd_demo_ping(const struct shell *shell, size_t argc,
char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL, "pong\r\n");
}
static void cmd_demo_params(const struct shell *shell, size_t argc,
char **argv)
{
int cnt;
shell_fprintf(shell, SHELL_NORMAL, "argc = %d\r\n", argc);
for (cnt = 0; cnt < argc; cnt++) {
shell_fprintf(shell, SHELL_NORMAL,
" argv[%d] = %s\r\n", cnt, argv[cnt]);
}
}
/* Creating subcommands (level 1 command) array for command "demo".
* Subcommands must be added in alphabetical order
*/
SHELL_CREATE_STATIC_SUBCMD_SET(sub_demo)
{
/* Alphabetically sorted. */
SHELL_CMD(params, NULL, "Print params command.",
cmd_demo_params),
SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping),
SHELL_SUBCMD_SET_END /* Array terminated. */
};
/* Creating root (level 0) command "demo" without a handler */
SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL);
/* Creating root (level 0) command "version" */
SHELL_CMD_REGISTER(version, NULL, "Show kernel version", cmd_version);
Users may use the :kbd:`Tab` key to complete a command/subcommand or to see the
available subcommands for the currently entered command level.
For example, when the cursor is positioned at the beginning of the command
line and the :kbd:`Tab` key is pressed, the user will see all root (level 0)
commands:
.. code-block:: none
clear demo shell history log resize version
.. note::
To view the subcommands that are available for a specific command, you
must first type a :kbd:`space` after this command and then hit
:kbd:`Tab`.
These commands are registered by various modules, for example:
* :command:`clear`, :command:`shell`, :command:`history`, and :command:`resize`
are built-in commands which have been registered by
:file:`subsys/shell/shell.c`
* :command:`demo` and :command:`version` have been registered in example code
above by main.c
* :command:`log` has been registered by :file:`subsys/logging/log_cmds.c`
Then, if a user types a :command:`demo` command and presses the :kbd:`Tab` key,
the shell will only print the subcommands registered for this command:
.. code-block:: none
params ping

View file

@ -18,7 +18,7 @@ to applications.
networking/networking.rst networking/networking.rst
power_management.rst power_management.rst
sensor sensor
shell shell/shell
test/index test/index
usb/usb.rst usb/usb.rst
settings/settings.rst settings/settings.rst

View file

@ -32,18 +32,16 @@ extern "C" {
#define SHELL_CMD_ROOT_LVL (0u) #define SHELL_CMD_ROOT_LVL (0u)
/* /**
* @defgroup shell Shell * @brief Shell API
* @ingroup subsys * @defgroup shell_api Shell API
* * @ingroup shell
* @brief Module for providing shell.
*
* @{ * @{
*/ */
struct shell_static_entry; struct shell_static_entry;
/* /**
* @brief Shell dynamic command descriptor. * @brief Shell dynamic command descriptor.
* *
* @details Function shall fill the received shell_static_entry structure * @details Function shall fill the received shell_static_entry structure
@ -57,12 +55,12 @@ struct shell_static_entry;
typedef void (*shell_dynamic_get)(size_t idx, typedef void (*shell_dynamic_get)(size_t idx,
struct shell_static_entry *entry); struct shell_static_entry *entry);
/* /**
* @brief Shell command descriptor. * @brief Shell command descriptor.
*/ */
struct shell_cmd_entry { struct shell_cmd_entry {
bool is_dynamic; bool is_dynamic;
union { union union_cmd_entry {
/*!< Pointer to function returning dynamic commands.*/ /*!< Pointer to function returning dynamic commands.*/
shell_dynamic_get dynamic_get; shell_dynamic_get dynamic_get;
@ -73,7 +71,7 @@ struct shell_cmd_entry {
struct shell; struct shell;
/* /**
* @brief Shell command handler prototype. * @brief Shell command handler prototype.
*/ */
typedef void (*shell_cmd_handler)(const struct shell *shell, typedef void (*shell_cmd_handler)(const struct shell *shell,
@ -89,8 +87,7 @@ struct shell_static_entry {
shell_cmd_handler handler; /*!< Command handler. */ shell_cmd_handler handler; /*!< Command handler. */
}; };
#define SHELL_CMD_NAME(name) UTIL_CAT(shell_cmd_, name) /**
/*
* @brief Macro for defining and adding a root command (level 0). * @brief Macro for defining and adding a root command (level 0).
* *
* @note Each root command shall have unique syntax. * @note Each root command shall have unique syntax.
@ -111,7 +108,7 @@ struct shell_static_entry {
.u.entry = &UTIL_CAT(shell_, syntax) \ .u.entry = &UTIL_CAT(shell_, syntax) \
} }
/* /**
* @brief Macro for creating a subcommand set. It must be used outside of any * @brief Macro for creating a subcommand set. It must be used outside of any
* function body. * function body.
* *
@ -125,13 +122,13 @@ struct shell_static_entry {
}; \ }; \
static const struct shell_static_entry shell_##name[] = static const struct shell_static_entry shell_##name[] =
/* /**
* @brief Define ending subcommands set. * @brief Define ending subcommands set.
* *
*/ */
#define SHELL_SUBCMD_SET_END {NULL} #define SHELL_SUBCMD_SET_END {NULL}
/* /**
* @brief Macro for creating a dynamic entry. * @brief Macro for creating a dynamic entry.
* *
* @param[in] name Name of the dynamic entry. * @param[in] name Name of the dynamic entry.
@ -143,7 +140,7 @@ struct shell_static_entry {
.u.dynamic_get = get \ .u.dynamic_get = get \
} }
/* /**
* @brief Initializes a shell command. * @brief Initializes a shell command.
* *
* @param[in] _syntax Command syntax (for example: history). * @param[in] _syntax Command syntax (for example: history).
@ -158,7 +155,7 @@ struct shell_static_entry {
.handler = _handler \ .handler = _handler \
} }
/* /**
* @internal @brief Internal shell state in response to data received from the * @internal @brief Internal shell state in response to data received from the
* terminal. * terminal.
*/ */
@ -170,7 +167,7 @@ enum shell_receive_state {
}; };
/* /**
* @internal @brief Internal shell state. * @internal @brief Internal shell state.
*/ */
enum shell_state { enum shell_state {
@ -181,7 +178,7 @@ enum shell_state {
SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/ SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/
}; };
/* @brief Shell transport event. */ /** @brief Shell transport event. */
enum shell_transport_evt { enum shell_transport_evt {
SHELL_TRANSPORT_EVT_RX_RDY, SHELL_TRANSPORT_EVT_RX_RDY,
SHELL_TRANSPORT_EVT_TX_RDY SHELL_TRANSPORT_EVT_TX_RDY
@ -192,11 +189,11 @@ typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt,
struct shell_transport; struct shell_transport;
/* /**
* @brief Unified shell transport interface. * @brief Unified shell transport interface.
*/ */
struct shell_transport_api { struct shell_transport_api {
/* /**
* @brief Function for initializing the shell transport interface. * @brief Function for initializing the shell transport interface.
* *
* @param[in] transport Pointer to the transfer instance. * @param[in] transport Pointer to the transfer instance.
@ -212,7 +209,7 @@ struct shell_transport_api {
shell_transport_handler_t evt_handler, shell_transport_handler_t evt_handler,
void *context); void *context);
/* /**
* @brief Function for uninitializing the shell transport interface. * @brief Function for uninitializing the shell transport interface.
* *
* @param[in] transport Pointer to the transfer instance. * @param[in] transport Pointer to the transfer instance.
@ -221,7 +218,7 @@ struct shell_transport_api {
*/ */
int (*uninit)(const struct shell_transport *transport); int (*uninit)(const struct shell_transport *transport);
/* /**
* @brief Function for reconfiguring the transport to work in blocking * @brief Function for reconfiguring the transport to work in blocking
* mode. * mode.
* *
@ -233,7 +230,7 @@ struct shell_transport_api {
*/ */
int (*enable)(const struct shell_transport *transport, bool blocking); int (*enable)(const struct shell_transport *transport, bool blocking);
/* /**
* @brief Function for writing data to the transport interface. * @brief Function for writing data to the transport interface.
* *
* @param[in] transport Pointer to the transfer instance. * @param[in] transport Pointer to the transfer instance.
@ -246,7 +243,7 @@ struct shell_transport_api {
int (*write)(const struct shell_transport *transport, int (*write)(const struct shell_transport *transport,
const void *data, size_t length, size_t *cnt); const void *data, size_t length, size_t *cnt);
/* /**
* @brief Function for reading data from the transport interface. * @brief Function for reading data from the transport interface.
* *
* @param[in] p_transport Pointer to the transfer instance. * @param[in] p_transport Pointer to the transfer instance.
@ -266,7 +263,9 @@ struct shell_transport {
void *ctx; void *ctx;
}; };
/** @brief Shell statistics structure. */ /**
* @brief Shell statistics structure.
*/
struct shell_stats { struct shell_stats {
u32_t log_lost_cnt; /*!< Lost log counter.*/ u32_t log_lost_cnt; /*!< Lost log counter.*/
}; };
@ -279,7 +278,7 @@ struct shell_stats {
#define SHELL_STATS_PTR(_name) NULL #define SHELL_STATS_PTR(_name) NULL
#endif /* CONFIG_SHELL_STATS */ #endif /* CONFIG_SHELL_STATS */
/* /**
* @internal @brief Flags for internal shell usage. * @internal @brief Flags for internal shell usage.
*/ */
struct shell_flags { struct shell_flags {
@ -292,9 +291,11 @@ struct shell_flags {
u32_t mode_delete :1; /*!< Operation mode of backspace key */ u32_t mode_delete :1; /*!< Operation mode of backspace key */
}; };
BUILD_ASSERT(sizeof(struct shell_flags) == sizeof(u32_t)); BUILD_ASSERT_MSG((sizeof(struct shell_flags) == sizeof(u32_t)),
"Structure must fit in 4 bytes");
/*
/**
* @internal @brief Union for internal shell usage. * @internal @brief Union for internal shell usage.
*/ */
union shell_internal { union shell_internal {
@ -310,7 +311,7 @@ enum shell_signal {
SHELL_SIGNALS SHELL_SIGNALS
}; };
/* /**
* @brief Shell instance context. * @brief Shell instance context.
*/ */
struct shell_ctx { struct shell_ctx {
@ -345,7 +346,7 @@ struct shell_ctx {
extern const struct log_backend_api log_backend_shell_api; extern const struct log_backend_api log_backend_shell_api;
/* /**
* @brief Shell instance internals. * @brief Shell instance internals.
*/ */
struct shell { struct shell {
@ -371,7 +372,7 @@ struct shell {
k_thread_stack_t *stack; k_thread_stack_t *stack;
}; };
/* /**
* @brief Macro for defining a shell instance. * @brief Macro for defining a shell instance.
* *
* @param[in] _name Instance name. * @param[in] _name Instance name.
@ -411,7 +412,7 @@ struct shell {
.stack = _name##_stack \ .stack = _name##_stack \
} }
/* /**
* @brief Function for initializing a transport layer and internal shell state. * @brief Function for initializing a transport layer and internal shell state.
* *
* @param[in] shell Pointer to shell instance. * @param[in] shell Pointer to shell instance.
@ -426,7 +427,7 @@ struct shell {
int shell_init(const struct shell *shell, const void *transport_config, int shell_init(const struct shell *shell, const void *transport_config,
bool use_colors, bool log_backend, u32_t init_log_level); bool use_colors, bool log_backend, u32_t init_log_level);
/* /**
* @brief Uninitializes the transport layer and the internal shell state. * @brief Uninitializes the transport layer and the internal shell state.
* *
* @param shell Pointer to shell instance. * @param shell Pointer to shell instance.
@ -435,7 +436,7 @@ int shell_init(const struct shell *shell, const void *transport_config,
*/ */
int shell_uninit(const struct shell *shell); int shell_uninit(const struct shell *shell);
/* /**
* @brief Function for starting shell processing. * @brief Function for starting shell processing.
* *
* @param shell Pointer to the shell instance. * @param shell Pointer to the shell instance.
@ -444,7 +445,7 @@ int shell_uninit(const struct shell *shell);
*/ */
int shell_start(const struct shell *shell); int shell_start(const struct shell *shell);
/* /**
* @brief Function for stopping shell processing. * @brief Function for stopping shell processing.
* *
* @param shell Pointer to shell instance. * @param shell Pointer to shell instance.
@ -453,16 +454,32 @@ int shell_start(const struct shell *shell);
*/ */
int shell_stop(const struct shell *shell); int shell_stop(const struct shell *shell);
/* /**
* @brief Shell colors for nrf_shell_fprintf function. * @brief Terminal default text color for nrf_shell_fprintf function.
*/ */
#define SHELL_NORMAL SHELL_VT100_COLOR_DEFAULT #define SHELL_NORMAL SHELL_VT100_COLOR_DEFAULT
/**
* @brief Green text color for nrf_shell_fprintf function.
*/
#define SHELL_INFO SHELL_VT100_COLOR_GREEN #define SHELL_INFO SHELL_VT100_COLOR_GREEN
/**
* @brief Cyan text color for nrf_shell_fprintf function.
*/
#define SHELL_OPTION SHELL_VT100_COLOR_CYAN #define SHELL_OPTION SHELL_VT100_COLOR_CYAN
/**
* @brief Yellow text color for nrf_shell_fprintf function.
*/
#define SHELL_WARNING SHELL_VT100_COLOR_YELLOW #define SHELL_WARNING SHELL_VT100_COLOR_YELLOW
/**
* @brief Red text color for nrf_shell_fprintf function.
*/
#define SHELL_ERROR SHELL_VT100_COLOR_RED #define SHELL_ERROR SHELL_VT100_COLOR_RED
/* /**
* @brief Printf-like function which sends formatted data stream to the shell. * @brief Printf-like function which sends formatted data stream to the shell.
* This function shall not be used outside of the shell command context. * This function shall not be used outside of the shell command context.
* *
@ -474,7 +491,7 @@ int shell_stop(const struct shell *shell);
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color, void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
const char *p_fmt, ...); const char *p_fmt, ...);
/* /**
* @brief Process function, which should be executed when data is ready in the * @brief Process function, which should be executed when data is ready in the
* transport interface. To be used if shell thread is disabled. * transport interface. To be used if shell thread is disabled.
* *
@ -482,7 +499,7 @@ void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
*/ */
void shell_process(const struct shell *shell); void shell_process(const struct shell *shell);
/* /**
* @brief Option descriptor. * @brief Option descriptor.
*/ */
struct shell_getopt_option { struct shell_getopt_option {
@ -491,7 +508,7 @@ struct shell_getopt_option {
const char *optname_help; /*!< Option help string.*/ const char *optname_help; /*!< Option help string.*/
}; };
/* /**
* @brief Option structure initializer. * @brief Option structure initializer.
* *
* @param[in] _optname Option name long. * @param[in] _optname Option name long.
@ -504,7 +521,7 @@ struct shell_getopt_option {
.optname_help = _help, \ .optname_help = _help, \
} }
/* /**
* @brief Informs that a command has been called with -h or --help option. * @brief Informs that a command has been called with -h or --help option.
* *
* @param[in] shell Pointer to the shell instance. * @param[in] shell Pointer to the shell instance.
@ -516,7 +533,7 @@ static inline bool shell_help_requested(const struct shell *shell)
return shell->ctx->internal.flags.show_help; return shell->ctx->internal.flags.show_help;
} }
/* /**
* @brief Prints the current command help. * @brief Prints the current command help.
* *
* Function will print a help string with: the currently entered command, its * Function will print a help string with: the currently entered command, its
@ -529,7 +546,7 @@ static inline bool shell_help_requested(const struct shell *shell)
void shell_help_print(const struct shell *shell, void shell_help_print(const struct shell *shell,
const struct shell_getopt_option *opt, size_t opt_len); const struct shell_getopt_option *opt, size_t opt_len);
/* /**
* @brief Change displayed shell prompt. * @brief Change displayed shell prompt.
* *
* @param[in] shell Pointer to the shell instance. * @param[in] shell Pointer to the shell instance.
@ -540,10 +557,9 @@ void shell_help_print(const struct shell *shell,
*/ */
int shell_prompt_change(const struct shell *shell, char *prompt); int shell_prompt_change(const struct shell *shell, char *prompt);
/* /**
* @brief Prints help if request and prints error message on wrong argument * @brief Prints help if requested and prints error message on wrong argument
* count. * count.
*
* Optionally, printing help on wrong argument count can be enabled. * Optionally, printing help on wrong argument count can be enabled.
* *
* @param[in] shell Pointer to the shell instance. * @param[in] shell Pointer to the shell instance.
@ -554,11 +570,11 @@ int shell_prompt_change(const struct shell *shell, char *prompt);
* @return True if check passed, false otherwise or help was requested. * @return True if check passed, false otherwise or help was requested.
*/ */
bool shell_cmd_precheck(const struct shell *shell, bool shell_cmd_precheck(const struct shell *shell,
bool arg_cnt_nok, bool arg_cnt_ok,
const struct shell_getopt_option *opt, const struct shell_getopt_option *opt,
size_t opt_len); size_t opt_len);
/* /**
* @internal @brief This function shall not be used directly, it is required by * @internal @brief This function shall not be used directly, it is required by
* the fprintf module. * the fprintf module.
* *
@ -569,7 +585,9 @@ bool shell_cmd_precheck(const struct shell *shell,
void shell_print_stream(const void *user_ctx, const char *data, void shell_print_stream(const void *user_ctx, const char *data,
size_t data_len); size_t data_len);
/* @} */ /**
* @}
*/
#ifdef __cplusplus #ifdef __cplusplus
} }