shell: documentation update

Updating documentation with dictionary commands description.

Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
Jakub Rzeszutko 2020-10-07 10:30:34 +02:00 committed by Anas Nashif
commit c195529615
3 changed files with 64 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -17,6 +17,7 @@ interaction is required. This module is a Unix-like shell with these features:
* Support for multiple instances. * Support for multiple instances.
* Advanced cooperation with the :ref:`logging_api`. * Advanced cooperation with the :ref:`logging_api`.
* Support for static and dynamic commands. * Support for static and dynamic commands.
* Support for dictionary commands.
* Smart command completion with the :kbd:`Tab` key. * Smart command completion with the :kbd:`Tab` key.
* Built-in commands: :command:`clear`, :command:`shell`, :command:`colors`, * Built-in commands: :command:`clear`, :command:`shell`, :command:`colors`,
:command:`echo`, :command:`history` and :command:`resize`. :command:`echo`, :command:`history` and :command:`resize`.
@ -34,8 +35,11 @@ interaction is required. This module is a Unix-like shell with these features:
The module can be connected to any transport for command input and output. The module can be connected to any transport for command input and output.
At this point, the following transport layers are implemented: At this point, the following transport layers are implemented:
* UART
* Segger RTT * Segger RTT
* SMP
* Telnet
* UART
* USB
* DUMMY - not a physical transport layer * DUMMY - not a physical transport layer
Connecting to Segger RTT via TCP (on macOS, for example) Connecting to Segger RTT via TCP (on macOS, for example)
@ -75,6 +79,7 @@ types:
* Dynamic subcommand (level > 0): Number and syntax does not need to be known * Dynamic subcommand (level > 0): Number and syntax does not need to be known
during compile time. Created in the software module. during compile time. Created in the software module.
Creating commands Creating commands
================= =================
@ -100,6 +105,8 @@ Use the following macros for adding shell commands:
time expression is non-zero. time expression is non-zero.
* :c:macro:`SHELL_STATIC_SUBCMD_SET_CREATE` - Create a static subcommands * :c:macro:`SHELL_STATIC_SUBCMD_SET_CREATE` - Create a static subcommands
array. array.
* :c:macro:`SHELL_SUBCMD_DICT_SET_CREATE` - Create a dictionary subcommands
array.
* :c:macro:`SHELL_DYNAMIC_CMD_CREATE` - Create a dynamic subcommands array. * :c:macro:`SHELL_DYNAMIC_CMD_CREATE` - Create a dynamic subcommands array.
Commands can be created in any file in the system that includes Commands can be created in any file in the system that includes
@ -131,6 +138,52 @@ subcommands.
Example implementation can be found under following location: Example implementation can be found under following location:
:zephyr_file:`samples/subsys/shell/shell_module/src/main.c`. :zephyr_file:`samples/subsys/shell/shell_module/src/main.c`.
Dictionary commands
===================
This is a special kind of static commands. Dictionary commands can be used
every time you want to use a pair: (string <-> corresponding data) in
a command handler. The string is usually a verbal description of a given data.
The idea is to use the string as a command syntax that can be prompted by the
shell and corresponding data can be used to process the command.
Let's use an example. Suppose you created a command to set an ADC gain.
It is a perfect place where a dictionary can be used. The dictionary would
be a set of pairs: (string: gain_value, int: value) where int value could
be used with the ADC driver API.
Abstract code for this task would look like this:
.. code-block:: c
static int gain_cmd_handler(const struct shell *shell,
size_t argc, char **argv, void *data)
{
int gain;
/* data is a value corresponding to called command syntax */
gain = (int)data;
adc_set_gain(gain);
shell_print(shell, "ADC gain set to: %s\n"
"Value send to ADC driver: %d",
argv[0],
gain);
return 0;
}
SHELL_SUBCMD_DICT_SET_CREATE(sub_gain, gain_cmd_handler,
(gain_1, 1), (gain_2, 2), (gain_1_2, 3), (gain_1_4, 4)
);
SHELL_CMD_REGISTER(gain, &sub_gain, "Set ADC gain", NULL);
This is how it would look like in the shell:
.. image:: images/dict_cmd.png
:align: center
:alt: Dictionary commands example.
Dynamic commands Dynamic commands
---------------- ----------------

View file

@ -429,22 +429,28 @@ static int UTIL_CAT(cmd_dict_, GET_ARG_N(1, __DEBRACKET _data))( \
/** /**
* @brief Initializes shell dictionary commands. * @brief Initializes shell dictionary commands.
* *
* This is a special kind of static commands. Dictionary commands can be used
* every time you want to use a pair: (string <-> corresponding data) in
* a command handler. The string is usually a verbal description of a given
* data. The idea is to use the string as a command syntax that can be prompted
* by the shell and corresponding data can be used to process the command.
*
* @param[in] _name Name of the dictionary subcommand set * @param[in] _name Name of the dictionary subcommand set
* @param[in] _handler Command handler common for all dictionary commands. * @param[in] _handler Command handler common for all dictionary commands.
* @see shell_dict_cmd_handler * @see shell_dict_cmd_handler
* @param[in] ... Dictionary pairs: (command_syntax, value). Value will be * @param[in] ... Dictionary pairs: (command_syntax, value). Value will be
* passed to the _handler as user data. * passed to the _handler as user data.
* *
* Example usage: * Example usage:
* static int my_handler(const struct shell *shell, * static int my_handler(const struct shell *shell,
* size_t argc, char **argv, void *data) * size_t argc, char **argv, void *data)
* { * {
* int val = (int)data; * int val = (int)data;
*
* shell_print(shell, "(syntax, value) : (%s, %d)", argv[0], val); * shell_print(shell, "(syntax, value) : (%s, %d)", argv[0], val);
* return 0; * return 0;
* } * }
*
* SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, my_handler, * SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, my_handler,
* (value_0, 0), (value_1, 1), (value_2, 2), (value_3, 3) * (value_0, 0), (value_1, 1), (value_2, 2), (value_3, 3)
* ); * );