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:
parent
8dce59b681
commit
bef64c3b77
9 changed files with 598 additions and 235 deletions
|
@ -27,3 +27,4 @@ The Zephyr APIs are used the same way on all SoCs and boards.
|
|||
display_api
|
||||
misc_api
|
||||
logger_api
|
||||
shell_api
|
||||
|
|
16
doc/api/shell_api.rst
Normal file
16
doc/api/shell_api.rst
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
.. _shell_api:
|
||||
|
||||
Shell system API
|
||||
#################
|
||||
|
||||
.. contents::
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: top
|
||||
|
||||
Shell API
|
||||
**********
|
||||
|
||||
.. doxygengroup:: shell_api
|
||||
:project: Zephyr
|
|
@ -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
|
BIN
doc/subsystems/shell/images/dynamic_cmd.PNG
Normal file
BIN
doc/subsystems/shell/images/dynamic_cmd.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
doc/subsystems/shell/images/static_cmd.PNG
Normal file
BIN
doc/subsystems/shell/images/static_cmd.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
doc/subsystems/shell/images/wildcard.png
Normal file
BIN
doc/subsystems/shell/images/wildcard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
510
doc/subsystems/shell/shell.rst
Normal file
510
doc/subsystems/shell/shell.rst
Normal 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
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ to applications.
|
|||
networking/networking.rst
|
||||
power_management.rst
|
||||
sensor
|
||||
shell
|
||||
shell/shell
|
||||
test/index
|
||||
usb/usb.rst
|
||||
settings/settings.rst
|
||||
|
|
|
@ -32,18 +32,16 @@ extern "C" {
|
|||
|
||||
#define SHELL_CMD_ROOT_LVL (0u)
|
||||
|
||||
/*
|
||||
* @defgroup shell Shell
|
||||
* @ingroup subsys
|
||||
*
|
||||
* @brief Module for providing shell.
|
||||
*
|
||||
/**
|
||||
* @brief Shell API
|
||||
* @defgroup shell_api Shell API
|
||||
* @ingroup shell
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct shell_static_entry;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Shell dynamic command descriptor.
|
||||
*
|
||||
* @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,
|
||||
struct shell_static_entry *entry);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Shell command descriptor.
|
||||
*/
|
||||
struct shell_cmd_entry {
|
||||
bool is_dynamic;
|
||||
union {
|
||||
union union_cmd_entry {
|
||||
/*!< Pointer to function returning dynamic commands.*/
|
||||
shell_dynamic_get dynamic_get;
|
||||
|
||||
|
@ -73,7 +71,7 @@ struct shell_cmd_entry {
|
|||
|
||||
struct shell;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Shell command handler prototype.
|
||||
*/
|
||||
typedef void (*shell_cmd_handler)(const struct shell *shell,
|
||||
|
@ -89,8 +87,7 @@ struct shell_static_entry {
|
|||
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).
|
||||
*
|
||||
* @note Each root command shall have unique syntax.
|
||||
|
@ -111,7 +108,7 @@ struct shell_static_entry {
|
|||
.u.entry = &UTIL_CAT(shell_, syntax) \
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Macro for creating a subcommand set. It must be used outside of any
|
||||
* function body.
|
||||
*
|
||||
|
@ -125,13 +122,13 @@ struct shell_static_entry {
|
|||
}; \
|
||||
static const struct shell_static_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.
|
||||
|
@ -143,7 +140,7 @@ struct shell_static_entry {
|
|||
.u.dynamic_get = get \
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Initializes a shell command.
|
||||
*
|
||||
* @param[in] _syntax Command syntax (for example: history).
|
||||
|
@ -158,7 +155,7 @@ struct shell_static_entry {
|
|||
.handler = _handler \
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @internal @brief Internal shell state in response to data received from the
|
||||
* terminal.
|
||||
*/
|
||||
|
@ -170,7 +167,7 @@ enum shell_receive_state {
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* @internal @brief Internal shell state.
|
||||
*/
|
||||
enum shell_state {
|
||||
|
@ -181,7 +178,7 @@ enum shell_state {
|
|||
SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/
|
||||
};
|
||||
|
||||
/* @brief Shell transport event. */
|
||||
/** @brief Shell transport event. */
|
||||
enum shell_transport_evt {
|
||||
SHELL_TRANSPORT_EVT_RX_RDY,
|
||||
SHELL_TRANSPORT_EVT_TX_RDY
|
||||
|
@ -192,11 +189,11 @@ typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt,
|
|||
|
||||
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.
|
||||
|
@ -212,7 +209,7 @@ struct shell_transport_api {
|
|||
shell_transport_handler_t evt_handler,
|
||||
void *context);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Function for uninitializing the shell transport interface.
|
||||
*
|
||||
* @param[in] transport Pointer to the transfer instance.
|
||||
|
@ -221,7 +218,7 @@ struct shell_transport_api {
|
|||
*/
|
||||
int (*uninit)(const struct shell_transport *transport);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Function for reconfiguring the transport to work in blocking
|
||||
* mode.
|
||||
*
|
||||
|
@ -233,7 +230,7 @@ struct shell_transport_api {
|
|||
*/
|
||||
int (*enable)(const struct shell_transport *transport, bool blocking);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Function for writing data to the transport interface.
|
||||
*
|
||||
* @param[in] transport Pointer to the transfer instance.
|
||||
|
@ -246,7 +243,7 @@ struct shell_transport_api {
|
|||
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.
|
||||
|
@ -266,7 +263,9 @@ struct shell_transport {
|
|||
void *ctx;
|
||||
};
|
||||
|
||||
/** @brief Shell statistics structure. */
|
||||
/**
|
||||
* @brief Shell statistics structure.
|
||||
*/
|
||||
struct shell_stats {
|
||||
u32_t log_lost_cnt; /*!< Lost log counter.*/
|
||||
};
|
||||
|
@ -279,7 +278,7 @@ struct shell_stats {
|
|||
#define SHELL_STATS_PTR(_name) NULL
|
||||
#endif /* CONFIG_SHELL_STATS */
|
||||
|
||||
/*
|
||||
/**
|
||||
* @internal @brief Flags for internal shell usage.
|
||||
*/
|
||||
struct shell_flags {
|
||||
|
@ -292,9 +291,11 @@ struct shell_flags {
|
|||
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.
|
||||
*/
|
||||
union shell_internal {
|
||||
|
@ -310,7 +311,7 @@ enum shell_signal {
|
|||
SHELL_SIGNALS
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Shell instance context.
|
||||
*/
|
||||
struct shell_ctx {
|
||||
|
@ -345,7 +346,7 @@ struct shell_ctx {
|
|||
|
||||
extern const struct log_backend_api log_backend_shell_api;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Shell instance internals.
|
||||
*/
|
||||
struct shell {
|
||||
|
@ -371,7 +372,7 @@ struct shell {
|
|||
k_thread_stack_t *stack;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Macro for defining a shell instance.
|
||||
*
|
||||
* @param[in] _name Instance name.
|
||||
|
@ -393,7 +394,7 @@ struct shell {
|
|||
SHELL_FPRINTF_DEFINE(_name## _fprintf, &_name, _name##_out_buffer, \
|
||||
CONFIG_SHELL_PRINTF_BUFF_SIZE, \
|
||||
true, shell_print_stream); \
|
||||
LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \
|
||||
LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \
|
||||
SHELL_STATS_DEFINE(_name); \
|
||||
static K_THREAD_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE);\
|
||||
static struct k_thread _name##_thread; \
|
||||
|
@ -411,7 +412,7 @@ struct shell {
|
|||
.stack = _name##_stack \
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Function for initializing a transport layer and internal shell state.
|
||||
*
|
||||
* @param[in] shell Pointer to shell instance.
|
||||
|
@ -426,7 +427,7 @@ struct shell {
|
|||
int shell_init(const struct shell *shell, const void *transport_config,
|
||||
bool use_colors, bool log_backend, u32_t init_log_level);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Uninitializes the transport layer and the internal shell state.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Function for starting shell processing.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Function for stopping shell processing.
|
||||
*
|
||||
* @param shell Pointer to shell instance.
|
||||
|
@ -453,16 +454,32 @@ int shell_start(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
|
||||
|
||||
/**
|
||||
* @brief Green text color for nrf_shell_fprintf function.
|
||||
*/
|
||||
#define SHELL_INFO SHELL_VT100_COLOR_GREEN
|
||||
|
||||
/**
|
||||
* @brief Cyan text color for nrf_shell_fprintf function.
|
||||
*/
|
||||
#define SHELL_OPTION SHELL_VT100_COLOR_CYAN
|
||||
|
||||
/**
|
||||
* @brief Yellow text color for nrf_shell_fprintf function.
|
||||
*/
|
||||
#define SHELL_WARNING SHELL_VT100_COLOR_YELLOW
|
||||
|
||||
/**
|
||||
* @brief Red text color for nrf_shell_fprintf function.
|
||||
*/
|
||||
#define SHELL_ERROR SHELL_VT100_COLOR_RED
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Printf-like function which sends formatted data stream to the shell.
|
||||
* 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,
|
||||
const char *p_fmt, ...);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Process function, which should be executed when data is ready in the
|
||||
* 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);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Option descriptor.
|
||||
*/
|
||||
struct shell_getopt_option {
|
||||
|
@ -491,7 +508,7 @@ struct shell_getopt_option {
|
|||
const char *optname_help; /*!< Option help string.*/
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Option structure initializer.
|
||||
*
|
||||
* @param[in] _optname Option name long.
|
||||
|
@ -504,7 +521,7 @@ struct shell_getopt_option {
|
|||
.optname_help = _help, \
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Informs that a command has been called with -h or --help option.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Prints the current command help.
|
||||
*
|
||||
* 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,
|
||||
const struct shell_getopt_option *opt, size_t opt_len);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Change displayed shell prompt.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/*
|
||||
* @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.
|
||||
*
|
||||
* Optionally, printing help on wrong argument count can be enabled.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
bool shell_cmd_precheck(const struct shell *shell,
|
||||
bool arg_cnt_nok,
|
||||
bool arg_cnt_ok,
|
||||
const struct shell_getopt_option *opt,
|
||||
size_t opt_len);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @internal @brief This function shall not be used directly, it is required by
|
||||
* 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,
|
||||
size_t data_len);
|
||||
|
||||
/* @} */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue