mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(console): Move IO initialization outside of the console component
- Move the linux repl chip and deprecate chip related functions - Update location of driver specific default config - Add missing comments on the newly added functions in the affected components.
This commit is contained in:
@@ -8,13 +8,12 @@ set(srcs "commands.c"
|
|||||||
"split_argv.c"
|
"split_argv.c"
|
||||||
"linenoise/linenoise.c")
|
"linenoise/linenoise.c")
|
||||||
|
|
||||||
set(requires vfs)
|
set(requires vfs esp_stdio)
|
||||||
|
|
||||||
if(${target} STREQUAL "linux")
|
if(${target} STREQUAL "linux")
|
||||||
list(APPEND srcs "esp_console_repl_linux.c" "esp_console_repl_internal.c")
|
list(APPEND srcs "esp_console_repl_internal.c")
|
||||||
else()
|
else()
|
||||||
list(APPEND srcs "esp_console_repl_chip.c")
|
list(APPEND srcs "esp_console_repl_chip.c")
|
||||||
list(APPEND requires esp_stdio)
|
|
||||||
if(CONFIG_VFS_SUPPORT_SELECT)
|
if(CONFIG_VFS_SUPPORT_SELECT)
|
||||||
list(APPEND srcs "esp_console_repl_internal.c")
|
list(APPEND srcs "esp_console_repl_internal.c")
|
||||||
endif()
|
endif()
|
||||||
@@ -35,16 +34,15 @@ set(argtable_srcs argtable3/arg_cmd.c
|
|||||||
argtable3/arg_utils.c
|
argtable3/arg_utils.c
|
||||||
argtable3/argtable3.c)
|
argtable3/argtable3.c)
|
||||||
|
|
||||||
|
# TODO IDF-14810: Remove io_requires dependency
|
||||||
|
if(NOT ${target} STREQUAL "linux")
|
||||||
|
set(io_requires esp_driver_uart esp_driver_usb_serial_jtag esp_usb_cdc_rom_console)
|
||||||
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs} ${argtable_srcs}
|
||||||
${argtable_srcs}
|
|
||||||
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
|
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
PRIV_INCLUDE_DIRS private_include
|
PRIV_INCLUDE_DIRS private_include
|
||||||
REQUIRES "${requires}"
|
REQUIRES ${requires} ${io_requires})
|
||||||
PRIV_REQUIRES esp_driver_uart
|
|
||||||
esp_driver_usb_serial_jtag
|
|
||||||
esp_usb_cdc_rom_console
|
|
||||||
)
|
|
||||||
|
|
||||||
if(CONFIG_LIBC_PICOLIBC)
|
if(CONFIG_LIBC_PICOLIBC)
|
||||||
list(APPEND srcs_include_stdio_private ${srcs})
|
list(APPEND srcs_include_stdio_private ${srcs})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2016-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -14,7 +14,7 @@ extern "C" {
|
|||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "soc/uart_pins.h"
|
#include "esp_stdio.h"
|
||||||
|
|
||||||
// Forward declaration. Definition in linenoise/linenoise.h.
|
// Forward declaration. Definition in linenoise/linenoise.h.
|
||||||
typedef struct linenoiseCompletions linenoiseCompletions;
|
typedef struct linenoiseCompletions linenoiseCompletions;
|
||||||
@@ -72,65 +72,6 @@ typedef struct {
|
|||||||
.max_cmdline_length = 0, \
|
.max_cmdline_length = 0, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
/**
|
|
||||||
* @brief Parameters for console device: UART
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
int channel; //!< UART channel number (count from zero)
|
|
||||||
int baud_rate; //!< Communication 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;
|
|
||||||
|
|
||||||
#if 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 >= 0) ? CONFIG_ESP_CONSOLE_UART_TX_GPIO : U0TXD_GPIO_NUM, \
|
|
||||||
.rx_gpio_num = (CONFIG_ESP_CONSOLE_UART_RX_GPIO >= 0) ? CONFIG_ESP_CONSOLE_UART_RX_GPIO : U0RXD_GPIO_NUM, \
|
|
||||||
}
|
|
||||||
#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 // CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
|
||||||
/**
|
|
||||||
* @brief Parameters for console device: USB CDC
|
|
||||||
*
|
|
||||||
* @note It's an empty structure for now, reserved for future
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
} esp_console_dev_usb_cdc_config_t;
|
|
||||||
|
|
||||||
#define ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT() {}
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
|
||||||
/**
|
|
||||||
* @brief Parameters for console device: USB-SERIAL-JTAG
|
|
||||||
*
|
|
||||||
* @note It's an empty structure for now, reserved for future
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
} esp_console_dev_usb_serial_jtag_config_t;
|
|
||||||
|
|
||||||
#define ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT() {}
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_CONSOLE_HELP_VERBOSE_LEVEL_0 = 0,
|
ESP_CONSOLE_HELP_VERBOSE_LEVEL_0 = 0,
|
||||||
ESP_CONSOLE_HELP_VERBOSE_LEVEL_1 = 1,
|
ESP_CONSOLE_HELP_VERBOSE_LEVEL_1 = 1,
|
||||||
@@ -377,7 +318,13 @@ struct esp_console_repl_s {
|
|||||||
esp_err_t (*del)(esp_console_repl_t *repl);
|
esp_err_t (*del)(esp_console_repl_t *repl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
|
/* TODO IDF-14810: Remove the whole section under the #if */
|
||||||
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
||||||
|
#include "driver/esp_private/uart_vfs.h"
|
||||||
|
#include "driver/uart_vfs.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Establish a console REPL environment over UART driver
|
* @brief Establish a console REPL environment over UART driver
|
||||||
*
|
*
|
||||||
@@ -399,10 +346,17 @@ struct esp_console_repl_s {
|
|||||||
* - ESP_OK on success
|
* - ESP_OK on success
|
||||||
* - ESP_FAIL Parameter error
|
* - ESP_FAIL Parameter error
|
||||||
*/
|
*/
|
||||||
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 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);
|
||||||
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
||||||
|
|
||||||
|
/* TODO IDF-14810: Remove the whole section under the #if */
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
#if CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
||||||
|
|
||||||
|
#include "esp_private/esp_vfs_cdcacm.h"
|
||||||
|
#include "esp_vfs_cdcacm.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Establish a console REPL environment over USB CDC
|
* @brief Establish a console REPL environment over USB CDC
|
||||||
*
|
*
|
||||||
@@ -422,10 +376,17 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
|||||||
* - ESP_OK on success
|
* - ESP_OK on success
|
||||||
* - ESP_FAIL Parameter error
|
* - ESP_FAIL Parameter error
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl);
|
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config,
|
||||||
|
const esp_console_repl_config_t *repl_config,
|
||||||
|
esp_console_repl_t **ret_repl);
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
#endif // CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
||||||
|
|
||||||
|
/* TODO IDF-14810: Remove the whole section under the #if */
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
||||||
|
|
||||||
|
#include "driver/esp_private/usb_serial_jtag_vfs.h"
|
||||||
|
#include "driver/usb_serial_jtag_vfs.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Establish a console REPL (Read-eval-print loop) environment over USB-SERIAL-JTAG
|
* @brief Establish a console REPL (Read-eval-print loop) environment over USB-SERIAL-JTAG
|
||||||
*
|
*
|
||||||
@@ -445,9 +406,39 @@ esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *d
|
|||||||
* - ESP_OK on success
|
* - ESP_OK on success
|
||||||
* - ESP_FAIL Parameter error
|
* - ESP_FAIL Parameter error
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl);
|
esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config,
|
||||||
|
const esp_console_repl_config_t *repl_config,
|
||||||
|
esp_console_repl_t **ret_repl);
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
||||||
|
|
||||||
|
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a new console REPL instance that uses the active stdio driver.
|
||||||
|
*
|
||||||
|
* This sets up a Read-Eval-Print-Loop (REPL) environment where user input and
|
||||||
|
* output are handled through the configured stdio backend. This allows the
|
||||||
|
* console shell to operate over UART, USB, or another configured console port
|
||||||
|
* without requiring backend-specific setup in user code.
|
||||||
|
*
|
||||||
|
* @param repl_config Pointer to the REPL configuration structure.
|
||||||
|
* @param ret_repl Output pointer that will be assigned the created REPL instance.
|
||||||
|
* @return ESP_OK if the REPL instance was created successfully, or an error code if creation failed.
|
||||||
|
*/
|
||||||
|
esp_err_t esp_console_new_repl_stdio(const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroy and clean up a stdio-based console REPL instance.
|
||||||
|
*
|
||||||
|
* This releases resources associated with a REPL created using
|
||||||
|
* esp_console_new_repl_stdio. Call this when the REPL is no longer required or
|
||||||
|
* before replacing it with another console interface.
|
||||||
|
*
|
||||||
|
* @param repl Pointer to the REPL instance to delete.
|
||||||
|
* @return ESP_OK if the REPL instance was deleted successfully, or an error code on failure.
|
||||||
|
*/
|
||||||
|
esp_err_t esp_console_delete_repl_stdio(esp_console_repl_t *repl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start REPL environment
|
* @brief Start REPL environment
|
||||||
* @param[in] repl REPL handle returned from esp_console_new_repl_xxx
|
* @param[in] repl REPL handle returned from esp_console_new_repl_xxx
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include <sys/cdefs.h> // __containerof
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "console_private.h"
|
#include "console_private.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "linenoise/linenoise.h"
|
#include "linenoise/linenoise.h"
|
||||||
|
#include "esp_stdio.h"
|
||||||
|
|
||||||
#include "esp_vfs_eventfd.h"
|
#include "esp_vfs_eventfd.h"
|
||||||
#if CONFIG_IDF_TARGET_LINUX
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
@@ -20,6 +20,96 @@
|
|||||||
|
|
||||||
static const char *TAG = "console.common";
|
static const char *TAG = "console.common";
|
||||||
|
|
||||||
|
void esp_console_repl_task(void *args)
|
||||||
|
{
|
||||||
|
esp_console_repl_universal_t *repl_conf = (esp_console_repl_universal_t *) args;
|
||||||
|
esp_console_repl_com_t *repl_com = &repl_conf->repl_com;
|
||||||
|
|
||||||
|
/* Waiting for task notify. This happens when `esp_console_start_repl()`
|
||||||
|
* function is called. */
|
||||||
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
|
||||||
|
if (repl_com->state_mux != NULL) {
|
||||||
|
xSemaphoreTake(repl_com->state_mux, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change standard input and output of the task if the requested UART is
|
||||||
|
* NOT the default one. This block will replace stdin, stdout and stderr.
|
||||||
|
*/
|
||||||
|
#if CONFIG_LIBC_PICOLIBC
|
||||||
|
// TODO IDF-14901
|
||||||
|
if (repl_com->_stdin) {
|
||||||
|
stdin = repl_com->_stdin;
|
||||||
|
stdout = stderr = repl_com->_stdout;
|
||||||
|
} else {
|
||||||
|
linenoise_init_with_global_stdio();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#if !CONFIG_IDF_TARGET_LINUX
|
||||||
|
esp_console_setup_standard_stream(repl_conf->dev_config);
|
||||||
|
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||||
|
#endif // CONFIG_LIBC_PICOLIBC
|
||||||
|
|
||||||
|
/* Disable buffering on stdin of the current task.
|
||||||
|
* If the console is ran on a different UART than the default one,
|
||||||
|
* buffering shall only be disabled for the current one. */
|
||||||
|
setvbuf(stdin, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
/* This message shall be printed here and not earlier as the stdout
|
||||||
|
* has just been set above. */
|
||||||
|
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");
|
||||||
|
|
||||||
|
if (linenoiseIsDumbMode()) {
|
||||||
|
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 Windows Terminal or Putty instead.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_LIBC_PICOLIBC
|
||||||
|
linenoise_close_stdio();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (repl_com->state_mux != NULL) {
|
||||||
|
xSemaphoreGive(repl_com->state_mux);
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "The End");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com)
|
esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *repl_com)
|
||||||
{
|
{
|
||||||
/* set command line prompt */
|
/* set command line prompt */
|
||||||
@@ -60,8 +150,6 @@ esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *r
|
|||||||
|
|
||||||
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_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;
|
repl_com->history_save_path = history_path;
|
||||||
if (history_path) {
|
if (history_path) {
|
||||||
/* Load command history from filesystem */
|
/* Load command history from filesystem */
|
||||||
@@ -71,12 +159,9 @@ esp_err_t esp_console_setup_history(const char *history_path, uint32_t max_histo
|
|||||||
/* Set command history size */
|
/* Set command history size */
|
||||||
if (linenoiseHistorySetMaxLen(max_history_len) != 1) {
|
if (linenoiseHistorySetMaxLen(max_history_len) != 1) {
|
||||||
ESP_LOGE(TAG, "set max history length to %"PRIu32" failed", max_history_len);
|
ESP_LOGE(TAG, "set max history length to %"PRIu32" failed", max_history_len);
|
||||||
ret = ESP_FAIL;
|
return ESP_FAIL;
|
||||||
goto _exit;
|
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak)) esp_err_t esp_console_internal_set_event_fd(esp_console_repl_com_t *repl_com)
|
__attribute__((weak)) esp_err_t esp_console_internal_set_event_fd(esp_console_repl_com_t *repl_com)
|
||||||
@@ -103,12 +188,12 @@ esp_err_t esp_console_common_init(size_t max_cmdline_length, esp_console_repl_co
|
|||||||
#endif
|
#endif
|
||||||
ret = esp_console_init(&console_config);
|
ret = esp_console_init(&console_config);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
goto _exit;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = esp_console_register_help_command();
|
ret = esp_console_register_help_command();
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
goto _exit;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure linenoise line completion library */
|
/* Configure linenoise line completion library */
|
||||||
@@ -119,16 +204,21 @@ esp_err_t esp_console_common_init(size_t max_cmdline_length, esp_console_repl_co
|
|||||||
linenoiseSetCompletionCallback(&esp_console_get_completion);
|
linenoiseSetCompletionCallback(&esp_console_get_completion);
|
||||||
linenoiseSetHintsCallback((linenoiseHintsCallback *)&esp_console_get_hint);
|
linenoiseSetHintsCallback((linenoiseHintsCallback *)&esp_console_get_hint);
|
||||||
|
|
||||||
|
/* set the maximum command line length. the function returns -1 or
|
||||||
|
* 0 so it is ok to cast it to esp_err_t here. */
|
||||||
|
ret = linenoiseSetMaxLineLen(repl_com->max_cmdline_length);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#if CONFIG_VFS_SUPPORT_SELECT || CONFIG_IDF_TARGET_LINUX
|
#if CONFIG_VFS_SUPPORT_SELECT || CONFIG_IDF_TARGET_LINUX
|
||||||
ret = esp_console_internal_set_event_fd(repl_com);
|
ret = esp_console_internal_set_event_fd(repl_com);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
goto _exit;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak)) esp_err_t esp_console_common_deinit(esp_console_repl_com_t *repl_com)
|
__attribute__((weak)) esp_err_t esp_console_common_deinit(esp_console_repl_com_t *repl_com)
|
||||||
@@ -151,116 +241,109 @@ __attribute__((weak)) esp_err_t esp_console_common_deinit(esp_console_repl_com_t
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_console_start_repl(esp_console_repl_t *repl)
|
esp_err_t esp_console_delete_repl_stdio(esp_console_repl_t *repl)
|
||||||
|
{
|
||||||
|
esp_console_repl_com_t *repl_com = (esp_console_repl_com_t*)repl;
|
||||||
|
esp_console_repl_universal_t *universal_repl = (esp_console_repl_universal_t*)repl_com;
|
||||||
|
|
||||||
|
const esp_err_t ret = esp_console_common_deinit(repl_com);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
if (ret == ESP_ERR_INVALID_STATE) {
|
||||||
|
ESP_LOGE(TAG, "already de-initialized");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_console_deinit();
|
||||||
|
|
||||||
|
esp_stdio_uninstall_io_driver();
|
||||||
|
|
||||||
|
free(universal_repl);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_console_new_repl_stdio(const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
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_universal_t *universal_repl = NULL;
|
||||||
|
if (!repl_config || !ret_repl) {
|
||||||
|
ret = ESP_ERR_INVALID_ARG;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate memory for console REPL context
|
||||||
|
universal_repl = calloc(1, sizeof(esp_console_repl_universal_t));
|
||||||
|
if (!universal_repl) {
|
||||||
|
ret = ESP_ERR_NO_MEM;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drain stdout before reconfiguring it */
|
||||||
|
fflush(stdout);
|
||||||
|
fsync(fileno(stdout));
|
||||||
|
|
||||||
|
/* the IO related initialization will be performed within the task
|
||||||
|
* created to run esp_console_repl_task */
|
||||||
|
|
||||||
|
/* initialize console, common part */
|
||||||
|
ret = esp_console_common_init(repl_config->max_cmdline_length,
|
||||||
|
&universal_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, &universal_repl->repl_com);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup prompt */
|
||||||
|
ret = esp_console_setup_prompt(repl_config->prompt, &universal_repl->repl_com);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = esp_stdio_install_io_driver();
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill the structure here as it will be used directly by the created task. */
|
||||||
|
universal_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||||
|
universal_repl->repl_com.repl_core.del = esp_console_delete_repl_stdio;
|
||||||
|
|
||||||
|
/* Spawn a single thread to run REPL, we need to pass `universal_repl` to it as
|
||||||
|
* it also requires the uart channel. */
|
||||||
|
if (xTaskCreatePinnedToCore(esp_console_repl_task, "console_repl", repl_config->task_stack_size,
|
||||||
|
universal_repl, repl_config->task_priority, &universal_repl->repl_com.task_hdl, repl_config->task_core_id) != pdTRUE) {
|
||||||
|
ret = ESP_FAIL;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_repl = &universal_repl->repl_com.repl_core;
|
||||||
|
return ESP_OK;
|
||||||
|
_exit:
|
||||||
|
if (universal_repl) {
|
||||||
|
esp_console_deinit();
|
||||||
|
free(universal_repl);
|
||||||
|
}
|
||||||
|
if (ret_repl) {
|
||||||
|
*ret_repl = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_console_start_repl(esp_console_repl_t *repl)
|
||||||
|
{
|
||||||
|
esp_console_repl_com_t *repl_com = (esp_console_repl_com_t*)repl;
|
||||||
// check if already initialized
|
// check if already initialized
|
||||||
if (repl_com->state != CONSOLE_REPL_STATE_INIT) {
|
if (repl_com->state != CONSOLE_REPL_STATE_INIT) {
|
||||||
ret = ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
goto _exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repl_com->state = CONSOLE_REPL_STATE_START;
|
repl_com->state = CONSOLE_REPL_STATE_START;
|
||||||
xTaskNotifyGive(repl_com->task_hdl);
|
xTaskNotifyGive(repl_com->task_hdl);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void esp_console_repl_task(void *args)
|
|
||||||
{
|
|
||||||
esp_console_repl_universal_t *repl_conf = (esp_console_repl_universal_t *) args;
|
|
||||||
esp_console_repl_com_t *repl_com = &repl_conf->repl_com;
|
|
||||||
|
|
||||||
/* Waiting for task notify. This happens when `esp_console_start_repl()`
|
|
||||||
* function is called. */
|
|
||||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
|
||||||
|
|
||||||
if (repl_com->state_mux != NULL) {
|
|
||||||
xSemaphoreTake(repl_com->state_mux, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change standard input and output of the task if the requested UART is
|
|
||||||
* NOT the default one. This block will replace stdin, stdout and stderr.
|
|
||||||
*/
|
|
||||||
#if CONFIG_LIBC_PICOLIBC
|
|
||||||
// TODO IDF-14901
|
|
||||||
if (repl_com->_stdin) {
|
|
||||||
stdin = repl_com->_stdin;
|
|
||||||
stdout = stderr = repl_com->_stdout;
|
|
||||||
} else {
|
|
||||||
linenoise_init_with_global_stdio();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const int uart_channel = repl_conf->uart_channel;
|
|
||||||
if (uart_channel != CONFIG_ESP_CONSOLE_UART_NUM) {
|
|
||||||
char path[CONSOLE_PATH_MAX_LEN] = { 0 };
|
|
||||||
snprintf(path, CONSOLE_PATH_MAX_LEN, "/dev/uart/%d", uart_channel);
|
|
||||||
|
|
||||||
stdin = fopen(path, "r");
|
|
||||||
stdout = fopen(path, "w");
|
|
||||||
stderr = stdout;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable buffering on stdin of the current task.
|
|
||||||
* If the console is ran on a different UART than the default one,
|
|
||||||
* buffering shall only be disabled for the current one. */
|
|
||||||
setvbuf(stdin, NULL, _IONBF, 0);
|
|
||||||
|
|
||||||
/* This message shall be printed here and not earlier as the stdout
|
|
||||||
* has just been set above. */
|
|
||||||
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");
|
|
||||||
|
|
||||||
if (linenoiseIsDumbMode()) {
|
|
||||||
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 Windows Terminal or Putty instead.\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
linenoiseSetMaxLineLen(repl_com->max_cmdline_length);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_LIBC_PICOLIBC
|
|
||||||
linenoise_close_stdio();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (repl_com->state_mux != NULL) {
|
|
||||||
xSemaphoreGive(repl_com->state_mux);
|
|
||||||
}
|
|
||||||
ESP_LOGD(TAG, "The End");
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2016-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -14,174 +14,40 @@
|
|||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "driver/uart.h"
|
#include "esp_stdio.h"
|
||||||
#include "driver/uart_vfs.h"
|
|
||||||
#include "driver/usb_serial_jtag.h"
|
|
||||||
#include "driver/usb_serial_jtag_vfs.h"
|
|
||||||
#include "esp_private/usb_console.h"
|
|
||||||
#include "esp_vfs_cdcacm.h"
|
|
||||||
|
|
||||||
#include "console_private.h"
|
#include "console_private.h"
|
||||||
|
|
||||||
#if !CONFIG_ESP_CONSOLE_NONE
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
|
#include "driver/uart_vfs.h"
|
||||||
|
|
||||||
static const char *TAG = "console.repl.chip";
|
static const char *TAG = "console.repl.chip";
|
||||||
#endif // !CONFIG_ESP_CONSOLE_NONE
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
static esp_err_t esp_console_repl_uart_delete_legacy(esp_console_repl_t *repl)
|
||||||
static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl);
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
static esp_err_t esp_console_repl_usb_cdc_delete(esp_console_repl_t *repl);
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
||||||
static esp_err_t esp_console_repl_usb_serial_jtag_delete(esp_console_repl_t *repl);
|
|
||||||
#endif //CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_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_com_t *repl_com = (esp_console_repl_com_t*)repl;
|
||||||
esp_console_repl_universal_t *cdc_repl = NULL;
|
esp_console_repl_universal_t *uart_repl = (esp_console_repl_universal_t*)repl_com;
|
||||||
if (!repl_config || !dev_config || !ret_repl) {
|
|
||||||
ret = ESP_ERR_INVALID_ARG;
|
// check if already de-initialized
|
||||||
goto _exit;
|
if (repl_com->state == CONSOLE_REPL_STATE_DEINIT) {
|
||||||
}
|
ESP_LOGE(TAG, "already de-initialized");
|
||||||
// allocate memory for console REPL context
|
return ESP_ERR_INVALID_STATE;
|
||||||
cdc_repl = calloc(1, sizeof(esp_console_repl_universal_t));
|
|
||||||
if (!cdc_repl) {
|
|
||||||
ret = ESP_ERR_NO_MEM;
|
|
||||||
goto _exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
const esp_err_t ret = esp_console_common_deinit(repl_com);
|
||||||
esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
|
||||||
/* Move the caret to the beginning of the next line on '\n' */
|
|
||||||
esp_vfs_dev_cdcacm_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
|
|
||||||
|
|
||||||
/* Enable blocking mode on stdin and stdout */
|
|
||||||
fcntl(fileno(stdout), F_SETFL, 0);
|
|
||||||
fcntl(fileno(stdin), F_SETFL, 0);
|
|
||||||
|
|
||||||
// initialize console, common part
|
|
||||||
ret = esp_console_common_init(repl_config->max_cmdline_length, &cdc_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
goto _exit;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup history
|
esp_console_deinit();
|
||||||
ret = esp_console_setup_history(repl_config->history_save_path, repl_config->max_history_len, &cdc_repl->repl_com);
|
uart_vfs_dev_port_deinit(uart_repl->dev_config);
|
||||||
if (ret != ESP_OK) {
|
/* free dev_config since it was malloc in esp_console_new_repl_uart_legacy */
|
||||||
goto _exit;
|
free(uart_repl->dev_config);
|
||||||
}
|
free(uart_repl);
|
||||||
|
|
||||||
// setup prompt
|
|
||||||
esp_console_setup_prompt(repl_config->prompt, &cdc_repl->repl_com);
|
|
||||||
|
|
||||||
/* Fill the structure here as it will be used directly by the created task. */
|
|
||||||
cdc_repl->uart_channel = CONFIG_ESP_CONSOLE_UART_NUM;
|
|
||||||
cdc_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
|
||||||
cdc_repl->repl_com.repl_core.del = esp_console_repl_usb_cdc_delete;
|
|
||||||
|
|
||||||
/* spawn a single thread to run REPL */
|
|
||||||
if (xTaskCreatePinnedToCore(esp_console_repl_task, "console_repl", repl_config->task_stack_size,
|
|
||||||
cdc_repl, repl_config->task_priority, &cdc_repl->repl_com.task_hdl, repl_config->task_core_id) != pdTRUE) {
|
|
||||||
ret = ESP_FAIL;
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret_repl = &cdc_repl->repl_com.repl_core;
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
_exit:
|
|
||||||
if (cdc_repl) {
|
|
||||||
esp_console_deinit();
|
|
||||||
free(cdc_repl);
|
|
||||||
}
|
|
||||||
if (ret_repl) {
|
|
||||||
*ret_repl = NULL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
static esp_err_t esp_console_new_repl_uart_legacy(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 esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
|
||||||
{
|
|
||||||
esp_console_repl_universal_t *usb_serial_jtag_repl = NULL;
|
|
||||||
if (!repl_config || !dev_config || !ret_repl) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t ret = ESP_OK;
|
|
||||||
// allocate memory for console REPL context
|
|
||||||
usb_serial_jtag_repl = calloc(1, sizeof(esp_console_repl_universal_t));
|
|
||||||
if (!usb_serial_jtag_repl) {
|
|
||||||
ret = ESP_ERR_NO_MEM;
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
|
||||||
usb_serial_jtag_vfs_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
|
||||||
/* Move the caret to the beginning of the next line on '\n' */
|
|
||||||
usb_serial_jtag_vfs_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
|
|
||||||
|
|
||||||
/* Enable blocking mode on stdin and stdout */
|
|
||||||
fcntl(fileno(stdout), F_SETFL, 0);
|
|
||||||
fcntl(fileno(stdin), F_SETFL, 0);
|
|
||||||
|
|
||||||
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
|
|
||||||
|
|
||||||
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
|
|
||||||
ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize console, common part
|
|
||||||
ret = esp_console_common_init(repl_config->max_cmdline_length, &usb_serial_jtag_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tell vfs to use usb-serial-jtag driver */
|
|
||||||
usb_serial_jtag_vfs_use_driver();
|
|
||||||
|
|
||||||
// setup history
|
|
||||||
ret = esp_console_setup_history(repl_config->history_save_path, repl_config->max_history_len, &usb_serial_jtag_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup prompt
|
|
||||||
esp_console_setup_prompt(repl_config->prompt, &usb_serial_jtag_repl->repl_com);
|
|
||||||
|
|
||||||
/* Fill the structure here as it will be used directly by the created task. */
|
|
||||||
usb_serial_jtag_repl->uart_channel = CONFIG_ESP_CONSOLE_UART_NUM;
|
|
||||||
usb_serial_jtag_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
|
||||||
usb_serial_jtag_repl->repl_com.repl_core.del = esp_console_repl_usb_serial_jtag_delete;
|
|
||||||
|
|
||||||
/* spawn a single thread to run REPL */
|
|
||||||
if (xTaskCreatePinnedToCore(esp_console_repl_task, "console_repl", repl_config->task_stack_size,
|
|
||||||
usb_serial_jtag_repl, repl_config->task_priority, &usb_serial_jtag_repl->repl_com.task_hdl, repl_config->task_core_id) != pdTRUE) {
|
|
||||||
ret = ESP_FAIL;
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret_repl = &usb_serial_jtag_repl->repl_com.repl_core;
|
|
||||||
return ESP_OK;
|
|
||||||
_exit:
|
|
||||||
if (usb_serial_jtag_repl) {
|
|
||||||
esp_console_deinit();
|
|
||||||
free(usb_serial_jtag_repl);
|
|
||||||
}
|
|
||||||
if (ret_repl) {
|
|
||||||
*ret_repl = NULL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
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_err_t ret = ESP_OK;
|
||||||
esp_console_repl_universal_t *uart_repl = NULL;
|
esp_console_repl_universal_t *uart_repl = NULL;
|
||||||
@@ -200,46 +66,11 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fsync(fileno(stdout));
|
fsync(fileno(stdout));
|
||||||
|
|
||||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
ret = uart_vfs_dev_port_init(dev_config, ESP_LINE_ENDINGS_CR, ESP_LINE_ENDINGS_CRLF);
|
||||||
uart_vfs_dev_port_set_rx_line_endings(dev_config->channel, ESP_LINE_ENDINGS_CR);
|
|
||||||
/* Move the caret to the beginning of the next line on '\n' */
|
|
||||||
uart_vfs_dev_port_set_tx_line_endings(dev_config->channel, ESP_LINE_ENDINGS_CRLF);
|
|
||||||
|
|
||||||
/* Configure UART. Note that REF_TICK/XTAL is used so that the baud rate remains
|
|
||||||
* correct while APB frequency is changing in light sleep mode.
|
|
||||||
*/
|
|
||||||
#if SOC_UART_SUPPORT_REF_TICK
|
|
||||||
uart_sclk_t clk_source = UART_SCLK_REF_TICK;
|
|
||||||
// REF_TICK clock can't provide a high baudrate
|
|
||||||
if (dev_config->baud_rate > 1 * 1000 * 1000) {
|
|
||||||
clk_source = UART_SCLK_DEFAULT;
|
|
||||||
ESP_LOGW(TAG, "light sleep UART wakeup might not work at the configured baud rate");
|
|
||||||
}
|
|
||||||
#elif SOC_UART_SUPPORT_XTAL_CLK
|
|
||||||
uart_sclk_t clk_source = UART_SCLK_XTAL;
|
|
||||||
#else
|
|
||||||
#error "No UART clock source is aware of DFS"
|
|
||||||
#endif // SOC_UART_SUPPORT_xxx
|
|
||||||
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 = clk_source,
|
|
||||||
};
|
|
||||||
|
|
||||||
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) {
|
if (ret != ESP_OK) {
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell VFS to use UART driver */
|
|
||||||
uart_vfs_dev_use_driver(dev_config->channel);
|
|
||||||
|
|
||||||
// initialize console, common part
|
// initialize console, common part
|
||||||
ret = esp_console_common_init(repl_config->max_cmdline_length, &uart_repl->repl_com);
|
ret = esp_console_common_init(repl_config->max_cmdline_length, &uart_repl->repl_com);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
@@ -278,7 +109,10 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setup prompt
|
// setup prompt
|
||||||
esp_console_setup_prompt(repl_config->prompt, &uart_repl->repl_com);
|
ret = esp_console_setup_prompt(repl_config->prompt, &uart_repl->repl_com);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
#if CONFIG_LIBC_PICOLIBC // TODO IDF-14901
|
#if CONFIG_LIBC_PICOLIBC // TODO IDF-14901
|
||||||
if (uart_repl->repl_com._stdin) {
|
if (uart_repl->repl_com._stdin) {
|
||||||
@@ -288,10 +122,20 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* we have to make a copy of the dev_config because it will be used to init the
|
||||||
|
* uart driver in the repl task. We have no guarantee that dev_config will still
|
||||||
|
* be valid then */
|
||||||
|
esp_console_dev_uart_config_t *copy_config = malloc(sizeof(esp_console_dev_uart_config_t));
|
||||||
|
if (copy_config == NULL) {
|
||||||
|
ret = ESP_ERR_NO_MEM;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
memcpy(copy_config, dev_config, sizeof(esp_console_dev_uart_config_t));
|
||||||
|
|
||||||
/* Fill the structure here as it will be used directly by the created task. */
|
/* Fill the structure here as it will be used directly by the created task. */
|
||||||
uart_repl->uart_channel = dev_config->channel;
|
uart_repl->dev_config = copy_config;
|
||||||
uart_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
uart_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||||
uart_repl->repl_com.repl_core.del = esp_console_repl_uart_delete;
|
uart_repl->repl_com.repl_core.del = esp_console_repl_uart_delete_legacy;
|
||||||
|
|
||||||
/* Spawn a single thread to run REPL, we need to pass `uart_repl` to it as
|
/* Spawn a single thread to run REPL, we need to pass `uart_repl` to it as
|
||||||
* it also requires the uart channel. */
|
* it also requires the uart channel. */
|
||||||
@@ -306,7 +150,6 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
|||||||
_exit:
|
_exit:
|
||||||
if (uart_repl) {
|
if (uart_repl) {
|
||||||
esp_console_deinit();
|
esp_console_deinit();
|
||||||
uart_driver_delete(dev_config->channel);
|
|
||||||
free(uart_repl);
|
free(uart_repl);
|
||||||
}
|
}
|
||||||
if (ret_repl) {
|
if (ret_repl) {
|
||||||
@@ -314,83 +157,57 @@ _exit:
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
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)
|
||||||
static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl)
|
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
return esp_console_new_repl_uart_legacy(dev_config, repl_config, ret_repl);
|
||||||
esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core);
|
|
||||||
esp_console_repl_universal_t *uart_repl = __containerof(repl_com, esp_console_repl_universal_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = esp_console_common_deinit(&uart_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_console_deinit();
|
|
||||||
uart_vfs_dev_use_nonblocking(uart_repl->uart_channel);
|
|
||||||
uart_driver_delete(uart_repl->uart_channel);
|
|
||||||
free(uart_repl);
|
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
|
void esp_console_repl_uart_setup_std_stream(const esp_console_dev_uart_config_t *dev_config)
|
||||||
|
{
|
||||||
|
const int uart_channel = dev_config->channel;
|
||||||
|
if (uart_channel != CONFIG_ESP_CONSOLE_UART_NUM) {
|
||||||
|
char path[CONSOLE_PATH_MAX_LEN] = { 0 };
|
||||||
|
snprintf(path, CONSOLE_PATH_MAX_LEN, "/dev/uart/%d", uart_channel);
|
||||||
|
|
||||||
|
FILE *temp_stdin = fopen(path, "r");
|
||||||
|
FILE *temp_stdout = fopen(path, "w");
|
||||||
|
if (temp_stdin == NULL || temp_stdout == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Failed to open UART device file for channel %d", uart_channel);
|
||||||
|
if (temp_stdin) {
|
||||||
|
fclose(temp_stdin);
|
||||||
|
}
|
||||||
|
if (temp_stdout) {
|
||||||
|
fclose(temp_stdout);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stdin = temp_stdin;
|
||||||
|
stdout = temp_stdout;
|
||||||
|
stderr = stdout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_UART
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||||
|
esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
||||||
|
{
|
||||||
|
(void)dev_config;
|
||||||
|
return esp_console_new_repl_stdio(repl_config, ret_repl);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC
|
#if CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
static esp_err_t esp_console_repl_usb_cdc_delete(esp_console_repl_t *repl)
|
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
(void)dev_config;
|
||||||
esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core);
|
return esp_console_new_repl_stdio(repl_config, ret_repl);
|
||||||
esp_console_repl_universal_t *cdc_repl = __containerof(repl_com, esp_console_repl_universal_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = esp_console_common_deinit(&cdc_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_console_deinit();
|
|
||||||
free(cdc_repl);
|
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
void esp_console_setup_standard_stream(void *dev_config)
|
||||||
static esp_err_t esp_console_repl_usb_serial_jtag_delete(esp_console_repl_t *repl)
|
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_OK;
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core);
|
esp_console_repl_uart_setup_std_stream((esp_console_dev_uart_config_t *)dev_config);
|
||||||
esp_console_repl_universal_t *usb_serial_jtag_repl = __containerof(repl_com, esp_console_repl_universal_t, repl_com);
|
#endif // CONFIG_ESP_CONSOLE_UART
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = esp_console_common_deinit(&usb_serial_jtag_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_console_deinit();
|
|
||||||
usb_serial_jtag_vfs_use_nonblocking();
|
|
||||||
usb_serial_jtag_driver_uninstall();
|
|
||||||
free(usb_serial_jtag_repl);
|
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
||||||
|
|||||||
@@ -6,10 +6,8 @@
|
|||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/cdefs.h> // __containerof
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include "esp_console.h"
|
|
||||||
#include "console_private.h"
|
#include "console_private.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "linenoise/linenoise.h"
|
#include "linenoise/linenoise.h"
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
|
|
||||||
#include "linenoise/linenoise.h"
|
|
||||||
#include "esp_console.h"
|
|
||||||
#include "console_private.h"
|
|
||||||
|
|
||||||
static const char *TAG = "console.repl";
|
|
||||||
|
|
||||||
static struct termios s_orig_termios;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function restores the original terminal settings.
|
|
||||||
*/
|
|
||||||
static void disable_raw_mode(void)
|
|
||||||
{
|
|
||||||
assert(tcsetattr(STDIN_FILENO, TCSAFLUSH, &s_orig_termios) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Depending on if the input is a terminal or a file or pipe, we need to apply different
|
|
||||||
* settings to avoid additional processing or buffering getting into our way.
|
|
||||||
*/
|
|
||||||
static void prepare_input_stream(void)
|
|
||||||
{
|
|
||||||
// Set stdin to unbuffered
|
|
||||||
setvbuf(stdin, NULL, _IONBF, 0);
|
|
||||||
|
|
||||||
const int stdin_fileno = fileno(stdin);
|
|
||||||
|
|
||||||
if (isatty(stdin_fileno)) {
|
|
||||||
// Use Termios driver to activate CR-NL translation and deactivate echo and canonical mode
|
|
||||||
assert(tcgetattr(stdin_fileno, &s_orig_termios) == 0);
|
|
||||||
struct termios raw = s_orig_termios;
|
|
||||||
raw.c_iflag |= ICRNL; // we translate to NL because linenoise expects NL
|
|
||||||
raw.c_lflag &= ~(ECHO | ICANON); // turn off echo and canonical mode
|
|
||||||
assert(tcsetattr(stdin_fileno, TCSAFLUSH, &raw) == 0);
|
|
||||||
|
|
||||||
// Make sure user does not end up with a broken terminal
|
|
||||||
assert(atexit(disable_raw_mode) == 0);
|
|
||||||
} else {
|
|
||||||
// Flush input
|
|
||||||
assert(fflush(stdin) == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t esp_console_repl_linux_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_universal_t *linux_repl = __containerof(repl_com, esp_console_repl_universal_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;
|
|
||||||
|
|
||||||
ret = esp_console_common_deinit(&linux_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_console_deinit();
|
|
||||||
|
|
||||||
free(linux_repl);
|
|
||||||
_exit:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t esp_console_new_repl_linux(const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
|
||||||
{
|
|
||||||
esp_console_repl_universal_t *linux_repl = NULL;
|
|
||||||
if (!repl_config || !ret_repl) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t ret = ESP_OK;
|
|
||||||
// allocate memory for console REPL context
|
|
||||||
linux_repl = calloc(1, sizeof(esp_console_repl_universal_t));
|
|
||||||
if (!linux_repl) {
|
|
||||||
ret = ESP_ERR_NO_MEM;
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable blocking mode on stdin and stdout */
|
|
||||||
fcntl(fileno(stdout), F_SETFL, 0);
|
|
||||||
fcntl(fileno(stdin), F_SETFL, 0);
|
|
||||||
|
|
||||||
// initialize console , common part
|
|
||||||
ret = esp_console_common_init(repl_config->max_cmdline_length, &linux_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, &linux_repl->repl_com);
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the setup works on Linux without buffering or additional processing
|
|
||||||
prepare_input_stream();
|
|
||||||
|
|
||||||
// setup prompt
|
|
||||||
esp_console_setup_prompt(repl_config->prompt, &linux_repl->repl_com);
|
|
||||||
|
|
||||||
/* Fill the structure here as it will be used directly by the created task. */
|
|
||||||
linux_repl->uart_channel = CONFIG_ESP_CONSOLE_UART_NUM;
|
|
||||||
linux_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
|
||||||
linux_repl->repl_com.repl_core.del = esp_console_repl_linux_delete;
|
|
||||||
|
|
||||||
/* spawn a single thread to run REPL */
|
|
||||||
if (xTaskCreate(esp_console_repl_task, "console_repl", repl_config->task_stack_size,
|
|
||||||
linux_repl, repl_config->task_priority, &linux_repl->repl_com.task_hdl) != pdTRUE) {
|
|
||||||
ret = ESP_FAIL;
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret_repl = &linux_repl->repl_com.repl_core;
|
|
||||||
return ESP_OK;
|
|
||||||
_exit:
|
|
||||||
if (linux_repl) {
|
|
||||||
esp_console_deinit();
|
|
||||||
free(linux_repl);
|
|
||||||
}
|
|
||||||
if (ret_repl) {
|
|
||||||
*ret_repl = NULL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (!dev_config) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return esp_console_new_repl_linux(repl_config, ret_repl);
|
|
||||||
}
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
|
||||||
{
|
|
||||||
if (!dev_config) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return esp_console_new_repl_linux(repl_config, ret_repl);
|
|
||||||
}
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
||||||
esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
|
||||||
{
|
|
||||||
if (!dev_config) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return esp_console_new_repl_linux(repl_config, ret_repl);
|
|
||||||
}
|
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -45,9 +45,15 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
esp_console_repl_com_t repl_com; // base class
|
esp_console_repl_com_t repl_com; // base class
|
||||||
int uart_channel; // uart channel number
|
void *dev_config;
|
||||||
} esp_console_repl_universal_t;
|
} esp_console_repl_universal_t;
|
||||||
|
|
||||||
|
_Static_assert(offsetof(esp_console_repl_com_t, repl_core) == 0,
|
||||||
|
"repl_core must be the first member of esp_console_repl_com_t");
|
||||||
|
|
||||||
|
_Static_assert(offsetof(esp_console_repl_universal_t, repl_com) == 0,
|
||||||
|
"repl_com must be the first member of esp_console_repl_universal_t");
|
||||||
|
|
||||||
void esp_console_repl_task(void *args);
|
void esp_console_repl_task(void *args);
|
||||||
|
|
||||||
esp_err_t esp_console_common_init(size_t max_cmdline_length, esp_console_repl_com_t *repl_com);
|
esp_err_t esp_console_common_init(size_t max_cmdline_length, esp_console_repl_com_t *repl_com);
|
||||||
@@ -57,3 +63,5 @@ esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_com_t *r
|
|||||||
esp_err_t esp_console_setup_history(const char *history_path,
|
esp_err_t esp_console_setup_history(const char *history_path,
|
||||||
uint32_t max_history_len,
|
uint32_t max_history_len,
|
||||||
esp_console_repl_com_t *repl_com);
|
esp_console_repl_com_t *repl_com);
|
||||||
|
|
||||||
|
void esp_console_setup_standard_stream(void *dev_config);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -89,10 +89,8 @@ TEST_CASE("esp console register with normal and context aware function set to NU
|
|||||||
TEST_CASE("esp console init function NULL param fails", "[console]")
|
TEST_CASE("esp console init function NULL param fails", "[console]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_console_new_repl_stdio(NULL, &s_repl));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_console_new_repl_uart(NULL, &repl_config, &s_repl));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_console_new_repl_stdio(&repl_config, NULL));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_console_new_repl_uart(&uart_config, NULL, &s_repl));
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_console_new_repl_uart(&uart_config, &repl_config, NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("esp console init/deinit test", "[console]")
|
TEST_CASE("esp console init/deinit test", "[console]")
|
||||||
@@ -161,8 +159,7 @@ TEST_CASE("esp console repl test", "[console][ignore]")
|
|||||||
TEST_ASSERT_NOT_NULL(s_test_console_mutex);
|
TEST_ASSERT_NOT_NULL(s_test_console_mutex);
|
||||||
|
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
|
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
||||||
|
|
||||||
@@ -195,8 +192,7 @@ TEST_CASE("esp console repl deinit", "[console][ignore]")
|
|||||||
set_leak_threshold(248);
|
set_leak_threshold(248);
|
||||||
|
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
|
|
||||||
/* start the repl task */
|
/* start the repl task */
|
||||||
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||||
@@ -227,11 +223,28 @@ static const esp_console_cmd_t cmd_z = {
|
|||||||
.func = do_hello_cmd,
|
.func = do_hello_cmd,
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("esp console help command - sorted registration", "[console][ignore]")
|
/* To keep testing the old API esp_console_new_repl_uart, the following
|
||||||
|
* 2 test cases will initialize repl using this API when run on other target
|
||||||
|
* than linux and will use the new API on linux. */
|
||||||
|
#if !CONFIG_IDF_TARGET_LINUX
|
||||||
|
static void test_console_repl_init(void)
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
/* use the old API to register the IO so we keep some coverage for it in the tests */
|
||||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
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));
|
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void test_console_repl_init(void)
|
||||||
|
{
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
|
}
|
||||||
|
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
|
TEST_CASE("esp console help command - sorted registration", "[console][ignore]")
|
||||||
|
{
|
||||||
|
test_console_repl_init();
|
||||||
|
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&cmd_a));
|
TEST_ESP_OK(esp_console_cmd_register(&cmd_a));
|
||||||
TEST_ESP_OK(esp_console_register_help_command());
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
@@ -248,9 +261,7 @@ TEST_CASE("esp console help command - sorted registration", "[console][ignore]")
|
|||||||
*/
|
*/
|
||||||
TEST_CASE("esp console help command - reverse registration", "[console][ignore]")
|
TEST_CASE("esp console help command - reverse registration", "[console][ignore]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
test_console_repl_init();
|
||||||
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));
|
|
||||||
|
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&cmd_z));
|
TEST_ESP_OK(esp_console_cmd_register(&cmd_z));
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
||||||
@@ -336,8 +347,7 @@ TEST_CASE("esp console test with context", "[console]")
|
|||||||
TEST_CASE("esp console help command - set verbose level = 0", "[console][ignore]")
|
TEST_CASE("esp console help command - set verbose level = 0", "[console][ignore]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
TEST_ESP_OK(esp_console_register_help_command());
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM));
|
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM));
|
||||||
TEST_ESP_OK(esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_0));
|
TEST_ESP_OK(esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_0));
|
||||||
@@ -348,8 +358,7 @@ TEST_CASE("esp console help command - set verbose level = 0", "[console][ignore]
|
|||||||
TEST_CASE("esp console help command - set verbose level = 1", "[console][ignore]")
|
TEST_CASE("esp console help command - set verbose level = 1", "[console][ignore]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
TEST_ESP_OK(esp_console_register_help_command());
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM));
|
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM));
|
||||||
TEST_ESP_OK(esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_1));
|
TEST_ESP_OK(esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_1));
|
||||||
@@ -360,8 +369,7 @@ TEST_CASE("esp console help command - set verbose level = 1", "[console][ignore]
|
|||||||
TEST_CASE("esp console help command - --verbose sub command", "[console][ignore]")
|
TEST_CASE("esp console help command - --verbose sub command", "[console][ignore]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
TEST_ESP_OK(esp_console_register_help_command());
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||||
@@ -370,8 +378,7 @@ TEST_CASE("esp console help command - --verbose sub command", "[console][ignore]
|
|||||||
TEST_CASE("esp console deregister commands", "[console][ignore]")
|
TEST_CASE("esp console deregister commands", "[console][ignore]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
|
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&cmd_a));
|
TEST_ESP_OK(esp_console_cmd_register(&cmd_a));
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
||||||
@@ -388,8 +395,7 @@ TEST_CASE("esp console deregister commands", "[console][ignore]")
|
|||||||
TEST_CASE("esp console re-register commands", "[console][ignore]")
|
TEST_CASE("esp console re-register commands", "[console][ignore]")
|
||||||
{
|
{
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
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();
|
TEST_ESP_OK(esp_console_new_repl_stdio(&repl_config, &s_repl));
|
||||||
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
|
||||||
|
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&cmd_a));
|
TEST_ESP_OK(esp_console_cmd_register(&cmd_a));
|
||||||
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd));
|
||||||
@@ -409,7 +415,6 @@ TEST_CASE("esp console re-register commands", "[console][ignore]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_IDF_TARGET_LINUX
|
#if !CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
TEST_CASE("esp console repl custom_uart test", "[console][ignore]")
|
TEST_CASE("esp console repl custom_uart test", "[console][ignore]")
|
||||||
{
|
{
|
||||||
set_leak_threshold(248);
|
set_leak_threshold(248);
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_vfs_common.h"
|
||||||
#include "esp_vfs.h"
|
#include "esp_vfs.h"
|
||||||
|
#include "esp_vfs_ops.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "driver/uart_vfs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -22,6 +26,33 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
const esp_vfs_fs_ops_t *esp_vfs_uart_get_vfs(void);
|
const esp_vfs_fs_ops_t *esp_vfs_uart_get_vfs(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the UART VFS console port.
|
||||||
|
*
|
||||||
|
* Registers a UART as a console device in the ESP-IDF virtual filesystem layer.
|
||||||
|
* Once initialized, system input and output streams such as `printf` and shell
|
||||||
|
* consoles will communicate through the configured UART channel.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the UART VFS device configuration.
|
||||||
|
* @param rx_mode Line ending mode to apply when receiving data.
|
||||||
|
* @param tx_mode Line ending mode to apply when transmitting data.
|
||||||
|
* @return ESP_OK if initialization completes successfully, or an error code if it fails.
|
||||||
|
*/
|
||||||
|
esp_err_t uart_vfs_dev_port_init(const esp_console_dev_uart_config_t *config,
|
||||||
|
esp_line_endings_t rx_mode,
|
||||||
|
esp_line_endings_t tx_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialize the UART VFS console port.
|
||||||
|
*
|
||||||
|
* Unregisters the UART from the VFS layer and restores driver state. Use this
|
||||||
|
* when the UART console is no longer required or when switching to another
|
||||||
|
* console backend.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the UART VFS device configuration.
|
||||||
|
*/
|
||||||
|
void uart_vfs_dev_port_deinit(const esp_console_dev_uart_config_t *config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -7,11 +7,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esp_vfs_common.h"
|
#include "esp_vfs_common.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* TODO IDF-14810: Rename so esp_console does not appear in the name. */
|
||||||
|
/**
|
||||||
|
* @brief UART VFS configuration structure.
|
||||||
|
*
|
||||||
|
* Defines the configuration parameters required to initialize and register
|
||||||
|
* a UART VFS driver instance.
|
||||||
|
*/
|
||||||
|
typedef struct esp_console_dev_uart_config {
|
||||||
|
int channel; //!< UART channel number (count from zero)
|
||||||
|
int baud_rate; //!< Communication 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add /dev/uart virtual filesystem driver
|
* @brief Add /dev/uart virtual filesystem driver
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "driver/uart_vfs.h"
|
#include "driver/uart_vfs.h"
|
||||||
|
#include "driver/esp_private/uart_vfs.h"
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "driver/uart_select.h"
|
#include "driver/uart_select.h"
|
||||||
#include "esp_rom_serial_output.h"
|
#include "esp_rom_serial_output.h"
|
||||||
@@ -1163,12 +1164,73 @@ void uart_vfs_dev_use_driver(int uart_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
|
esp_err_t uart_vfs_dev_port_init(const esp_console_dev_uart_config_t *config,
|
||||||
|
esp_line_endings_t rx_mode,
|
||||||
|
esp_line_endings_t tx_mode)
|
||||||
|
{
|
||||||
|
if (config == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_vfs_dev_port_set_rx_line_endings(config->channel, rx_mode) == -1) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_vfs_dev_port_set_tx_line_endings(config->channel, tx_mode) == -1) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure UART. Note that REF_TICK/XTAL is used so that the baud rate remains
|
||||||
|
* correct while APB frequency is changing in light sleep mode.
|
||||||
|
*/
|
||||||
|
#if SOC_UART_SUPPORT_REF_TICK
|
||||||
|
uart_sclk_t clk_source = UART_SCLK_REF_TICK;
|
||||||
|
// REF_TICK clock can't provide a high baudrate
|
||||||
|
if (config->baud_rate > 1 * 1000 * 1000) {
|
||||||
|
clk_source = UART_SCLK_DEFAULT;
|
||||||
|
ESP_LOGW("uart_vfs", "light sleep UART wakeup might not work at the configured baud rate");
|
||||||
|
}
|
||||||
|
#elif SOC_UART_SUPPORT_XTAL_CLK
|
||||||
|
uart_sclk_t clk_source = UART_SCLK_XTAL;
|
||||||
|
#else
|
||||||
|
#error "No UART clock source is aware of DFS"
|
||||||
|
#endif // SOC_UART_SUPPORT_xxx
|
||||||
|
const uart_config_t uart_driver_config = {
|
||||||
|
.baud_rate = config->baud_rate,
|
||||||
|
.data_bits = UART_DATA_8_BITS,
|
||||||
|
.parity = UART_PARITY_DISABLE,
|
||||||
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
|
.source_clk = clk_source,
|
||||||
|
};
|
||||||
|
|
||||||
|
uart_param_config(config->channel, &uart_driver_config);
|
||||||
|
uart_set_pin(config->channel, config->tx_gpio_num, config->rx_gpio_num, -1, -1);
|
||||||
|
|
||||||
|
/* Install UART driver for interrupt-driven reads and writes */
|
||||||
|
const esp_err_t ret = uart_driver_install(config->channel, 256, 0, 0, NULL, 0);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
uart_driver_delete(config->channel);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell VFS to use UART driver */
|
||||||
|
uart_vfs_dev_use_driver(config->channel);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_vfs_dev_port_deinit(const esp_console_dev_uart_config_t *config)
|
||||||
|
{
|
||||||
|
uart_vfs_dev_use_nonblocking(config->channel);
|
||||||
|
uart_driver_delete(config->channel);
|
||||||
|
}
|
||||||
|
|
||||||
ESP_SYSTEM_INIT_FN(init_vfs_uart, CORE, BIT(0), 110)
|
ESP_SYSTEM_INIT_FN(init_vfs_uart, CORE, BIT(0), 110)
|
||||||
{
|
{
|
||||||
uart_vfs_dev_register();
|
uart_vfs_dev_register();
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // CONFIG_ESP_CONSOLE_UART
|
||||||
|
|
||||||
void uart_vfs_include_dev_init(void)
|
void uart_vfs_include_dev_init(void)
|
||||||
{
|
{
|
||||||
|
|||||||
+33
-1
@@ -1,12 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
#include "esp_vfs.h"
|
#include "esp_vfs.h"
|
||||||
|
#include "esp_vfs_common.h"
|
||||||
|
#include "esp_vfs_ops.h"
|
||||||
|
#include "driver/usb_serial_jtag_vfs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -22,6 +26,34 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
const esp_vfs_fs_ops_t *esp_vfs_usb_serial_jtag_get_vfs(void);
|
const esp_vfs_fs_ops_t *esp_vfs_usb_serial_jtag_get_vfs(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the USB Serial JTAG VFS console port.
|
||||||
|
*
|
||||||
|
* Registers the USB Serial JTAG interface as a standard console I/O device
|
||||||
|
* through the ESP-IDF virtual filesystem. Once initialized, standard input
|
||||||
|
* and output streams (such as `printf` and interactive console REPL) will be
|
||||||
|
* routed through the USB Serial JTAG peripheral.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the USB Serial JTAG VFS device configuration.
|
||||||
|
* @param rx_mode Line ending mode to apply to received data.
|
||||||
|
* @param tx_mode Line ending mode to apply to transmitted data.
|
||||||
|
* @return ESP_OK on successful initialization, or an error code if setup fails.
|
||||||
|
*/
|
||||||
|
esp_err_t usb_serial_jtag_vfs_dev_port_init(const esp_console_dev_usb_serial_jtag_config_t *config,
|
||||||
|
esp_line_endings_t rx_mode,
|
||||||
|
esp_line_endings_t tx_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialize the USB Serial JTAG VFS console port.
|
||||||
|
*
|
||||||
|
* Unregisters the USB Serial JTAG VFS device and restores driver state. Call
|
||||||
|
* this when the console is no longer needed or when switching to a different
|
||||||
|
* console backend.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the USB Serial JTAG VFS device configuration.
|
||||||
|
*/
|
||||||
|
void usb_serial_jtag_vfs_dev_port_deinit(const esp_console_dev_usb_serial_jtag_config_t *config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -14,6 +14,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* TODO IDF-14810: Rename so esp_console does not appear in the name. */
|
||||||
|
/**
|
||||||
|
* @brief Parameters for console device: USB-SERIAL-JTAG
|
||||||
|
*
|
||||||
|
* @note It's an empty structure for now, reserved for future
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct esp_console_dev_usb_serial_jtag_config {
|
||||||
|
|
||||||
|
} esp_console_dev_usb_serial_jtag_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief add /dev/usbserjtag virtual filesystem driver
|
* @brief add /dev/usbserjtag virtual filesystem driver
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "driver/usb_serial_jtag_select.h"
|
#include "driver/usb_serial_jtag_select.h"
|
||||||
#include "driver/usb_serial_jtag_vfs.h"
|
#include "driver/usb_serial_jtag_vfs.h"
|
||||||
#include "driver/usb_serial_jtag.h"
|
#include "driver/usb_serial_jtag.h"
|
||||||
|
#include "driver/esp_private/usb_serial_jtag_vfs.h"
|
||||||
#include "esp_private/startup_internal.h"
|
#include "esp_private/startup_internal.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
|
|
||||||
@@ -680,6 +681,36 @@ ESP_SYSTEM_INIT_FN(init_vfs_usj, CORE, BIT(0), 111)
|
|||||||
usb_serial_jtag_vfs_register();
|
usb_serial_jtag_vfs_register();
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t usb_serial_jtag_vfs_dev_port_init(const esp_console_dev_usb_serial_jtag_config_t *config,
|
||||||
|
esp_line_endings_t rx_mode,
|
||||||
|
esp_line_endings_t tx_mode)
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
|
||||||
|
usb_serial_jtag_vfs_set_rx_line_endings(rx_mode);
|
||||||
|
usb_serial_jtag_vfs_set_tx_line_endings(tx_mode);
|
||||||
|
|
||||||
|
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
|
||||||
|
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
|
||||||
|
esp_err_t ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell vfs to use usb-serial-jtag driver */
|
||||||
|
usb_serial_jtag_vfs_use_driver();
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_serial_jtag_vfs_dev_port_deinit(const esp_console_dev_usb_serial_jtag_config_t *config)
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
usb_serial_jtag_vfs_use_nonblocking();
|
||||||
|
usb_serial_jtag_driver_uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
|
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
|
||||||
|
|||||||
@@ -3,17 +3,29 @@ idf_build_get_property(target IDF_TARGET)
|
|||||||
# Bootloader builds only needs it for config, not for anything else
|
# Bootloader builds only needs it for config, not for anything else
|
||||||
idf_build_get_property(non_os_build NON_OS_BUILD)
|
idf_build_get_property(non_os_build NON_OS_BUILD)
|
||||||
|
|
||||||
if(non_os_build OR ${target} STREQUAL "linux")
|
if(non_os_build)
|
||||||
idf_component_register()
|
idf_component_register()
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(srcs "stdio_vfs.c"
|
set(srcs)
|
||||||
"stdio_simple.c"
|
set(includes)
|
||||||
"stdio_syscalls_simple.c")
|
|
||||||
|
if(${target} STREQUAL "linux")
|
||||||
|
list(APPEND srcs "stdio_port.c"
|
||||||
|
"linux/esp_stdio_linux.c")
|
||||||
|
list(APPEND includes "include"
|
||||||
|
"linux/include")
|
||||||
|
else()
|
||||||
|
list(APPEND srcs "stdio_port.c"
|
||||||
|
"stdio_vfs.c"
|
||||||
|
"stdio_simple.c"
|
||||||
|
"stdio_syscalls_simple.c")
|
||||||
|
list(APPEND includes "include")
|
||||||
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
INCLUDE_DIRS include)
|
INCLUDE_DIRS ${includes})
|
||||||
|
|
||||||
if(CONFIG_VFS_SUPPORT_IO)
|
if(CONFIG_VFS_SUPPORT_IO)
|
||||||
if(IDF_BUILD_V2)
|
if(IDF_BUILD_V2)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
|
#include "esp_stdio_cli_config.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -21,6 +21,30 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_stdio_register(void);
|
esp_err_t esp_stdio_register(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Install and enable the default stdio driver.
|
||||||
|
*
|
||||||
|
* Initializes the selected console backend and registers it as the active
|
||||||
|
* input and output stream source. After calling this function, standard I/O
|
||||||
|
* functions such as `printf` and terminal input will use the configured backend.
|
||||||
|
*
|
||||||
|
* Line endings are automatically configured for typical terminal use:
|
||||||
|
* - RX: CR (terminals send CR when Enter is pressed)
|
||||||
|
* - TX: CRLF (move cursor to beginning of next line on newline)
|
||||||
|
*
|
||||||
|
* @return ESP_OK if the driver is successfully installed, or an appropriate error code otherwise.
|
||||||
|
*/
|
||||||
|
esp_err_t esp_stdio_install_io_driver(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Uninstall the active stdio driver.
|
||||||
|
*
|
||||||
|
* Restores driver state and detaches the console backend from the standard I/O
|
||||||
|
* streams. Call this when shutting down or when replacing the current console
|
||||||
|
* driver with a different one.
|
||||||
|
*/
|
||||||
|
void esp_stdio_uninstall_io_driver(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
||||||
|
#include "soc/uart_pins.h"
|
||||||
|
#if 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 >= 0) ? CONFIG_ESP_CONSOLE_UART_TX_GPIO : U0TXD_GPIO_NUM, \
|
||||||
|
.rx_gpio_num = (CONFIG_ESP_CONSOLE_UART_RX_GPIO >= 0) ? CONFIG_ESP_CONSOLE_UART_RX_GPIO : U0RXD_GPIO_NUM, \
|
||||||
|
}
|
||||||
|
#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 // CONFIG_ESP_CONSOLE_UART_CUSTOM
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
||||||
|
#define ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT() {}
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
||||||
|
#define ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT() {}
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_USB_CDC || (defined __DOXYGEN__ && SOC_USB_OTG_SUPPORTED)
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
|
#define ESP_CONSOLE_DEV_LINUX_CONFIG_DEFAULT() {}
|
||||||
|
#endif // CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_stdio_linux.h"
|
||||||
|
|
||||||
|
static struct termios s_orig_termios;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function restores the original terminal settings.
|
||||||
|
*/
|
||||||
|
static void disable_raw_mode(void)
|
||||||
|
{
|
||||||
|
assert(tcsetattr(STDIN_FILENO, TCSAFLUSH, &s_orig_termios) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void linux_vfs_dev_port_deinit(linux_port_config_t *config)
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t linux_vfs_dev_port_init(linux_port_config_t *config)
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
|
||||||
|
// Set stdin to unbuffered
|
||||||
|
setvbuf(stdin, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
const int stdin_fileno = fileno(stdin);
|
||||||
|
|
||||||
|
if (isatty(stdin_fileno)) {
|
||||||
|
// Use Termios driver to activate CR-NL translation and deactivate echo and canonical mode
|
||||||
|
assert(tcgetattr(stdin_fileno, &s_orig_termios) == 0);
|
||||||
|
struct termios raw = s_orig_termios;
|
||||||
|
raw.c_iflag |= ICRNL; // we translate to NL because linenoise expects NL
|
||||||
|
raw.c_lflag &= ~(ECHO | ICANON); // turn off echo and canonical mode
|
||||||
|
assert(tcsetattr(stdin_fileno, TCSAFLUSH, &raw) == 0);
|
||||||
|
|
||||||
|
// Make sure user does not end up with a broken terminal
|
||||||
|
assert(atexit(disable_raw_mode) == 0);
|
||||||
|
} else {
|
||||||
|
// Flush input
|
||||||
|
assert(fflush(stdin) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration for a Linux host-side console port.
|
||||||
|
*
|
||||||
|
* Represents the configuration used when running the console interface on a
|
||||||
|
* Linux host environment. This is typically used in host-based testing,
|
||||||
|
* emulation, or development workflows where the console backend is not a
|
||||||
|
* hardware UART or USB device.
|
||||||
|
*/
|
||||||
|
typedef struct linux_port_config {
|
||||||
|
|
||||||
|
} linux_port_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Install the Linux console driver.
|
||||||
|
*
|
||||||
|
* Sets up the Linux console port as the active input/output backend for console
|
||||||
|
* operations. After installation, standard I/O (such as printf or terminal input)
|
||||||
|
* will pass through this Linux-based interface.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the Linux console port configuration.
|
||||||
|
* @return ESP_OK if the driver was successfully installed, or an error otherwise.
|
||||||
|
*/
|
||||||
|
esp_err_t linux_vfs_dev_port_init(linux_port_config_t *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Uninstall the Linux console driver.
|
||||||
|
*
|
||||||
|
* Releases resources allocated during driver installation and restores state
|
||||||
|
* associated with the Linux console backend. Call this when shutting down or
|
||||||
|
* switching to another console interface.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the Linux console port configuration.
|
||||||
|
*/
|
||||||
|
void linux_vfs_dev_port_deinit(linux_port_config_t *config);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_stdio.h"
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
|
#include "esp_stdio_linux.h"
|
||||||
|
#elif CONFIG_VFS_SUPPORT_IO // VFS required for all device drivers below
|
||||||
|
|
||||||
|
#include "esp_vfs_common.h"
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
#include "esp_vfs_cdcacm.h"
|
||||||
|
#include "esp_private/esp_vfs_cdcacm.h"
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||||
|
#include "driver/esp_private/usb_serial_jtag_vfs.h"
|
||||||
|
#include "driver/usb_serial_jtag_vfs.h"
|
||||||
|
#endif // #if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
|
#include "driver/esp_private/uart_vfs.h"
|
||||||
|
#include "driver/uart_vfs.h"
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_UART
|
||||||
|
|
||||||
|
#endif // CONFIG_VFS_SUPPORT_IO
|
||||||
|
|
||||||
|
esp_err_t esp_stdio_install_io_driver(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_FAIL;
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
|
linux_port_config_t config = ESP_CONSOLE_DEV_LINUX_CONFIG_DEFAULT();
|
||||||
|
ret = linux_vfs_dev_port_init(&config);
|
||||||
|
#elif CONFIG_VFS_SUPPORT_IO
|
||||||
|
|
||||||
|
/* - set rx_mode to ESP_LINE_ENDINGS_CRLF as minicom, screen, idf_monitor
|
||||||
|
* send CR when ENTER key is pressed.
|
||||||
|
* - set tx_mode to move the caret to the beginning of the next line on '\n' */
|
||||||
|
|
||||||
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
|
esp_console_dev_uart_config_t config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
ret = uart_vfs_dev_port_init(&config, ESP_LINE_ENDINGS_CR, ESP_LINE_ENDINGS_CRLF);
|
||||||
|
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||||
|
esp_console_dev_usb_serial_jtag_config_t config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
||||||
|
ret = usb_serial_jtag_vfs_dev_port_init(&config, ESP_LINE_ENDINGS_CR, ESP_LINE_ENDINGS_CRLF);
|
||||||
|
#elif CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
esp_console_dev_usb_cdc_config_t config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
|
||||||
|
ret = cdcacm_vfs_dev_port_init(&config, ESP_LINE_ENDINGS_CR, ESP_LINE_ENDINGS_CRLF);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
ret = ESP_ERR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_stdio_uninstall_io_driver(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_LINUX
|
||||||
|
linux_port_config_t config = ESP_CONSOLE_DEV_LINUX_CONFIG_DEFAULT();
|
||||||
|
linux_vfs_dev_port_deinit(&config);
|
||||||
|
#elif CONFIG_VFS_SUPPORT_IO
|
||||||
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
|
esp_console_dev_uart_config_t config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
uart_vfs_dev_port_deinit(&config);
|
||||||
|
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||||
|
esp_console_dev_usb_serial_jtag_config_t config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
||||||
|
usb_serial_jtag_vfs_dev_port_deinit(&config);
|
||||||
|
#elif CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
esp_console_dev_usb_cdc_config_t config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
|
||||||
|
cdcacm_vfs_dev_port_deinit(&config);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -10,26 +10,26 @@
|
|||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_stdio.h"
|
#include "esp_stdio.h"
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
|
|
||||||
#if CONFIG_VFS_SUPPORT_IO
|
#if CONFIG_VFS_SUPPORT_IO
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC
|
#if CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
#include "esp_vfs_cdcacm.h"
|
#include "esp_vfs_cdcacm.h"
|
||||||
#include "esp_private/usb_console.h"
|
|
||||||
#endif
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_CDC
|
|
||||||
#include "esp_private/esp_vfs_cdcacm.h"
|
#include "esp_private/esp_vfs_cdcacm.h"
|
||||||
#endif
|
#endif // CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||||
#include "driver/esp_private/usb_serial_jtag_vfs.h"
|
#include "driver/esp_private/usb_serial_jtag_vfs.h"
|
||||||
#endif
|
#include "driver/usb_serial_jtag_vfs.h"
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||||
|
|
||||||
#if CONFIG_ESP_CONSOLE_UART
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
#include "driver/esp_private/uart_vfs.h"
|
#include "driver/esp_private/uart_vfs.h"
|
||||||
#endif
|
#include "driver/uart_vfs.h"
|
||||||
|
#endif // CONFIG_ESP_CONSOLE_UART
|
||||||
|
|
||||||
#include "esp_private/startup_internal.h"
|
#include "esp_private/startup_internal.h"
|
||||||
#include "esp_private/nullfs.h"
|
#include "esp_private/nullfs.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STRINGIFY(s) STRINGIFY2(s)
|
#define STRINGIFY(s) STRINGIFY2(s)
|
||||||
#define STRINGIFY2(s) #s
|
#define STRINGIFY2(s) #s
|
||||||
@@ -47,8 +47,6 @@ typedef struct {
|
|||||||
int fd_secondary;
|
int fd_secondary;
|
||||||
} vfs_console_context_t;
|
} vfs_console_context_t;
|
||||||
|
|
||||||
#if CONFIG_VFS_SUPPORT_IO
|
|
||||||
|
|
||||||
// Secondary register part.
|
// Secondary register part.
|
||||||
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
|
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
|
||||||
const static esp_vfs_fs_ops_t *secondary_vfs = NULL;
|
const static esp_vfs_fs_ops_t *secondary_vfs = NULL;
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esp_vfs.h"
|
#include "esp_err.h"
|
||||||
|
#include "esp_vfs_common.h"
|
||||||
|
#include "../esp_vfs_cdcacm.h" /* use relative path to make sure we include the correct header */
|
||||||
|
#include "esp_vfs_ops.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -22,6 +25,33 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
const esp_vfs_fs_ops_t *esp_vfs_cdcacm_get_vfs(void);
|
const esp_vfs_fs_ops_t *esp_vfs_cdcacm_get_vfs(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the USB CDC-ACM VFS console port.
|
||||||
|
*
|
||||||
|
* Registers the USB CDC-ACM interface as a console device in the ESP-IDF
|
||||||
|
* virtual filesystem layer. Once initialized, standard I/O functions such as
|
||||||
|
* `printf` and interactive console input will use the USB CDC-ACM channel.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the USB CDC-ACM VFS device configuration.
|
||||||
|
* @param rx_mode Line ending mode to apply when receiving data.
|
||||||
|
* @param tx_mode Line ending mode to apply when transmitting data.
|
||||||
|
* @return ESP_OK if initialization completed successfully, or a related error code.
|
||||||
|
*/
|
||||||
|
esp_err_t cdcacm_vfs_dev_port_init(const esp_console_dev_usb_cdc_config_t *config,
|
||||||
|
esp_line_endings_t rx_mode,
|
||||||
|
esp_line_endings_t tx_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialize the USB CDC-ACM VFS console port.
|
||||||
|
*
|
||||||
|
* Unregisters the USB CDC-ACM VFS device and releases resources allocated during
|
||||||
|
* initialization. Call this when the console is being shut down or replaced by
|
||||||
|
* another console backend.
|
||||||
|
*
|
||||||
|
* @param config Pointer to the USB CDC-ACM VFS device configuration.
|
||||||
|
*/
|
||||||
|
void cdcacm_vfs_dev_port_deinit(const esp_console_dev_usb_cdc_config_t *config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -13,6 +13,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* TODO IDF-14810: Rename so esp_console does not appear in the name. */
|
||||||
|
/**
|
||||||
|
* @brief Parameters for console device: USB CDC
|
||||||
|
*
|
||||||
|
* @note It's an empty structure for now, reserved for future
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct esp_console_dev_usb_cdc_config {
|
||||||
|
|
||||||
|
} esp_console_dev_usb_cdc_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief add /dev/cdcacm virtual filesystem driver
|
* @brief add /dev/cdcacm virtual filesystem driver
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_private/esp_vfs_cdcacm.h"
|
||||||
#include "esp_private/esp_vfs_cdcacm_select.h"
|
#include "esp_private/esp_vfs_cdcacm_select.h"
|
||||||
#include "esp_private/usb_console.h"
|
#include "esp_private/usb_console.h"
|
||||||
#include "esp_private/startup_internal.h"
|
#include "esp_private/startup_internal.h"
|
||||||
@@ -533,6 +534,24 @@ ESP_SYSTEM_INIT_FN(init_vfs_usb_cdc_rom_console, CORE, BIT(0), 113)
|
|||||||
|
|
||||||
return esp_vfs_dev_cdcacm_register();
|
return esp_vfs_dev_cdcacm_register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t cdcacm_vfs_dev_port_init(const esp_console_dev_usb_cdc_config_t *config,
|
||||||
|
esp_line_endings_t rx_mode,
|
||||||
|
esp_line_endings_t tx_mode)
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
|
||||||
|
esp_vfs_dev_cdcacm_set_rx_line_endings(rx_mode);
|
||||||
|
esp_vfs_dev_cdcacm_set_tx_line_endings(tx_mode);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdcacm_vfs_dev_port_deinit(const esp_console_dev_usb_cdc_config_t *config)
|
||||||
|
{
|
||||||
|
(void)config;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void esp_vfs_dev_cdcacm_include_dev_init(void)
|
void esp_vfs_dev_cdcacm_include_dev_init(void)
|
||||||
|
|||||||
@@ -185,13 +185,10 @@ Initialize Console REPL Environment
|
|||||||
|
|
||||||
To establish a basic REPL environment, ``console`` component provides several useful APIs, combining those functions described above.
|
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_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`).
|
In a typical application, you only need to call :cpp:func:`esp_console_new_repl_stdio` to initialize the REPL environment, 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_start_repl`.
|
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`.
|
||||||
|
|
||||||
.. only:: SOC_USB_SERIAL_JTAG_SUPPORTED
|
|
||||||
|
|
||||||
Likewise, if your REPL environment is based on USB_SERIAL_JTAG device, you only need to call :cpp:func:`esp_console_new_repl_usb_serial_jtag` at first step. Then call other functions as usual.
|
|
||||||
|
|
||||||
Application Examples
|
Application Examples
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@@ -102,21 +102,6 @@ void app_main(void)
|
|||||||
#endif
|
#endif
|
||||||
register_nvs();
|
register_nvs();
|
||||||
|
|
||||||
#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM)
|
ESP_ERROR_CHECK(esp_console_new_repl_stdio(&repl_config, &repl));
|
||||||
esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
|
||||||
ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl));
|
|
||||||
|
|
||||||
#elif defined(CONFIG_ESP_CONSOLE_USB_CDC)
|
|
||||||
esp_console_dev_usb_cdc_config_t hw_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
|
|
||||||
ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&hw_config, &repl_config, &repl));
|
|
||||||
|
|
||||||
#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)
|
|
||||||
esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
|
||||||
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl));
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error Unsupported console type
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user