From 98d7f13c24089a090e156b9820b3e2b3d0a3a8bb Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 28 May 2020 11:00:56 +0800 Subject: [PATCH] console_repl: change config structure to support different devices --- components/console/esp_console.h | 133 ++--- components/console/esp_console_repl.c | 465 +++++++++--------- components/console/test/test_console.c | 23 +- docs/en/api-reference/system/console.rst | 4 +- docs/zh_CN/api-reference/system/console.rst | 4 +- .../main/ble_mesh_console_main.c | 12 +- .../main/ble_mesh_console_main.c | 11 +- .../ble_mesh_wifi_coexist/main/main.c | 22 +- .../iperf/main/ethernet_example_main.c | 9 +- .../i2c_tools/main/i2ctools_example_main.c | 8 +- .../icmp_echo/main/echo_example_main.c | 29 +- examples/wifi/iperf/main/iperf_example_main.c | 8 +- .../main/simple_sniffer_example_main.c | 10 +- 13 files changed, 404 insertions(+), 334 deletions(-) diff --git a/components/console/esp_console.h b/components/console/esp_console.h index 1409bfe5b..98201cdbc 100644 --- a/components/console/esp_console.h +++ b/components/console/esp_console.h @@ -56,60 +56,49 @@ typedef struct { uint32_t task_stack_size; //!< repl task stack size uint32_t task_priority; //!< repl task priority const char *prompt; //!< prompt (NULL represents default: "esp> ") - union { - struct { - int channel; //!< UART channel - uint32_t baud_rate; //!< Comunication baud rate - int tx_gpio; //!< GPIO number for TX path, -1 means using the default - int rx_gpio; //!< GPIO number for RX path, -1 means using the default - } uart; //!< UART specific configuration - } device; //!< device configuration } esp_console_repl_config_t; -#ifdef CONFIG_ESP_CONSOLE_UART_NUM -#define CONSOLE_DEFAULT_UART_CHANNEL CONFIG_ESP_CONSOLE_UART_NUM -#else -#define CONSOLE_DEFAULT_UART_CHANNEL 0 -#endif - -#ifdef CONFIG_ESP_CONSOLE_UART_BAUDRATE -#define CONSOLE_DEFAULT_UART_BAUDRATE CONFIG_ESP_CONSOLE_UART_BAUDRATE -#else -#define CONSOLE_DEFAULT_UART_BAUDRATE 115200 -#endif - -#ifdef CONFIG_ESP_CONSOLE_UART_TX_GPIO -#define CONSOLE_DEFAULT_UART_TX_GPIO CONFIG_ESP_CONSOLE_UART_TX_GPIO -#else -#define CONSOLE_DEFAULT_UART_TX_GPIO 1 -#endif - -#ifdef CONFIG_ESP_CONSOLE_UART_RX_GPIO -#define CONSOLE_DEFAULT_UART_RX_GPIO CONFIG_ESP_CONSOLE_UART_RX_GPIO -#else -#define CONSOLE_DEFAULT_UART_RX_GPIO 3 -#endif - /** * @brief Default console repl configuration value * */ -#define ESP_CONSOLE_REPL_CONFIG_DEFAULT() \ - { \ - .max_history_len = 32, \ - .history_save_path = NULL, \ - .task_stack_size = 4096, \ - .task_priority = 2, \ - .prompt = NULL, \ - .device = { \ - .uart = { \ - .channel = CONSOLE_DEFAULT_UART_CHANNEL, \ - .baud_rate = CONSOLE_DEFAULT_UART_BAUDRATE, \ - .tx_gpio = CONSOLE_DEFAULT_UART_TX_GPIO, \ - .rx_gpio = CONSOLE_DEFAULT_UART_RX_GPIO, \ - } \ - } \ - } +#define ESP_CONSOLE_REPL_CONFIG_DEFAULT() \ +{ \ + .max_history_len = 32, \ + .history_save_path = NULL, \ + .task_stack_size = 4096, \ + .task_priority = 2, \ + .prompt = NULL, \ +} + +/** + * @brief Parameters for console device: UART + * + */ +typedef struct { + int channel; //!< UART channel number (count from zero) + int baud_rate; //!< Comunication baud rate + int tx_gpio_num; //!< GPIO number for TX path, -1 means using default one + int rx_gpio_num; //!< GPIO number for RX path, -1 means using default one +} esp_console_dev_uart_config_t; + +#ifdef CONFIG_ESP_CONSOLE_UART_CUSTOM +#define ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT() \ +{ \ + .channel = CONFIG_ESP_CONSOLE_UART_NUM, \ + .baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE, \ + .tx_gpio_num = CONFIG_ESP_CONSOLE_UART_TX_GPIO, \ + .rx_gpio_num = CONFIG_ESP_CONSOLE_UART_RX_GPIO, \ +} +#else +#define ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT() \ +{ \ + .channel = CONFIG_ESP_CONSOLE_UART_NUM, \ + .baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE, \ + .tx_gpio_num = -1, \ + .rx_gpio_num = -1, \ +} +#endif /** * @brief initialize console module @@ -270,10 +259,34 @@ esp_err_t esp_console_register_help_command(void); /****************************************************************************** * Console REPL ******************************************************************************/ + /** - * @brief Initialize console REPL environment + * @brief Type defined for console REPL * - * @param config REPL configuration + */ +typedef struct esp_console_repl_s esp_console_repl_t; + +/** + * @brief Console REPL base structure + * + */ +struct esp_console_repl_s { + /** + * @brief Delete console REPL environment + * @param[in] repl REPL handle returned from esp_console_new_repl_xxx + * @return + * - ESP_OK on success + * - ESP_FAIL on errors + */ + esp_err_t (*del)(esp_console_repl_t *repl); +}; + +/** + * @brief Establish a console REPL environment over UART driver + * + * @param[in] dev_config UART device configuration + * @param[in] repl_config REPL configuration + * @param[out] ret_repl return REPL handle after initialization succeed, return NULL otherwise * * @note This is a all-in-one function to establish the environment needed for REPL, includes: * - Install the UART driver on the console UART (8n1, 115200, REF_TICK clock source) @@ -289,27 +302,17 @@ esp_err_t esp_console_register_help_command(void); * - ESP_OK on success * - ESP_FAIL Parameter error */ -esp_err_t esp_console_repl_init(const esp_console_repl_config_t *config); +esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl); /** - * @brief Start REPL task - * + * @brief Start REPL environment + * @param[in] repl REPL handle returned from esp_console_new_repl_xxx + * @note Once the REPL got started, it won't be stopped until user call repl->del(repl) to destory the REPL environment. * @return * - ESP_OK on success * - ESP_ERR_INVALID_STATE, if repl has started already */ -esp_err_t esp_console_repl_start(void); - -/** - * @brief Register a 'quit' command - * - * Default 'quit' command will destory resources and exit REPL environment. - * - * @return - * - ESP_OK on success - * - others on failed - */ -esp_err_t esp_console_register_quit_command(void); +esp_err_t esp_console_start_repl(esp_console_repl_t *repl); #ifdef __cplusplus } diff --git a/components/console/esp_console_repl.c b/components/console/esp_console_repl.c index 39e8d2d14..5fc8a50be 100644 --- a/components/console/esp_console_repl.c +++ b/components/console/esp_console_repl.c @@ -1,4 +1,4 @@ -// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD +// Copyright 2016-2020 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ #include #include +#include #include "sdkconfig.h" #include "esp_err.h" #include "esp_log.h" @@ -24,9 +25,9 @@ #include "driver/uart.h" #include "linenoise/linenoise.h" -static const char *TAG = "console.repl"; +static const char *TAG = "console.repl.uart"; -#define CONSOLE_PROMPT_LEN_MAX (32) +#define CONSOLE_PROMPT_MAX_LEN (32) typedef enum { CONSOLE_REPL_STATE_DEINIT, @@ -34,38 +35,244 @@ typedef enum { CONSOLE_REPL_STATE_START, } repl_state_t; -static repl_state_t s_repl_state = CONSOLE_REPL_STATE_DEINIT; +typedef struct { + esp_console_repl_t repl_core; // base class + char prompt[CONSOLE_PROMPT_MAX_LEN]; // Prompt to be printed before each line + repl_state_t state; + const char *history_save_path; + TaskHandle_t task_hdl; // REPL task handle +} esp_console_repl_com_t; -/** - * @brief Prompt to be printed before each line. - * - */ -static char s_prompt[CONSOLE_PROMPT_LEN_MAX]; +typedef struct { + esp_console_repl_com_t repl_com; // base class + int uart_channel; // uart channel number +} esp_console_repl_uart_t; -/** - * @brief path to save history commands in file system - * - */ -static const char *s_history_save_path = NULL; +static void esp_console_repl_task(void *args); +static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl); +static esp_err_t esp_console_common_init(esp_console_repl_com_t *repl_com); +static esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com); +static esp_err_t esp_console_setup_history(const char *history_path, uint32_t max_history_len, esp_console_repl_com_t *repl_com); -/** - * @brief default uart channel number - * - */ -static int s_uart_channel = -1; - -/** - * @brief REPL task handle - * - */ -static TaskHandle_t s_repl_task_hdl = NULL; - -static void esp_console_repl_thread(void *param) +esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl) { + esp_err_t ret = ESP_OK; + esp_console_repl_uart_t *uart_repl = NULL; + if (!repl_config | !dev_config | !ret_repl) { + ret = ESP_ERR_INVALID_ARG; + goto _exit; + } + // allocate memory for console REPL context + uart_repl = calloc(1, sizeof(esp_console_repl_uart_t)); + if (!uart_repl) { + ret = ESP_ERR_NO_MEM; + goto _exit; + } + + /* Drain stdout before reconfiguring it */ + fflush(stdout); + fsync(fileno(stdout)); + + /* Disable buffering on stdin */ + setvbuf(stdin, NULL, _IONBF, 0); + + /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ + esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + /* Move the caret to the beginning of the next line on '\n' */ + esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); + + /* Configure UART. Note that REF_TICK is used so that the baud rate remains + * correct while APB frequency is changing in light sleep mode. + */ + const uart_config_t uart_config = { + .baud_rate = dev_config->baud_rate, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .source_clk = UART_SCLK_REF_TICK, + }; + + uart_param_config(dev_config->channel, &uart_config); + uart_set_pin(dev_config->channel, dev_config->tx_gpio_num, dev_config->rx_gpio_num, -1, -1); + + /* Install UART driver for interrupt-driven reads and writes */ + ret = uart_driver_install(dev_config->channel, 256, 0, 0, NULL, 0); + if (ret != ESP_OK) { + goto _exit; + } + + /* Tell VFS to use UART driver */ + esp_vfs_dev_uart_use_driver(dev_config->channel); + + // initialize console, common part + ret = esp_console_common_init(&uart_repl->repl_com); + if (ret != ESP_OK) { + goto _exit; + } + + // setup history + ret = esp_console_setup_history(repl_config->history_save_path, repl_config->max_history_len, &uart_repl->repl_com); + if (ret != ESP_OK) { + goto _exit; + } + + // setup prompt + esp_console_setup_prompt(repl_config->prompt, &uart_repl->repl_com); + + /* spawn a single thread to run REPL */ + if (xTaskCreate(esp_console_repl_task, "console_repl", repl_config->task_stack_size, + &uart_repl->repl_com, repl_config->task_priority, &uart_repl->repl_com.task_hdl) != pdTRUE) { + ret = ESP_FAIL; + goto _exit; + } + + uart_repl->uart_channel = dev_config->channel; + uart_repl->repl_com.state = CONSOLE_REPL_STATE_INIT; + uart_repl->repl_com.repl_core.del = esp_console_repl_uart_delete; + *ret_repl = &uart_repl->repl_com.repl_core; + return ESP_OK; +_exit: + if (uart_repl) { + esp_console_deinit(); + uart_driver_delete(dev_config->channel); + free(uart_repl); + } + if (ret_repl) { + *ret_repl = NULL; + } + return ret; +} + +esp_err_t esp_console_start_repl(esp_console_repl_t *repl) +{ + esp_err_t ret = ESP_OK; + esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core); + // check if already initialized + if (repl_com->state != CONSOLE_REPL_STATE_INIT) { + ret = ESP_ERR_INVALID_STATE; + goto _exit; + } + + repl_com->state = CONSOLE_REPL_STATE_START; + xTaskNotifyGive(repl_com->task_hdl); + return ESP_OK; +_exit: + return ret; +} + +static esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com) +{ + /* set command line prompt */ + const char *prompt_temp = "esp>"; + if (prompt) { + prompt_temp = prompt; + } + snprintf(repl_com->prompt, CONSOLE_PROMPT_MAX_LEN - 1, LOG_COLOR_I "%s " LOG_RESET_COLOR, prompt_temp); + + printf("\r\n" + "Type 'help' to get the list of commands.\r\n" + "Use UP/DOWN arrows to navigate through command history.\r\n" + "Press TAB when typing command name to auto-complete.\r\n"); + + /* Figure out if the terminal supports escape sequences */ + int probe_status = linenoiseProbe(); + if (probe_status) { + /* zero indicates success */ + printf("\r\n" + "Your terminal application does not support escape sequences.\n\n" + "Line editing and history features are disabled.\n\n" + "On Windows, try using Putty instead.\r\n"); + linenoiseSetDumbMode(1); +#if CONFIG_LOG_COLORS + /* Since the terminal doesn't support escape sequences, + * don't use color codes in the s_prompt. + */ + snprintf(repl_com->prompt, CONSOLE_PROMPT_MAX_LEN - 1, "%s ", prompt_temp); +#endif //CONFIG_LOG_COLORS + } + + return ESP_OK; +} + +static esp_err_t esp_console_setup_history(const char *history_path, uint32_t max_history_len, esp_console_repl_com_t *repl_com) +{ + esp_err_t ret = ESP_OK; + + repl_com->history_save_path = history_path; + if (history_path) { + /* Load command history from filesystem */ + linenoiseHistoryLoad(history_path); + } + + /* Set command history size */ + if (linenoiseHistorySetMaxLen(max_history_len) != 1) { + ESP_LOGE(TAG, "set max history length to %d failed", max_history_len); + ret = ESP_FAIL; + goto _exit; + } + return ESP_OK; +_exit: + return ret; +} + +static esp_err_t esp_console_common_init(esp_console_repl_com_t *repl_com) +{ + esp_err_t ret = ESP_OK; + /* Initialize the console */ + esp_console_config_t console_config = ESP_CONSOLE_CONFIG_DEFAULT(); +#if CONFIG_LOG_COLORS + console_config.hint_color = atoi(LOG_COLOR_CYAN); +#endif + ret = esp_console_init(&console_config); + if (ret != ESP_OK) { + goto _exit; + } + + ret = esp_console_register_help_command(); + if (ret != ESP_OK) { + goto _exit; + } + + /* Configure linenoise line completion library */ + /* Enable multiline editing. If not set, long commands will scroll within single line */ + linenoiseSetMultiLine(1); + + /* Tell linenoise where to get command completions and hints */ + linenoiseSetCompletionCallback(&esp_console_get_completion); + linenoiseSetHintsCallback((linenoiseHintsCallback *)&esp_console_get_hint); + + return ESP_OK; +_exit: + return ret; +} + +static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl) +{ + esp_err_t ret = ESP_OK; + esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core); + esp_console_repl_uart_t *uart_repl = __containerof(repl_com, esp_console_repl_uart_t, repl_com); + // check if already de-initialized + if (repl_com->state == CONSOLE_REPL_STATE_DEINIT) { + ESP_LOGE(TAG, "already de-initialized"); + ret = ESP_ERR_INVALID_STATE; + goto _exit; + } + repl_com->state = CONSOLE_REPL_STATE_DEINIT; + esp_console_deinit(); + esp_vfs_dev_uart_use_nonblocking(uart_repl->uart_channel); + uart_driver_delete(uart_repl->uart_channel); + free(uart_repl); +_exit: + return ret; +} + +static void esp_console_repl_task(void *args) +{ + esp_console_repl_com_t *repl_com = (esp_console_repl_com_t *)args; // waiting for task notify ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - while (s_repl_state == CONSOLE_REPL_STATE_START) { - char *line = linenoise(s_prompt); + while (repl_com->state == CONSOLE_REPL_STATE_START) { + char *line = linenoise(repl_com->prompt); if (line == NULL) { ESP_LOGD(TAG, "empty line"); /* Ignore empty lines */ @@ -74,8 +281,8 @@ static void esp_console_repl_thread(void *param) /* Add the command to the history */ linenoiseHistoryAdd(line); /* Save command history to filesystem */ - if (s_history_save_path) { - linenoiseHistorySave(s_history_save_path); + if (repl_com->history_save_path) { + linenoiseHistorySave(repl_com->history_save_path); } /* Try to run the command */ @@ -96,199 +303,3 @@ static void esp_console_repl_thread(void *param) ESP_LOGD(TAG, "The End"); vTaskDelete(NULL); } - -esp_err_t esp_console_repl_init(const esp_console_repl_config_t *config) -{ - esp_err_t ret = ESP_OK; - if (!config) { - ret = ESP_ERR_INVALID_ARG; - goto _exit; - } - - // check if already initialized - if (s_repl_state != CONSOLE_REPL_STATE_DEINIT) { - ESP_LOGE(TAG, "already initialized"); - ret = ESP_ERR_INVALID_STATE; - goto _exit; - } - - /* Drain stdout before reconfiguring it */ - fflush(stdout); - fsync(fileno(stdout)); - - /* Disable buffering on stdin */ - setvbuf(stdin, NULL, _IONBF, 0); - - /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - /* Configure UART. Note that REF_TICK is used so that the baud rate remains - * correct while APB frequency is changing in light sleep mode. - */ - const uart_config_t uart_config = { - .baud_rate = config->device.uart.baud_rate, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .source_clk = UART_SCLK_REF_TICK, - }; - /* Install UART driver for interrupt-driven reads and writes */ - ret = uart_driver_install(config->device.uart.channel, 256, 0, 0, NULL, 0); - if (ret != ESP_OK) { - goto _exit; - } - s_uart_channel = config->device.uart.channel; - uart_param_config(s_uart_channel, &uart_config); - uart_set_pin(s_uart_channel, config->device.uart.tx_gpio, config->device.uart.rx_gpio, -1, -1); - - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(s_uart_channel); - - /* Initialize the console */ - esp_console_config_t console_config = ESP_CONSOLE_CONFIG_DEFAULT(); -#if CONFIG_LOG_COLORS - console_config.hint_color = atoi(LOG_COLOR_CYAN); -#endif - ret = esp_console_init(&console_config); - if (ret != ESP_OK) { - goto _console_del; - } - - ret = esp_console_register_help_command(); - if (ret != ESP_OK) { - goto _console_del; - } - - ret = esp_console_register_quit_command(); - if (ret != ESP_OK) { - goto _console_del; - } - - /* Configure linenoise line completion library */ - /* Enable multiline editing. If not set, long commands will scroll within single line */ - linenoiseSetMultiLine(1); - - /* Tell linenoise where to get command completions and hints */ - linenoiseSetCompletionCallback(&esp_console_get_completion); - linenoiseSetHintsCallback((linenoiseHintsCallback *)&esp_console_get_hint); - - if (config->history_save_path) { - s_history_save_path = config->history_save_path; - /* Load command history from filesystem */ - linenoiseHistoryLoad(s_history_save_path); - } - - /* Set command history size */ - if (linenoiseHistorySetMaxLen(config->max_history_len) != 1) { - ESP_LOGE(TAG, "set max history length to %d failed", config->max_history_len); - ret = ESP_FAIL; - goto _console_del; - } - - /* set command line prompt */ - const char *prompt_temp = "esp>"; - if (config->prompt) { - prompt_temp = config->prompt; - } - snprintf(s_prompt, CONSOLE_PROMPT_LEN_MAX - 1, LOG_COLOR_I "%s " LOG_RESET_COLOR, prompt_temp); - - printf("\r\n" - "Type 'help' to get the list of commands.\r\n" - "Use UP/DOWN arrows to navigate through command history.\r\n" - "Press TAB when typing command name to auto-complete.\r\n"); - - /* Figure out if the terminal supports escape sequences */ - int probe_status = linenoiseProbe(); - if (probe_status) { - /* zero indicates success */ - printf("\r\n" - "Your terminal application does not support escape sequences.\n\n" - "Line editing and history features are disabled.\n\n" - "On Windows, try using Putty instead.\r\n"); - linenoiseSetDumbMode(1); -#if CONFIG_LOG_COLORS - /* Since the terminal doesn't support escape sequences, - * don't use color codes in the s_prompt. - */ - snprintf(s_prompt, CONSOLE_PROMPT_LEN_MAX - 1, "%s ", prompt_temp); -#endif //CONFIG_LOG_COLORS - } - - /* spawn a single thread to run REPL */ - if (xTaskCreate(esp_console_repl_thread, "console_repl", config->task_stack_size, - NULL, config->task_priority, &s_repl_task_hdl) != pdTRUE) { - ret = ESP_FAIL; - goto _console_del; - } - s_repl_state = CONSOLE_REPL_STATE_INIT; - - return ret; - -_console_del: - esp_console_deinit(); - esp_vfs_dev_uart_use_nonblocking(s_uart_channel); - uart_driver_delete(s_uart_channel); - s_uart_channel = -1; - s_repl_state = CONSOLE_REPL_STATE_DEINIT; -_exit: - return ret; -} - -esp_err_t esp_console_repl_deinit(void) -{ - esp_err_t ret = ESP_OK; - - // check if already de-initialized - if (s_repl_state == CONSOLE_REPL_STATE_DEINIT) { - ESP_LOGE(TAG, "not initialized yet"); - ret = ESP_ERR_INVALID_STATE; - goto _exit; - } - - s_repl_state = CONSOLE_REPL_STATE_DEINIT; - esp_console_deinit(); - esp_vfs_dev_uart_use_nonblocking(s_uart_channel); - uart_driver_delete(s_uart_channel); - s_uart_channel = -1; - s_repl_task_hdl = NULL; - s_history_save_path = NULL; -_exit: - return ret; -} - -esp_err_t esp_console_repl_start(void) -{ - esp_err_t ret = ESP_OK; - - // check if already initialized - if (s_repl_state != CONSOLE_REPL_STATE_INIT) { - ret = ESP_ERR_INVALID_STATE; - goto _exit; - } - - s_repl_state = CONSOLE_REPL_STATE_START; - xTaskNotifyGive(s_repl_task_hdl); - -_exit: - return ret; -} - -/* handle 'quit' command */ -static int do_cmd_quit(int argc, char **argv) -{ - printf("ByeBye\r\n"); - esp_console_repl_deinit(); - return 0; -} - -esp_err_t esp_console_register_quit_command(void) -{ - esp_console_cmd_t command = { - .command = "quit", - .help = "Quit REPL environment", - .func = &do_cmd_quit - }; - return esp_console_cmd_register(&command); -} diff --git a/components/console/test/test_console.c b/components/console/test/test_console.c index 77b1a5ee1..b634a6c20 100644 --- a/components/console/test/test_console.c +++ b/components/console/test/test_console.c @@ -30,11 +30,30 @@ TEST_CASE("esp console init/deinit test", "[console]") TEST_ESP_OK(esp_console_deinit()); } +static esp_console_repl_t *s_repl = NULL; + +/* handle 'quit' command */ +static int do_cmd_quit(int argc, char **argv) +{ + printf("ByeBye\r\n"); + s_repl->del(s_repl); + return 0; +} + // Enter "quit" to exit REPL environment TEST_CASE("esp console repl test", "[console][ignore]") { esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); - TEST_ESP_OK(esp_console_repl_init(&repl_config)); - TEST_ESP_OK(esp_console_repl_start()); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl)); + + esp_console_cmd_t cmd = { + .command = "quit", + .help = "Quit REPL environment", + .func = &do_cmd_quit + }; + TEST_ESP_OK(esp_console_cmd_register(&cmd)); + + TEST_ESP_OK(esp_console_start_repl(s_repl)); vTaskDelay(pdMS_TO_TICKS(2000)); } diff --git a/docs/en/api-reference/system/console.rst b/docs/en/api-reference/system/console.rst index 273bf4a88..4b9bd0f23 100644 --- a/docs/en/api-reference/system/console.rst +++ b/docs/en/api-reference/system/console.rst @@ -148,9 +148,9 @@ Initialize console REPL environment To establish a basic REPL environment, ``console`` component provides several useful APIs, combining those functions described above. -In a typical application, you only need to call :cpp:func:`esp_console_repl_init` to initialize the REPL environment, including UART driver install, basic console configuration, spawning a thread to do REPL task and register several useful commands (e.g. `help`, `quit`). +In a typical application, you only need to call :cpp:func:`esp_console_new_repl_uart` to initialize the REPL environment based on UART device, including driver install, basic console configuration, spawning a thread to do REPL task and register several useful commands (e.g. `help`). -After that, you can register your own commands with :cpp:func:`esp_console_cmd_register`. The REPL environment keeps in init state until you call :cpp:func:`esp_console_repl_start`. +After that, you can register your own commands with :cpp:func:`esp_console_cmd_register`. The REPL environment keeps in init state until you call :cpp:func:`esp_console_start_repl`. Application Example ------------------- diff --git a/docs/zh_CN/api-reference/system/console.rst b/docs/zh_CN/api-reference/system/console.rst index d6ac05d77..a95ba64d7 100644 --- a/docs/zh_CN/api-reference/system/console.rst +++ b/docs/zh_CN/api-reference/system/console.rst @@ -162,9 +162,9 @@ Linenoise 库不需要显式地初始化,但是在调用行编辑函数之前 ``console`` 组建还提供了一些 API 来帮助创建一个基本的 REPL 环境。 -在一个典型的 console 应用中,你只需要调用 :cpp:func:`esp_console_repl_init`,它会为你初始化好 REPL 环境,其中包括安装 UART 驱动,基本的 console 配置,创建一个新的线程来执行 REPL 任务,注册一些基本的命令(比如 `help` 和 `quit` 命令)。 +在一个典型的 console 应用中,你只需要调用 :cpp:func:`esp_console_new_repl_uart`,它会为你初始化好构建在 UART 基础上的 REPL 环境,其中包括安装 UART 驱动,基本的 console 配置,创建一个新的线程来执行 REPL 任务,注册一些基本的命令(比如 `help` 命令)。 -完了之后你可以使用 :cpp:func:`esp_console_cmd_register` 来注册其它命令。REPL 环境在初始化后需要再调用 :cpp:func:`esp_console_repl_start` 函数才能开始运行。 +完了之后你可以使用 :cpp:func:`esp_console_cmd_register` 来注册其它命令。REPL 环境在初始化后需要再调用 :cpp:func:`esp_console_start_repl` 函数才能开始运行。 应用程序示例 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_node/main/ble_mesh_console_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_node/main/ble_mesh_console_main.c index 9fef35d82..e0277f6af 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_node/main/ble_mesh_console_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_node/main/ble_mesh_console_main.c @@ -91,14 +91,16 @@ void app_main(void) printf("esp32_bluetooth_init failed (ret %d)", res); } + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); - const char* prompt = LOG_COLOR_I "esp32> " LOG_RESET_COLOR; - repl_config.prompt = prompt; + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); #if CONFIG_STORE_HISTORY initialize_filesystem(); - repl_config.his_save_path = HISTORY_PATH; + repl_config.history_save_path = HISTORY_PATH; #endif - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + repl_config.prompt = "ble_mesh_node>"; + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); /* Register commands */ register_system(); @@ -110,5 +112,5 @@ void app_main(void) #endif // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(repl)); } diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_console_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_console_main.c index d11abf9fc..2543bbc65 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_console_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner/main/ble_mesh_console_main.c @@ -95,15 +95,16 @@ void app_main(void) printf("esp32_bluetooth_init failed (ret %d)", res); } + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); - const char* prompt = LOG_COLOR_I "esp32> " LOG_RESET_COLOR; - repl_config.prompt = prompt; + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); #if CONFIG_STORE_HISTORY initialize_filesystem(); - repl_config.his_save_path = HISTORY_PATH; + repl_config.history_save_path = HISTORY_PATH; #endif + repl_config.prompt = "ble_mesh_prov>"; // init console REPL environment - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); /* Register commands */ register_system(); @@ -121,5 +122,5 @@ void app_main(void) #endif // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(repl)); } diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/main.c index 2689ec057..e9111da85 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/main/main.c @@ -141,9 +141,9 @@ static esp_ble_mesh_model_t root_models[] = { static esp_ble_mesh_model_t vnd_models[] = { ESP_BLE_MESH_VENDOR_MODEL(CID_ESP, ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_SRV, - fast_prov_srv_op, NULL, &fast_prov_server), + fast_prov_srv_op, NULL, &fast_prov_server), ESP_BLE_MESH_VENDOR_MODEL(CID_ESP, ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_CLI, - fast_prov_cli_op, NULL, &fast_prov_client), + fast_prov_cli_op, NULL, &fast_prov_client), }; static esp_ble_mesh_elem_t elements[] = { @@ -249,7 +249,7 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint return; } if (fast_prov_server.node_addr_cnt != FAST_PROV_NODE_COUNT_MIN && - fast_prov_server.node_addr_cnt <= fast_prov_server.max_node_num) { + fast_prov_server.node_addr_cnt <= fast_prov_server.max_node_num) { if (bt_mesh_atomic_test_and_clear_bit(fast_prov_server.srv_flags, GATT_PROXY_ENABLE_START)) { k_delayed_work_cancel(&fast_prov_server.gatt_proxy_enable_timer); } @@ -355,7 +355,7 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT"); node_prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr, - param->node_prov_complete.flags, param->node_prov_complete.iv_index); + param->node_prov_complete.flags, param->node_prov_complete.iv_index); break; case ESP_BLE_MESH_NODE_PROXY_GATT_DISABLE_COMP_EVT: ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROXY_GATT_DISABLE_COMP_EVT"); @@ -665,7 +665,7 @@ static void example_ble_mesh_config_server_cb(esp_ble_mesh_cfg_server_cb_event_t err = example_handle_config_app_key_add_evt(param->value.state_change.appkey_add.app_idx); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to bind app_idx 0x%04x with non-config models", - __func__, param->value.state_change.appkey_add.app_idx); + __func__, param->value.state_change.appkey_add.app_idx); return; } break; @@ -679,16 +679,16 @@ static void example_ble_mesh_config_server_cb(esp_ble_mesh_cfg_server_cb_event_t } static void example_ble_mesh_generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event, - esp_ble_mesh_generic_server_cb_param_t *param) + esp_ble_mesh_generic_server_cb_param_t *param) { ESP_LOGI(TAG, "event 0x%02x, opcode 0x%04x, src 0x%04x, dst 0x%04x", - event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst); + event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst); switch (event) { case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT: ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT"); if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET || - param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) { + param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) { ESP_LOGI(TAG, "onoff 0x%02x", param->value.state_change.onoff_set.onoff); example_change_led_state(param->value.state_change.onoff_set.onoff); } @@ -748,9 +748,11 @@ static void wifi_console_init(void) { initialise_wifi(); + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); // init console REPL environment - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); /* Register commands */ register_wifi(); @@ -766,7 +768,7 @@ static void wifi_console_init(void) printf(" =================================================\n\n"); // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(repl)); } void app_main(void) diff --git a/examples/ethernet/iperf/main/ethernet_example_main.c b/examples/ethernet/iperf/main/ethernet_example_main.c index b2633eddd..49b9c2c46 100644 --- a/examples/ethernet/iperf/main/ethernet_example_main.c +++ b/examples/ethernet/iperf/main/ethernet_example_main.c @@ -40,13 +40,16 @@ static void initialize_filesystem(void) void app_main(void) { + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); #if CONFIG_EXAMPLE_STORE_HISTORY initialize_filesystem(); repl_config.history_save_path = HISTORY_PATH; #endif - // initialize console REPL environment - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + repl_config.prompt = "iperf>"; + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); /* Register commands */ register_system(); @@ -64,5 +67,5 @@ void app_main(void) printf(" =======================================================\n\n"); // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(repl)); } diff --git a/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c b/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c index 287e52014..23cad5a87 100644 --- a/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c +++ b/examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c @@ -40,14 +40,16 @@ static void initialize_filesystem(void) void app_main(void) { + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); #if CONFIG_EXAMPLE_STORE_HISTORY initialize_filesystem(); repl_config.history_save_path = HISTORY_PATH; #endif repl_config.prompt = "i2c-tools>"; - // initialize console REPL environment - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); register_i2ctools(); register_system(); @@ -65,5 +67,5 @@ void app_main(void) printf(" ==============================================================\n\n"); // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(repl)); } diff --git a/examples/protocols/icmp_echo/main/echo_example_main.c b/examples/protocols/icmp_echo/main/echo_example_main.c index b13793cd9..5750749ac 100644 --- a/examples/protocols/icmp_echo/main/echo_example_main.c +++ b/examples/protocols/icmp_echo/main/echo_example_main.c @@ -75,7 +75,7 @@ static struct { struct arg_int *tos; struct arg_str *host; struct arg_end *end; -} ping_args;; +} ping_args; static int do_ping_cmd(int argc, char **argv) { @@ -161,6 +161,26 @@ static void register_ping(void) ESP_ERROR_CHECK(esp_console_cmd_register(&ping_cmd)); } +static esp_console_repl_t *s_repl = NULL; + +/* handle 'quit' command */ +static int do_cmd_quit(int argc, char **argv) +{ + printf("ByeBye\r\n"); + s_repl->del(s_repl); + return 0; +} + +static esp_err_t register_quit(void) +{ + esp_console_cmd_t command = { + .command = "quit", + .help = "Quit REPL environment", + .func = &do_cmd_quit + }; + return esp_console_cmd_register(&command); +} + void app_main(void) { ESP_ERROR_CHECK(nvs_flash_init()); @@ -170,12 +190,15 @@ void app_main(void) ESP_ERROR_CHECK(example_connect()); esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); // init console REPL environment - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl)); /* register command `ping` */ register_ping(); + /* register command `quit` */ + register_quit(); // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(s_repl)); } diff --git a/examples/wifi/iperf/main/iperf_example_main.c b/examples/wifi/iperf/main/iperf_example_main.c index 9979cbd1e..873024d76 100644 --- a/examples/wifi/iperf/main/iperf_example_main.c +++ b/examples/wifi/iperf/main/iperf_example_main.c @@ -27,10 +27,12 @@ void app_main(void) initialise_wifi(); + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); repl_config.prompt = "iperf>"; - // init console REPL - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); /* Register commands */ register_system(); register_wifi(); @@ -46,6 +48,6 @@ void app_main(void) printf(" =================================================\n\n"); // start console REPL - ESP_ERROR_CHECK(esp_console_repl_start()); + ESP_ERROR_CHECK(esp_console_start_repl(repl)); } diff --git a/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c b/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c index 2853a4be8..fe95e2e34 100644 --- a/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c +++ b/examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c @@ -179,15 +179,16 @@ void app_main(void) /* Initialize WiFi */ initialize_wifi(); + esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); #if CONFIG_SNIFFER_STORE_HISTORY initialize_filesystem(); repl_config.history_save_path = HISTORY_FILE_PATH; #endif repl_config.prompt = "sniffer>"; - /* Initialize Console REPL environment */ - ESP_ERROR_CHECK(esp_console_repl_init(&repl_config)); - + // init console REPL environment + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); /* Register commands */ #if CONFIG_SNIFFER_PCAP_DESTINATION_SD @@ -207,5 +208,6 @@ void app_main(void) printf(" | |\n"); printf(" =======================================================\n\n"); - ESP_ERROR_CHECK(esp_console_repl_start()); + // start console REPL + ESP_ERROR_CHECK(esp_console_start_repl(repl)); }