From 1a8cd31d64ec20b14fc0734ddde3931bbf4b2ea6 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 25 May 2017 21:14:08 +0300 Subject: [PATCH] shell: Add shell_exec This adds shell_exec which can be used to execute commands directly without the use of a console which is useful for both testing as well as interfacing with applications/upper layer which would like to have access to shell commands directly. In addition to that this may be more trivial to interface with instead of using fifos like uart_register_input and telnet_register_input do. Signed-off-by: Luiz Augusto von Dentz --- include/shell/shell.h | 16 +++++++++++++ subsys/shell/shell.c | 53 ++++++++++++++++++++++++------------------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/include/shell/shell.h b/include/shell/shell.h index 2a2712eb775..eee80dda4e5 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -119,6 +119,22 @@ void shell_register_prompt_handler(shell_prompt_function_t handler); */ void shell_register_default_module(const char *name); +/** @brief Execute command line. + * + * Pass command line to shell to execute. The line cannot be a C string literal + * since it will be modified in place, instead a variable can be used: + * + * char cmd[] = "command"; + * shell_exec(cmd); + * + * Note: This by no means makes any of the commands a stable interface, so + * this function should only be used for debugging/diagnostic. + * + * @param line Command line to be executed + * @returns Result of the execution + */ +int shell_exec(char *line); + /** * @} */ diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 33df1ee6f8a..73debb90237 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -350,44 +350,51 @@ static inline void print_cmd_unknown(char *argv) printk("Type 'help' for list of available commands\n"); } -static void shell(void *p1, void *p2, void *p3) +int shell_exec(char *line) { char *argv[ARGC_MAX + 1]; size_t argc; + int err; + shell_cmd_function_t cb; + argc = line2argv(line, argv, ARRAY_SIZE(argv)); + if (!argc) { + return -EINVAL; + } + + cb = get_cb(argc, argv); + if (!cb) { + if (app_cmd_handler != NULL) { + cb = app_cmd_handler; + } else { + print_cmd_unknown(argv[0]); + return -EINVAL; + } + } + + /* Execute callback with arguments */ + err = cb(argc, argv); + if (err < 0) { + show_cmd_help(argv); + } + + return err; +} + +static void shell(void *p1, void *p2, void *p3) +{ ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); while (1) { struct console_input *cmd; - shell_cmd_function_t cb; printk("%s", get_prompt()); cmd = k_fifo_get(&cmds_queue, K_FOREVER); - argc = line2argv(cmd->line, argv, ARRAY_SIZE(argv)); - if (!argc) { - k_fifo_put(&avail_queue, cmd); - continue; - } - - cb = get_cb(argc, argv); - if (!cb) { - if (app_cmd_handler != NULL) { - cb = app_cmd_handler; - } else { - print_cmd_unknown(argv[0]); - k_fifo_put(&avail_queue, cmd); - continue; - } - } - - /* Execute callback with arguments */ - if (cb(argc, argv) < 0) { - show_cmd_help(argv); - } + shell_exec(cmd->line); k_fifo_put(&avail_queue, cmd); }