diff --git a/doc/api/api.rst b/doc/api/api.rst index 205bda035b4..a16c76582b5 100644 --- a/doc/api/api.rst +++ b/doc/api/api.rst @@ -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 diff --git a/doc/api/shell_api.rst b/doc/api/shell_api.rst new file mode 100644 index 00000000000..0c684eb4a82 --- /dev/null +++ b/doc/api/shell_api.rst @@ -0,0 +1,16 @@ + +.. _shell_api: + +Shell system API +################# + +.. contents:: + :depth: 2 + :local: + :backlinks: top + +Shell API +********** + +.. doxygengroup:: shell_api + :project: Zephyr diff --git a/doc/subsystems/shell.rst b/doc/subsystems/shell.rst deleted file mode 100644 index e9f1d0689c5..00000000000 --- a/doc/subsystems/shell.rst +++ /dev/null @@ -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 diff --git a/doc/subsystems/shell/images/dynamic_cmd.PNG b/doc/subsystems/shell/images/dynamic_cmd.PNG new file mode 100644 index 00000000000..09701d07efe Binary files /dev/null and b/doc/subsystems/shell/images/dynamic_cmd.PNG differ diff --git a/doc/subsystems/shell/images/static_cmd.PNG b/doc/subsystems/shell/images/static_cmd.PNG new file mode 100644 index 00000000000..e2118818c2a Binary files /dev/null and b/doc/subsystems/shell/images/static_cmd.PNG differ diff --git a/doc/subsystems/shell/images/wildcard.png b/doc/subsystems/shell/images/wildcard.png new file mode 100644 index 00000000000..84be7083e5e Binary files /dev/null and b/doc/subsystems/shell/images/wildcard.png differ diff --git a/doc/subsystems/shell/shell.rst b/doc/subsystems/shell/shell.rst new file mode 100644 index 00000000000..fc7928db98a --- /dev/null +++ b/doc/subsystems/shell/shell.rst @@ -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 + +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 + + diff --git a/doc/subsystems/subsystems.rst b/doc/subsystems/subsystems.rst index 372fdeec983..64a659b48d9 100644 --- a/doc/subsystems/subsystems.rst +++ b/doc/subsystems/subsystems.rst @@ -18,7 +18,7 @@ to applications. networking/networking.rst power_management.rst sensor - shell + shell/shell test/index usb/usb.rst settings/settings.rst diff --git a/include/shell/shell.h b/include/shell/shell.h index 43a7a2dfca4..1abd8270219 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -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 }