Explorar el Código

console_repl: change config structure to support different devices

morris hace 5 años
padre
commit
29f8aecfc0

+ 68 - 65
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
 }

+ 171 - 160
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 <stdint.h>
 #include <stdio.h>
+#include <sys/cdefs.h>
 #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,81 +35,37 @@ typedef enum {
     CONSOLE_REPL_STATE_START,
 } repl_state_t;
 
-static repl_state_t s_repl_state =  CONSOLE_REPL_STATE_DEINIT;
-
-/**
- * @brief Prompt to be printed before each line.
- *
- */
-static char s_prompt[CONSOLE_PROMPT_LEN_MAX];
-
-/**
- * @brief path to save history commands in file system
- *
- */
-static const char *s_history_save_path = NULL;
-
-/**
- * @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)
-{
-    // waiting for task notify
-    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
-    while (s_repl_state == CONSOLE_REPL_STATE_START) {
-        char *line = linenoise(s_prompt);
-        if (line == NULL) {
-            ESP_LOGD(TAG, "empty line");
-            /* Ignore empty lines */
-            continue;
-        }
-        /* Add the command to the history */
-        linenoiseHistoryAdd(line);
-        /* Save command history to filesystem */
-        if (s_history_save_path) {
-            linenoiseHistorySave(s_history_save_path);
-        }
-
-        /* Try to run the command */
-        int ret;
-        esp_err_t err = esp_console_run(line, &ret);
-        if (err == ESP_ERR_NOT_FOUND) {
-            printf("Unrecognized command\n");
-        } else if (err == ESP_ERR_INVALID_ARG) {
-            // command was empty
-        } else if (err == ESP_OK && ret != ESP_OK) {
-            printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
-        } else if (err != ESP_OK) {
-            printf("Internal error: %s\n", esp_err_to_name(err));
-        }
-        /* linenoise allocates line buffer on the heap, so need to free it */
-        linenoiseFree(line);
-    }
-    ESP_LOGD(TAG, "The End");
-    vTaskDelete(NULL);
-}
-
-esp_err_t esp_console_repl_init(const esp_console_repl_config_t *config)
+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;
+
+typedef struct {
+    esp_console_repl_com_t repl_com; // base class
+    int uart_channel;                // uart channel number
+} esp_console_repl_uart_t;
+
+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);
+
+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;
-    if (!config) {
+    esp_console_repl_uart_t *uart_repl = NULL;
+    if (!repl_config | !dev_config | !ret_repl) {
         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;
+    // 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;
     }
 
@@ -128,71 +85,89 @@ esp_err_t esp_console_repl_init(const esp_console_repl_config_t *config)
      * correct while APB frequency is changing in light sleep mode.
      */
     const uart_config_t uart_config = {
-        .baud_rate = config->device.uart.baud_rate,
+        .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(config->device.uart.channel, 256, 0, 0, NULL, 0);
+    ret = uart_driver_install(dev_config->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);
+    esp_vfs_dev_uart_use_driver(dev_config->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);
+    // initialize console, common part
+    ret = esp_console_common_init(&uart_repl->repl_com);
     if (ret != ESP_OK) {
-        goto _console_del;
-    }
-
-    ret = esp_console_register_help_command();
-    if (ret != ESP_OK) {
-        goto _console_del;
+        goto _exit;
     }
 
-    ret = esp_console_register_quit_command();
+    // 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 _console_del;
+        goto _exit;
     }
 
-    /* Configure linenoise line completion library */
-    /* Enable multiline editing. If not set, long commands will scroll within single line */
-    linenoiseSetMultiLine(1);
+    // setup prompt
+    esp_console_setup_prompt(repl_config->prompt, &uart_repl->repl_com);
 
-    /* Tell linenoise where to get command completions and hints */
-    linenoiseSetCompletionCallback(&esp_console_get_completion);
-    linenoiseSetHintsCallback((linenoiseHintsCallback *)&esp_console_get_hint);
+    /* 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;
+    }
 
-    if (config->history_save_path) {
-        s_history_save_path = config->history_save_path;
-        /* Load command history from filesystem */
-        linenoiseHistoryLoad(s_history_save_path);
+    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;
+}
 
-    /* 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;
+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 (config->prompt) {
-        prompt_temp = config->prompt;
+    if (prompt) {
+        prompt_temp = prompt;
     }
-    snprintf(s_prompt, CONSOLE_PROMPT_LEN_MAX - 1, LOG_COLOR_I "%s " LOG_RESET_COLOR, prompt_temp);
+    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"
@@ -212,83 +187,119 @@ esp_err_t esp_console_repl_init(const esp_console_repl_config_t *config)
         /* 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);
+        snprintf(repl_com->prompt, CONSOLE_PROMPT_MAX_LEN - 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 ESP_OK;
+}
 
-    return ret;
+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;
 
-_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;
+    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;
 }
 
-esp_err_t esp_console_repl_deinit(void)
+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;
+    }
 
-    // check if already de-initialized
-    if (s_repl_state == CONSOLE_REPL_STATE_DEINIT) {
-        ESP_LOGE(TAG, "not initialized yet");
-        ret = ESP_ERR_INVALID_STATE;
+    ret = esp_console_register_help_command();
+    if (ret != ESP_OK) {
         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;
+    /* 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;
 }
 
-esp_err_t esp_console_repl_start(void)
+static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl)
 {
     esp_err_t ret = ESP_OK;
-
-    // check if already initialized
-    if (s_repl_state != CONSOLE_REPL_STATE_INIT) {
+    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;
     }
-
-    s_repl_state = CONSOLE_REPL_STATE_START;
-    xTaskNotifyGive(s_repl_task_hdl);
-
+    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;
 }
 
-/* handle 'quit' command */
-static int do_cmd_quit(int argc, char **argv)
+static void esp_console_repl_task(void *args)
 {
-    printf("ByeBye\r\n");
-    esp_console_repl_deinit();
-    return 0;
-}
+    esp_console_repl_com_t *repl_com = (esp_console_repl_com_t *)args;
+    // waiting for task notify
+    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
+    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 */
+            continue;
+        }
+        /* Add the command to the history */
+        linenoiseHistoryAdd(line);
+        /* Save command history to filesystem */
+        if (repl_com->history_save_path) {
+            linenoiseHistorySave(repl_com->history_save_path);
+        }
 
-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);
+        /* Try to run the command */
+        int ret;
+        esp_err_t err = esp_console_run(line, &ret);
+        if (err == ESP_ERR_NOT_FOUND) {
+            printf("Unrecognized command\n");
+        } else if (err == ESP_ERR_INVALID_ARG) {
+            // command was empty
+        } else if (err == ESP_OK && ret != ESP_OK) {
+            printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
+        } else if (err != ESP_OK) {
+            printf("Internal error: %s\n", esp_err_to_name(err));
+        }
+        /* linenoise allocates line buffer on the heap, so need to free it */
+        linenoiseFree(line);
+    }
+    ESP_LOGD(TAG, "The End");
+    vTaskDelete(NULL);
 }

+ 21 - 2
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));
 }

+ 2 - 2
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
 -------------------

+ 2 - 2
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` 函数才能开始运行。
 
 
 应用程序示例

+ 7 - 5
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));
 }

+ 6 - 5
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));
 }

+ 12 - 10
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)

+ 6 - 3
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));
 }

+ 5 - 3
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));
 }

+ 26 - 3
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));
 }

+ 5 - 3
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));
 }
 

+ 6 - 4
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));
 }