Merge branch 'refactor/esp_driver_uart' into 'master'

refactor(uart): make uart driver as component

Closes IDF-8384

See merge request espressif/esp-idf!27333
This commit is contained in:
Song Ruo Jing
2023-12-18 19:16:34 +08:00
88 changed files with 926 additions and 628 deletions

View File

@@ -63,8 +63,7 @@ endif()
idf_component_register(SRCS "${srcs}" idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}" INCLUDE_DIRS "${include_dirs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}"
PRIV_REQUIRES soc esp_driver_gptimer esp_driver_gpio PRIV_REQUIRES esp_driver_gptimer esp_driver_gpio esp_driver_uart
driver # TODO: replace with esp_driver_uart (IDF-8384)
REQUIRES esp_timer REQUIRES esp_timer
LDFRAGMENTS linker.lf) LDFRAGMENTS linker.lf)

View File

@@ -789,7 +789,7 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}" INCLUDE_DIRS "${include_dirs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}"
REQUIRES esp_timer esp_wifi REQUIRES esp_timer esp_wifi
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls esp_driver_uart vfs esp_ringbuf
LDFRAGMENTS "${ldfragments}") LDFRAGMENTS "${ldfragments}")
if(CONFIG_BT_ENABLED) if(CONFIG_BT_ENABLED)

View File

@@ -28,4 +28,6 @@ idf_component_register(SRCS "commands.c"
${argtable_srcs} ${argtable_srcs}
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
REQUIRES vfs REQUIRES vfs
PRIV_REQUIRES driver) PRIV_REQUIRES esp_driver_uart
driver # to be replaced by esp_driver_usj
)

View File

@@ -18,6 +18,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "driver/uart_vfs.h"
#include "driver/usb_serial_jtag.h" #include "driver/usb_serial_jtag.h"
#include "linenoise/linenoise.h" #include "linenoise/linenoise.h"
@@ -224,9 +225,9 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
fsync(fileno(stdout)); fsync(fileno(stdout));
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
esp_vfs_dev_uart_port_set_rx_line_endings(dev_config->channel, ESP_LINE_ENDINGS_CR); 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' */ /* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(dev_config->channel, ESP_LINE_ENDINGS_CRLF); 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 /* 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. * correct while APB frequency is changing in light sleep mode.
@@ -261,7 +262,7 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
} }
/* Tell VFS to use UART driver */ /* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(dev_config->channel); 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);
@@ -423,7 +424,7 @@ static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl)
} }
repl_com->state = CONSOLE_REPL_STATE_DEINIT; repl_com->state = CONSOLE_REPL_STATE_DEINIT;
esp_console_deinit(); esp_console_deinit();
esp_vfs_dev_uart_use_nonblocking(uart_repl->uart_channel); uart_vfs_dev_use_nonblocking(uart_repl->uart_channel);
uart_driver_delete(uart_repl->uart_channel); uart_driver_delete(uart_repl->uart_channel);
free(uart_repl); free(uart_repl);
_exit: _exit:

View File

@@ -14,7 +14,6 @@ set(includes "deprecated"
"parlio/include" "parlio/include"
"touch_sensor/include" "touch_sensor/include"
"twai/include" "twai/include"
"uart/include"
"usb_serial_jtag/include") "usb_serial_jtag/include")
# Always included linker fragments # Always included linker fragments
@@ -101,13 +100,6 @@ if(CONFIG_SOC_TWAI_SUPPORTED)
list(APPEND ldfragments "twai/linker.lf") list(APPEND ldfragments "twai/linker.lf")
endif() endif()
# UART related source files
if(CONFIG_SOC_UART_SUPPORTED)
list(APPEND srcs "uart/uart.c")
list(APPEND ldfragments "uart/linker.lf")
endif()
# USB Serial JTAG related source files # USB Serial JTAG related source files
if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED) if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED)
list(APPEND srcs "usb_serial_jtag/usb_serial_jtag.c" list(APPEND srcs "usb_serial_jtag/usb_serial_jtag.c"
@@ -135,6 +127,7 @@ else()
esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi esp_driver_mcpwm esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi esp_driver_mcpwm
esp_driver_ana_cmpr esp_driver_i2s esp_driver_sdmmc esp_driver_sdspi esp_driver_sdio esp_driver_ana_cmpr esp_driver_i2s esp_driver_sdmmc esp_driver_sdspi esp_driver_sdio
esp_driver_dac esp_driver_rmt esp_driver_tsens esp_driver_sdm esp_driver_i2c esp_driver_dac esp_driver_rmt esp_driver_tsens esp_driver_sdm esp_driver_i2c
esp_driver_uart
LDFRAGMENTS ${ldfragments} LDFRAGMENTS ${ldfragments}
) )
endif() endif()

View File

@@ -64,8 +64,6 @@ menu "Driver Configurations"
orsource "./twai/Kconfig.twai" orsource "./twai/Kconfig.twai"
orsource "./uart/Kconfig.uart"
menu "USB Serial/JTAG Configuration" menu "USB Serial/JTAG Configuration"
depends on SOC_USB_SERIAL_JTAG_SUPPORTED depends on SOC_USB_SERIAL_JTAG_SUPPORTED
config USJ_NO_AUTO_LS_ON_CONNECTION config USJ_NO_AUTO_LS_ON_CONNECTION

View File

@@ -78,14 +78,6 @@ components/driver/test_apps/parlio:
temporary: true temporary: true
reason: lack of runner reason: lack of runner
components/driver/test_apps/rs485:
disable:
- if: SOC_UART_SUPPORTED != 1
disable_test:
- if: IDF_TARGET != "esp32"
temporary: true
reason: lack of runners
components/driver/test_apps/touch_sensor_v1: components/driver/test_apps/touch_sensor_v1:
disable: disable:
- if: SOC_TOUCH_SENSOR_VERSION != 1 - if: SOC_TOUCH_SENSOR_VERSION != 1
@@ -98,10 +90,6 @@ components/driver/test_apps/twai:
disable: disable:
- if: SOC_TWAI_SUPPORTED != 1 - if: SOC_TWAI_SUPPORTED != 1
components/driver/test_apps/uart:
disable:
- if: SOC_UART_SUPPORTED != 1
components/driver/test_apps/usb_serial_jtag: components/driver/test_apps/usb_serial_jtag:
disable: disable:
- if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1 - if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1

View File

@@ -1,5 +0,0 @@
[mapping:uart_hal]
archive: libhal.a
entries:
if UART_ISR_IN_IRAM = y:
uart_hal_iram (noflash)

View File

@@ -8,3 +8,5 @@ components/esp_driver_gpio/test_apps/gpio_extensions:
enable: enable:
- if: SOC_DEDICATED_GPIO_SUPPORTED == 1 - if: SOC_DEDICATED_GPIO_SUPPORTED == 1
- if: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER == 1 or SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0 - if: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER == 1 or SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0
depends_components:
- esp_driver_gpio

View File

@@ -11,6 +11,6 @@ endif()
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${public_include} INCLUDE_DIRS ${public_include}
PRIV_REQUIRES "esp_pm" REQUIRES "esp_pm"
LDFRAGMENTS "linker.lf" LDFRAGMENTS "linker.lf"
) )

View File

@@ -0,0 +1,19 @@
set(srcs)
set(public_include "include")
if(CONFIG_SOC_UART_SUPPORTED)
list(APPEND srcs "src/uart.c")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${public_include}
PRIV_REQUIRES esp_pm esp_driver_gpio esp_ringbuf
LDFRAGMENTS "linker.lf"
)
if(CONFIG_VFS_SUPPORT_IO)
target_link_libraries(${COMPONENT_LIB} PUBLIC idf::vfs)
target_sources(${COMPONENT_LIB} PRIVATE "src/uart_vfs.c")
if(CONFIG_ESP_CONSOLE_UART)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u uart_vfs_include_dev_init")
endif()
endif()

View File

@@ -1,4 +1,4 @@
menu "UART Configuration" menu "ESP-Driver:UART Configurations"
config UART_ISR_IN_IRAM config UART_ISR_IN_IRAM
bool "Place UART ISR function into IRAM" bool "Place UART ISR function into IRAM"
@@ -9,4 +9,4 @@ menu "UART Configuration"
If this option is not selected, UART interrupt will be disabled for a long time and If this option is not selected, UART interrupt will be disabled for a long time and
may cause data lost when doing spi flash operation. may cause data lost when doing spi flash operation.
endmenu # UART Configuration endmenu

View File

@@ -14,10 +14,7 @@ extern "C" {
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/ringbuf.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
/* @brief When calling `uart_set_pin`, instead of GPIO number, `UART_PIN_NO_CHANGE` /* @brief When calling `uart_set_pin`, instead of GPIO number, `UART_PIN_NO_CHANGE`

View File

@@ -0,0 +1,84 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_vfs_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Add /dev/uart virtual filesystem driver
*
* This function is called from startup code to enable serial output
*/
void uart_vfs_dev_register(void);
/**
* @brief Set the line endings expected to be received on specified UART
*
* This specifies the conversion between line endings received on UART and
* newlines ('\n', LF) passed into stdin:
*
* - ESP_LINE_ENDINGS_CRLF: convert CRLF to LF
* - ESP_LINE_ENDINGS_CR: convert CR to LF
* - ESP_LINE_ENDINGS_LF: no modification
*
* @note this function is not thread safe w.r.t. reading from UART
*
* @param uart_num the UART number
* @param mode line endings to send to UART
*
* @return 0 if successed, or -1
* when an error (specified by errno) have occurred.
*/
int uart_vfs_dev_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode);
/**
* @brief Set the line endings to sent to specified UART
*
* This specifies the conversion between newlines ('\n', LF) on stdout and line
* endings sent over UART:
*
* - ESP_LINE_ENDINGS_CRLF: convert LF to CRLF
* - ESP_LINE_ENDINGS_CR: convert LF to CR
* - ESP_LINE_ENDINGS_LF: no modification
*
* @note this function is not thread safe w.r.t. writing to UART
*
* @param uart_num the UART number
* @param mode line endings to send to UART
*
* @return 0 if successed, or -1
* when an error (specified by errno) have occurred.
*/
int uart_vfs_dev_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode);
/**
* @brief set VFS to use simple functions for reading and writing UART
*
* Read is non-blocking, write is busy waiting until TX FIFO has enough space.
* These functions are used by default.
*
* @param uart_num UART peripheral number
*/
void uart_vfs_dev_use_nonblocking(int uart_num);
/**
* @brief set VFS to use UART driver for reading and writing
*
* @note Application must configure UART driver before calling these functions
* With these functions, read and write are blocking and interrupt-driven.
*
* @param uart_num UART peripheral number
*/
void uart_vfs_dev_use_driver(int uart_num);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,11 @@
[mapping:uart_vfs]
archive: libesp_driver_uart.a
entries:
if VFS_SELECT_IN_RAM = y:
uart_vfs: select_notif_callback_isr (noflash)
[mapping:uart_hal]
archive: libhal.a
entries:
if UART_ISR_IN_IRAM = y:
uart_hal_iram (noflash)

View File

@@ -11,7 +11,6 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_check.h" #include "esp_check.h"
#include "malloc.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
@@ -20,7 +19,6 @@
#include "esp_private/critical_section.h" #include "esp_private/critical_section.h"
#include "hal/uart_hal.h" #include "hal/uart_hal.h"
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/uart_periph.h" #include "soc/uart_periph.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "driver/gpio.h" #include "driver/gpio.h"
@@ -28,7 +26,6 @@
#include "driver/uart_select.h" #include "driver/uart_select.h"
#include "driver/lp_io.h" #include "driver/lp_io.h"
#include "esp_private/uart_share_hw_ctrl.h" #include "esp_private/uart_share_hw_ctrl.h"
#include "esp_private/periph_ctrl.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
@@ -527,7 +524,7 @@ esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int queue_length)
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error"); ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]), ESP_ERR_INVALID_STATE, UART_TAG, "uart driver error"); ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]), ESP_ERR_INVALID_STATE, UART_TAG, "uart driver error");
int *pdata = (int *) malloc(queue_length * sizeof(int)); int *pdata = (int *)heap_caps_malloc(queue_length * sizeof(int), UART_MALLOC_CAPS);
if (pdata == NULL) { if (pdata == NULL) {
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }

View File

@@ -13,15 +13,15 @@
#include <sys/param.h> #include <sys/param.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_vfs.h" #include "driver/uart_vfs.h"
#include "esp_vfs_dev.h"
#include "esp_vfs_private.h"
#include "esp_rom_uart.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "driver/uart_select.h" #include "driver/uart_select.h"
#include "esp_rom_uart.h"
#include "hal/uart_ll.h" #include "hal/uart_ll.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/uart_periph.h" #include "esp_private/esp_vfs_console.h"
#include "esp_vfs_dev.h" // Old headers for the aliasing functions
#include "esp_private/startup_internal.h"
#define UART_NUM SOC_UART_HP_NUM #define UART_NUM SOC_UART_HP_NUM
@@ -44,6 +44,12 @@
# define DEFAULT_RX_MODE ESP_LINE_ENDINGS_LF # define DEFAULT_RX_MODE ESP_LINE_ENDINGS_LF
#endif #endif
#if CONFIG_VFS_SELECT_IN_RAM
#define UART_VFS_MALLOC_FLAGS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else
#define UART_VFS_MALLOC_FLAGS MALLOC_CAP_DEFAULT
#endif
// UART write bytes function type // UART write bytes function type
typedef void (*tx_func_t)(int, int); typedef void (*tx_func_t)(int, int);
// UART read bytes function type // UART read bytes function type
@@ -77,9 +83,9 @@ typedef struct {
tx_func_t tx_func; tx_func_t tx_func;
// Functions used to read bytes from UART. Default to "basic" functions. // Functions used to read bytes from UART. Default to "basic" functions.
rx_func_t rx_func; rx_func_t rx_func;
} vfs_uart_context_t; } uart_vfs_context_t;
#define VFS_CTX_DEFAULT_VAL(uart_dev) (vfs_uart_context_t) {\ #define VFS_CTX_DEFAULT_VAL(uart_dev) (uart_vfs_context_t) {\
.uart = (uart_dev),\ .uart = (uart_dev),\
.peek_char = NONE,\ .peek_char = NONE,\
.tx_mode = DEFAULT_TX_MODE,\ .tx_mode = DEFAULT_TX_MODE,\
@@ -90,7 +96,7 @@ typedef struct {
//If the context should be dynamically initialized, remove this structure //If the context should be dynamically initialized, remove this structure
//and point s_ctx to allocated data. //and point s_ctx to allocated data.
static vfs_uart_context_t s_context[UART_NUM] = { static uart_vfs_context_t s_context[UART_NUM] = {
VFS_CTX_DEFAULT_VAL(&UART0), VFS_CTX_DEFAULT_VAL(&UART0),
VFS_CTX_DEFAULT_VAL(&UART1), VFS_CTX_DEFAULT_VAL(&UART1),
#if UART_NUM > 2 #if UART_NUM > 2
@@ -98,7 +104,7 @@ static vfs_uart_context_t s_context[UART_NUM] = {
#endif #endif
}; };
static vfs_uart_context_t* s_ctx[UART_NUM] = { static uart_vfs_context_t* s_ctx[UART_NUM] = {
&s_context[0], &s_context[0],
&s_context[1], &s_context[1],
#if UART_NUM > 2 #if UART_NUM > 2
@@ -366,7 +372,7 @@ static esp_err_t register_select(uart_select_args_t *args)
portENTER_CRITICAL(&s_registered_select_lock); portENTER_CRITICAL(&s_registered_select_lock);
const int new_size = s_registered_select_num + 1; const int new_size = s_registered_select_num + 1;
uart_select_args_t **new_selects; uart_select_args_t **new_selects;
if ((new_selects = heap_caps_realloc(s_registered_selects, new_size * sizeof(uart_select_args_t *), VFS_MALLOC_FLAGS)) == NULL) { if ((new_selects = heap_caps_realloc(s_registered_selects, new_size * sizeof(uart_select_args_t *), UART_VFS_MALLOC_FLAGS)) == NULL) {
ret = ESP_ERR_NO_MEM; ret = ESP_ERR_NO_MEM;
} else { } else {
s_registered_selects = new_selects; s_registered_selects = new_selects;
@@ -392,7 +398,7 @@ static esp_err_t unregister_select(uart_select_args_t *args)
// The item is removed by overwriting it with the last item. The subsequent rellocation will drop the // The item is removed by overwriting it with the last item. The subsequent rellocation will drop the
// last item. // last item.
s_registered_selects[i] = s_registered_selects[new_size]; s_registered_selects[i] = s_registered_selects[new_size];
s_registered_selects = heap_caps_realloc(s_registered_selects, new_size * sizeof(uart_select_args_t *), VFS_MALLOC_FLAGS); s_registered_selects = heap_caps_realloc(s_registered_selects, new_size * sizeof(uart_select_args_t *), UART_VFS_MALLOC_FLAGS);
// Shrinking a buffer with realloc is guaranteed to succeed. // Shrinking a buffer with realloc is guaranteed to succeed.
s_registered_select_num = new_size; s_registered_select_num = new_size;
ret = ESP_OK; ret = ESP_OK;
@@ -449,7 +455,7 @@ static esp_err_t uart_start_select(int nfds, fd_set *readfds, fd_set *writefds,
} }
} }
uart_select_args_t *args = heap_caps_malloc(sizeof(uart_select_args_t), VFS_MALLOC_FLAGS); uart_select_args_t *args = heap_caps_malloc(sizeof(uart_select_args_t), UART_VFS_MALLOC_FLAGS);
if (args == NULL) { if (args == NULL) {
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
@@ -980,7 +986,7 @@ static int uart_tcflush(int fd, int select)
} }
#endif // CONFIG_VFS_SUPPORT_TERMIOS #endif // CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_t vfs = { static const esp_vfs_t uart_vfs = {
.flags = ESP_VFS_FLAG_DEFAULT, .flags = ESP_VFS_FLAG_DEFAULT,
.write = &uart_write, .write = &uart_write,
.open = &uart_open, .open = &uart_open,
@@ -1004,17 +1010,12 @@ static const esp_vfs_t vfs = {
#endif // CONFIG_VFS_SUPPORT_TERMIOS #endif // CONFIG_VFS_SUPPORT_TERMIOS
}; };
const esp_vfs_t* esp_vfs_uart_get_vfs(void) void uart_vfs_dev_register(void)
{ {
return &vfs; ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &uart_vfs, NULL));
} }
void esp_vfs_dev_uart_register(void) int uart_vfs_dev_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode)
{
ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &vfs, NULL));
}
int esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode)
{ {
if (uart_num < 0 || uart_num >= UART_NUM) { if (uart_num < 0 || uart_num >= UART_NUM) {
errno = EBADF; errno = EBADF;
@@ -1024,7 +1025,7 @@ int esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num, esp_line_endings_t m
return 0; return 0;
} }
int esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode) int uart_vfs_dev_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode)
{ {
if (uart_num < 0 || uart_num >= UART_NUM) { if (uart_num < 0 || uart_num >= UART_NUM) {
errno = EBADF; errno = EBADF;
@@ -1034,21 +1035,23 @@ int esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num, esp_line_endings_t m
return 0; return 0;
} }
void esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode) // Deprecated
void uart_vfs_dev_set_rx_line_endings(esp_line_endings_t mode)
{ {
for (int i = 0; i < UART_NUM; ++i) { for (int i = 0; i < UART_NUM; ++i) {
s_ctx[i]->rx_mode = mode; s_ctx[i]->rx_mode = mode;
} }
} }
void esp_vfs_dev_uart_set_tx_line_endings(esp_line_endings_t mode) // Deprecated
void uart_vfs_dev_set_tx_line_endings(esp_line_endings_t mode)
{ {
for (int i = 0; i < UART_NUM; ++i) { for (int i = 0; i < UART_NUM; ++i) {
s_ctx[i]->tx_mode = mode; s_ctx[i]->tx_mode = mode;
} }
} }
void esp_vfs_dev_uart_use_nonblocking(int uart_num) void uart_vfs_dev_use_nonblocking(int uart_num)
{ {
_lock_acquire_recursive(&s_ctx[uart_num]->read_lock); _lock_acquire_recursive(&s_ctx[uart_num]->read_lock);
_lock_acquire_recursive(&s_ctx[uart_num]->write_lock); _lock_acquire_recursive(&s_ctx[uart_num]->write_lock);
@@ -1058,7 +1061,7 @@ void esp_vfs_dev_uart_use_nonblocking(int uart_num)
_lock_release_recursive(&s_ctx[uart_num]->read_lock); _lock_release_recursive(&s_ctx[uart_num]->read_lock);
} }
void esp_vfs_dev_uart_use_driver(int uart_num) void uart_vfs_dev_use_driver(int uart_num)
{ {
_lock_acquire_recursive(&s_ctx[uart_num]->read_lock); _lock_acquire_recursive(&s_ctx[uart_num]->read_lock);
_lock_acquire_recursive(&s_ctx[uart_num]->write_lock); _lock_acquire_recursive(&s_ctx[uart_num]->write_lock);
@@ -1067,3 +1070,32 @@ void esp_vfs_dev_uart_use_driver(int uart_num)
_lock_release_recursive(&s_ctx[uart_num]->write_lock); _lock_release_recursive(&s_ctx[uart_num]->write_lock);
_lock_release_recursive(&s_ctx[uart_num]->read_lock); _lock_release_recursive(&s_ctx[uart_num]->read_lock);
} }
#if CONFIG_VFS_SUPPORT_IO && CONFIG_ESP_CONSOLE_UART
ESP_SYSTEM_INIT_FN(init_vfs_uart, CORE, BIT(0), 110)
{
esp_vfs_set_primary_dev_vfs_def_struct(&uart_vfs);
return ESP_OK;
}
#endif
void uart_vfs_include_dev_init(void)
{
// Linker hook function, exists to make the linker examine this file
}
// -------------------------- esp_vfs_dev_uart_xxx ALIAS (deprecated) ----------------------------
void esp_vfs_dev_uart_register(void) __attribute__((alias("uart_vfs_dev_register")));
void esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode) __attribute__((alias("uart_vfs_dev_set_rx_line_endings")));
void esp_vfs_dev_uart_set_tx_line_endings(esp_line_endings_t mode) __attribute__((alias("uart_vfs_dev_set_tx_line_endings")));
int esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode) __attribute__((alias("uart_vfs_dev_port_set_rx_line_endings")));
int esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode) __attribute__((alias("uart_vfs_dev_port_set_tx_line_endings")));
void esp_vfs_dev_uart_use_nonblocking(int uart_num) __attribute__((alias("uart_vfs_dev_use_nonblocking")));
void esp_vfs_dev_uart_use_driver(int uart_num) __attribute__((alias("uart_vfs_dev_use_driver")));

View File

@@ -0,0 +1,24 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/esp_driver_uart/test_apps/rs485:
disable:
- if: SOC_UART_SUPPORTED != 1
disable_test:
- if: IDF_TARGET != "esp32"
temporary: true
reason: lack of runners
depends_components:
- esp_driver_uart
- esp_driver_gpio
components/esp_driver_uart/test_apps/uart:
disable:
- if: SOC_UART_SUPPORTED != 1
depends_components:
- esp_driver_uart
- esp_driver_gpio
components/esp_driver_uart/test_apps/uart_vfs:
depends_components:
- esp_driver_uart
- vfs

View File

@@ -2,6 +2,6 @@
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register( idf_component_register(
SRCS "test_app_main.c" "test_rs485.c" SRCS "test_app_main.c" "test_rs485.c"
REQUIRES driver unity test_utils REQUIRES esp_driver_uart unity test_utils
WHOLE_ARCHIVE WHOLE_ARCHIVE
) )

View File

@@ -5,30 +5,21 @@
*/ */
#include "unity.h" #include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils.h" #include "unity_test_utils.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define TEST_MEMORY_LEAK_THRESHOLD (200) #define TEST_MEMORY_LEAK_THRESHOLD (200)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void) void setUp(void)
{ {
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); unity_utils_record_free_mem();
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
} }
void tearDown(void) void tearDown(void)
{ {
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
printf("\n");
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
} }
void app_main(void) void app_main(void)

View File

@@ -111,7 +111,6 @@ static const uint8_t crc_low[] = {
0x40 0x40
}; };
// Calculate buffer checksum using tables // Calculate buffer checksum using tables
// The checksum CRC16 algorithm is specific // The checksum CRC16 algorithm is specific
// for Modbus standard and uses polynomial value = 0xA001 // for Modbus standard and uses polynomial value = 0xA001
@@ -123,8 +122,7 @@ static uint16_t get_buffer_crc16( uint8_t * frame_ptr, uint16_t length )
uint8_t crc_low_byte = 0xFF; uint8_t crc_low_byte = 0xFF;
int index; int index;
while ( length-- ) while (length--) {
{
index = crc_low_byte ^ *(frame_ptr++); index = crc_low_byte ^ *(frame_ptr++);
crc_low_byte = crc_hi_byte ^ crc_hi[index]; crc_low_byte = crc_hi_byte ^ crc_hi[index];
crc_hi_byte = crc_low[index]; crc_hi_byte = crc_low[index];
@@ -268,8 +266,7 @@ static void rs485_master(void)
err_count++; err_count++;
printf("Errors: %d\r\n", err_count); printf("Errors: %d\r\n", err_count);
} }
} } else {
else {
printf("Incorrect answer from slave, length = %d.\r\n", len); printf("Incorrect answer from slave, length = %d.\r\n", len);
err_count++; err_count++;
} }

View File

@@ -12,7 +12,7 @@ project(uart_test)
if(CONFIG_COMPILER_DUMP_RTL_FILES) if(CONFIG_COMPILER_DUMP_RTL_FILES)
add_custom_target(check_test_app_sections ALL add_custom_target(check_test_app_sections ALL
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_uart/,${CMAKE_BINARY_DIR}/esp-idf/hal/
--elf-file ${CMAKE_BINARY_DIR}/uart_test.elf --elf-file ${CMAKE_BINARY_DIR}/uart_test.elf
find-refs find-refs
--from-sections=.iram0.text --from-sections=.iram0.text

View File

@@ -2,6 +2,6 @@
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register( idf_component_register(
SRCS "test_app_main.c" "test_uart.c" SRCS "test_app_main.c" "test_uart.c"
REQUIRES driver unity REQUIRES esp_driver_uart unity esp_psram
WHOLE_ARCHIVE WHOLE_ARCHIVE
) )

View File

@@ -5,29 +5,21 @@
*/ */
#include "unity.h" #include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils.h" #include "unity_test_utils.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define TEST_MEMORY_LEAK_THRESHOLD (200) #define TEST_MEMORY_LEAK_THRESHOLD (200)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void) void setUp(void)
{ {
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); unity_utils_record_free_mem();
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
} }
void tearDown(void) void tearDown(void)
{ {
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
printf("\n");
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
} }
void app_main(void) void app_main(void)

View File

@@ -5,6 +5,7 @@ import pytest
@pytest.mark.supported_targets @pytest.mark.supported_targets
@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='skip due to duplication with test_uart_single_dev_psram')
@pytest.mark.generic @pytest.mark.generic
@pytest.mark.parametrize( @pytest.mark.parametrize(
'config', 'config',
@@ -16,3 +17,17 @@ import pytest
) )
def test_uart_single_dev(case_tester) -> None: # type: ignore def test_uart_single_dev(case_tester) -> None: # type: ignore
case_tester.run_all_normal_cases(reset=True) case_tester.run_all_normal_cases(reset=True)
@pytest.mark.esp32s3
@pytest.mark.octal_psram
@pytest.mark.parametrize(
'config',
[
'iram_safe',
'release',
],
indirect=True,
)
def test_uart_single_dev_psram(case_tester) -> None: # type: ignore
case_tester.run_all_normal_cases(reset=True)

View File

@@ -0,0 +1,4 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_SPEED_80M=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0

View File

@@ -0,0 +1,11 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults")
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(uart_vfs_test)

View File

@@ -0,0 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |

View File

@@ -0,0 +1,9 @@
set(src "test_app_main.c"
"test_vfs_uart.c"
)
idf_component_register(SRCS ${src}
PRIV_INCLUDE_DIRS .
PRIV_REQUIRES esp_driver_uart unity test_utils esp_psram
WHOLE_ARCHIVE
)

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
// Some resources are lazy allocated, the threadhold is left for that case
#define TEST_MEMORY_LEAK_THRESHOLD (400)
void setUp(void)
{
unity_utils_record_free_mem();
}
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
unity_run_menu();
}

View File

@@ -10,15 +10,15 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/termios.h> #include <sys/termios.h>
#include <sys/errno.h> #include <sys/errno.h>
#include <unistd.h>
#include "unity.h" #include "unity.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "driver/uart_vfs.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "hal/uart_ll.h" #include "hal/uart_ll.h"
#include "esp_vfs_dev.h"
#include "esp_vfs.h"
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#include "test_utils.h" #include "test_utils.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@@ -45,7 +45,7 @@ static void flush_stdin_stdout(void)
esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
} }
TEST_CASE("can read from stdin", "[vfs]") TEST_CASE("can read from stdin", "[vfs_uart]")
{ {
flush_stdin_stdout(); flush_stdin_stdout();
@@ -68,11 +68,10 @@ TEST_CASE("can read from stdin", "[vfs]")
free(buf); free(buf);
} }
TEST_CASE("CRs are removed from the stdin correctly", "[vfs_uart]")
TEST_CASE("CRs are removed from the stdin correctly", "[vfs]")
{ {
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
flush_stdin_stdout(); flush_stdin_stdout();
const char* send_str = "1234567890\n\r123\r\n4\n"; const char* send_str = "1234567890\n\r123\r\n4\n";
@@ -155,7 +154,7 @@ static void write_task_fn(void* varg)
vTaskDelete(NULL); vTaskDelete(NULL);
} }
TEST_CASE("can write to UART while another task is reading", "[vfs]") TEST_CASE("can write to UART while another task is reading", "[vfs_uart]")
{ {
char out_buffer[32]; char out_buffer[32];
size_t out_buffer_len = sizeof(out_buffer); size_t out_buffer_len = sizeof(out_buffer);
@@ -175,14 +174,12 @@ TEST_CASE("can write to UART while another task is reading", "[vfs]")
ESP_ERROR_CHECK(uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, ESP_ERROR_CHECK(uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0)); 256, 0, 0, NULL, 0));
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
xTaskCreate(&read_task_fn, "vfs_read", 4096, &read_arg, 5, NULL); xTaskCreate(&read_task_fn, "vfs_read", 4096, &read_arg, 5, NULL);
vTaskDelay(10); vTaskDelay(10);
xTaskCreate(&write_task_fn, "vfs_write", 4096, &write_arg, 6, NULL); xTaskCreate(&write_task_fn, "vfs_write", 4096, &write_arg, 6, NULL);
int res = xSemaphoreTake(write_arg.done, 100 / portTICK_PERIOD_MS); int res = xSemaphoreTake(write_arg.done, 100 / portTICK_PERIOD_MS);
TEST_ASSERT(res); TEST_ASSERT(res);
@@ -191,13 +188,14 @@ TEST_CASE("can write to UART while another task is reading", "[vfs]")
TEST_ASSERT_EQUAL(0, strcmp(write_arg.str, read_arg.out_buffer)); TEST_ASSERT_EQUAL(0, strcmp(write_arg.str, read_arg.out_buffer));
esp_vfs_dev_uart_use_nonblocking(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_nonblocking(CONFIG_ESP_CONSOLE_UART_NUM);
uart_driver_delete(CONFIG_ESP_CONSOLE_UART_NUM); uart_driver_delete(CONFIG_ESP_CONSOLE_UART_NUM);
vSemaphoreDelete(read_arg.done); vSemaphoreDelete(read_arg.done);
vSemaphoreDelete(write_arg.done); vSemaphoreDelete(write_arg.done);
vTaskDelay(2); // wait for tasks to exit
} }
TEST_CASE("fcntl supported in UART VFS", "[vfs]") TEST_CASE("fcntl supported in UART VFS", "[vfs_uart]")
{ {
int flags = fcntl(STDIN_FILENO, F_GETFL, 0); int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
TEST_ASSERT_NOT_EQUAL(-1, flags); TEST_ASSERT_NOT_EQUAL(-1, flags);
@@ -209,7 +207,7 @@ TEST_CASE("fcntl supported in UART VFS", "[vfs]")
} }
#ifdef CONFIG_VFS_SUPPORT_TERMIOS #ifdef CONFIG_VFS_SUPPORT_TERMIOS
TEST_CASE("Can use termios for UART", "[vfs]") TEST_CASE("Can use termios for UART", "[vfs_uart]")
{ {
uint32_t clk_src_hz = 0; uint32_t clk_src_hz = 0;
TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)UART_SCLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz)); TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)UART_SCLK_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz));
@@ -226,7 +224,7 @@ TEST_CASE("Can use termios for UART", "[vfs]")
const int uart_fd = open("/dev/uart/1", O_RDWR); const int uart_fd = open("/dev/uart/1", O_RDWR);
TEST_ASSERT_NOT_EQUAL_MESSAGE(uart_fd, -1, "Cannot open UART"); TEST_ASSERT_NOT_EQUAL_MESSAGE(uart_fd, -1, "Cannot open UART");
esp_vfs_dev_uart_use_driver(1); uart_vfs_dev_use_driver(1);
TEST_ASSERT_EQUAL(-1, tcgetattr(uart_fd, NULL)); TEST_ASSERT_EQUAL(-1, tcgetattr(uart_fd, NULL));
TEST_ASSERT_EQUAL(EINVAL, errno); TEST_ASSERT_EQUAL(EINVAL, errno);
@@ -343,7 +341,7 @@ TEST_CASE("Can use termios for UART", "[vfs]")
memset(&tios_result, 0xFF, sizeof(struct termios)); memset(&tios_result, 0xFF, sizeof(struct termios));
} }
esp_vfs_dev_uart_use_nonblocking(1); uart_vfs_dev_use_nonblocking(1);
close(uart_fd); close(uart_fd);
uart_driver_delete(UART_NUM_1); uart_driver_delete(UART_NUM_1);
} }

View File

@@ -0,0 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs, data, nvs, 0x9000, 0x6000,
factory, 0, 0, 0x10000, 1M
flash_test, data, fat, , 528K
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3 nvs, data, nvs, 0x9000, 0x6000,
4 factory, 0, 0, 0x10000, 1M
5 flash_test, data, fat, , 528K

View File

@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.supported_targets
@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='skip due to duplication with test_uart_vfs_psram')
@pytest.mark.generic
@pytest.mark.parametrize('config', [
'default', 'iram',
], indirect=True)
def test_uart_vfs_default(dut: Dut) -> None:
dut.run_all_single_board_cases()
@pytest.mark.esp32s3
@pytest.mark.quad_psram
@pytest.mark.parametrize('config', [
'default', 'iram',
], indirect=True)
def test_uart_vfs_psram(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@@ -0,0 +1 @@
CONFIG_UART_ISR_IN_IRAM=y

View File

@@ -0,0 +1,9 @@
# Enable Unity fixture support
CONFIG_UNITY_ENABLE_FIXTURE=n
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
# Custom partition table for this test app
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_ESP_TASK_WDT_INIT=n

View File

@@ -0,0 +1,3 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y

View File

@@ -19,5 +19,5 @@ endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf, # In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
REQUIRES unity driver test_utils efuse REQUIRES unity esp_driver_gpio esp_driver_gptimer esp_driver_uart test_utils efuse
WHOLE_ARCHIVE) WHOLE_ARCHIVE)

View File

@@ -4,5 +4,5 @@ set(srcs "test_app_main.c"
# In order for the cases defined by `TEST_CASE` to be linked into the final elf, # In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity driver PRIV_REQUIRES unity esp_driver_uart
WHOLE_ARCHIVE) WHOLE_ARCHIVE)

View File

@@ -4,5 +4,5 @@ set(srcs "test_app_main.c"
# In order for the cases defined by `TEST_CASE` to be linked into the final elf, # In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
REQUIRES unity driver test_utils REQUIRES unity esp_driver_gpio test_utils
WHOLE_ARCHIVE) WHOLE_ARCHIVE)

View File

@@ -4,5 +4,5 @@ set(srcs "test_app_main.c"
# In order for the cases defined by `TEST_CASE` to be linked into the final elf, # In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity driver PRIV_REQUIRES unity esp_driver_uart driver
WHOLE_ARCHIVE) WHOLE_ARCHIVE)

View File

@@ -52,11 +52,6 @@
#include "esp_private/pm_impl.h" #include "esp_private/pm_impl.h"
#endif #endif
#if CONFIG_VFS_SUPPORT_IO
#include "esp_vfs_dev.h"
#include "esp_vfs_console.h"
#endif
#include "esp_pthread.h" #include "esp_pthread.h"
#include "esp_private/esp_clk.h" #include "esp_private/esp_clk.h"
#include "esp_private/spi_flash_os.h" #include "esp_private/spi_flash_os.h"
@@ -135,12 +130,6 @@ ESP_SYSTEM_INIT_FN(init_timer, CORE, BIT(0), 101)
return ESP_OK; return ESP_OK;
} }
ESP_SYSTEM_INIT_FN(init_newlib, CORE, BIT(0), 102)
{
esp_newlib_init();
return ESP_OK;
}
ESP_SYSTEM_INIT_FN(init_psram_heap, CORE, BIT(0), 103) ESP_SYSTEM_INIT_FN(init_psram_heap, CORE, BIT(0), 103)
{ {
#if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) #if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
@@ -174,24 +163,6 @@ ESP_SYSTEM_INIT_FN(init_newlib_time, CORE, BIT(0), 105)
return ESP_OK; return ESP_OK;
} }
#if CONFIG_VFS_SUPPORT_IO
ESP_SYSTEM_INIT_FN(init_vfs_console, CORE, BIT(0), 110)
{
// VFS console register.
return esp_vfs_console_register();
}
#endif // CONFIG_VFS_SUPPORT_IO
ESP_SYSTEM_INIT_FN(init_newlib_stdio, CORE, BIT(0), 115)
{
#if defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
esp_newlib_init_global_stdio(ESP_VFS_DEV_CONSOLE);
#else
esp_newlib_init_global_stdio(NULL);
#endif
return ESP_OK;
}
ESP_SYSTEM_INIT_FN(init_pthread, CORE, BIT(0), 120) ESP_SYSTEM_INIT_FN(init_pthread, CORE, BIT(0), 120)
{ {
return esp_pthread_init(); return esp_pthread_init();

View File

@@ -37,12 +37,17 @@ CORE: 100: init_heap in components/esp_system/startup_funcs.c on BIT(0)
# esp_timer early initialization is required for esp_timer_get_time to work. # esp_timer early initialization is required for esp_timer_get_time to work.
CORE: 101: init_timer in components/esp_system/startup_funcs.c on BIT(0) CORE: 101: init_timer in components/esp_system/startup_funcs.c on BIT(0)
CORE: 102: init_newlib in components/esp_system/startup_funcs.c on BIT(0) CORE: 102: init_newlib in components/newlib/newlib_init.c on BIT(0)
CORE: 103: init_psram_heap in components/esp_system/startup_funcs.c on BIT(0) CORE: 103: init_psram_heap in components/esp_system/startup_funcs.c on BIT(0)
CORE: 104: init_brownout in components/esp_system/startup_funcs.c on BIT(0) CORE: 104: init_brownout in components/esp_system/startup_funcs.c on BIT(0)
CORE: 105: init_newlib_time in components/esp_system/startup_funcs.c on BIT(0) CORE: 105: init_newlib_time in components/esp_system/startup_funcs.c on BIT(0)
CORE: 110: init_vfs_console in components/esp_system/startup_funcs.c on BIT(0)
CORE: 115: init_newlib_stdio in components/esp_system/startup_funcs.c on BIT(0) # Peripheral-specific implementation operators should be filled first
# Then register vfs console, and follow by newlib stdio initialization
CORE: 110: init_vfs_uart in components/esp_driver_uart/src/uart_vfs.c on BIT(0)
CORE: 114: init_vfs_console in components/vfs/vfs_console.c on BIT(0)
CORE: 115: init_newlib_stdio in components/newlib/newlib_init.c on BIT(0)
CORE: 120: init_pthread in components/esp_system/startup_funcs.c on BIT(0) CORE: 120: init_pthread in components/esp_system/startup_funcs.c on BIT(0)
CORE: 130: init_flash in components/esp_system/startup_funcs.c on BIT(0) CORE: 130: init_flash in components/esp_system/startup_funcs.c on BIT(0)
CORE: 140: init_virtual_efuse in components/esp_system/startup_funcs.c on BIT(0) CORE: 140: init_virtual_efuse in components/esp_system/startup_funcs.c on BIT(0)

View File

@@ -1,6 +1,7 @@
set(requires "unity" set(requires "unity"
"test_utils" "test_utils"
"driver" "esp_driver_uart"
"esp_driver_gpio"
"esp_timer" "esp_timer"
"nvs_flash" "nvs_flash"
"esp_psram") "esp_psram")

View File

@@ -55,6 +55,9 @@ list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_pthread_impl")
list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_assert_impl") list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_assert_impl")
target_link_libraries(${COMPONENT_LIB} INTERFACE "${EXTRA_LINK_FLAGS}") target_link_libraries(${COMPONENT_LIB} INTERFACE "${EXTRA_LINK_FLAGS}")
# Forces the linker to include newlib_init.c
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u newlib_include_init_funcs")
if(CONFIG_NEWLIB_NANO_FORMAT) if(CONFIG_NEWLIB_NANO_FORMAT)
if(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(libc_dir_cmd ${CMAKE_C_COMPILER}) set(libc_dir_cmd ${CMAKE_C_COMPILER})

View File

@@ -20,6 +20,7 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_rom_caps.h" #include "esp_rom_caps.h"
#include "esp_private/startup_internal.h"
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/libc_stubs.h" #include "esp32/rom/libc_stubs.h"
@@ -176,8 +177,22 @@ void esp_newlib_init(void)
esp_newlib_locks_init(); esp_newlib_locks_init();
} }
ESP_SYSTEM_INIT_FN(init_newlib, CORE, BIT(0), 102)
{
esp_newlib_init();
return ESP_OK;
}
void esp_setup_newlib_syscalls(void) __attribute__((alias("esp_newlib_init"))); void esp_setup_newlib_syscalls(void) __attribute__((alias("esp_newlib_init")));
/**
* Postponed _GLOBAL_REENT stdio FPs initialization.
*
* Can not be a part of esp_reent_init() because stdio device may not initialized yet.
*
* Called from startup code and FreeRTOS, not intended to be called from
* application code.
*/
void esp_newlib_init_global_stdio(const char *stdio_dev) void esp_newlib_init_global_stdio(const char *stdio_dev)
{ {
if (stdio_dev == NULL) if (stdio_dev == NULL)
@@ -207,3 +222,18 @@ void esp_newlib_init_global_stdio(const char *stdio_dev)
#endif /* ESP_ROM_NEEDS_SWSETUP_WORKAROUND */ #endif /* ESP_ROM_NEEDS_SWSETUP_WORKAROUND */
} }
} }
ESP_SYSTEM_INIT_FN(init_newlib_stdio, CORE, BIT(0), 115)
{
#if defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
esp_newlib_init_global_stdio("/dev/console");
#else
esp_newlib_init_global_stdio(NULL);
#endif
return ESP_OK;
}
// Hook to force the linker to include this file
void newlib_include_init_funcs(void)
{
}

View File

@@ -196,7 +196,7 @@ idf_component_register(SRC_DIRS "${src_dirs}"
EXCLUDE_SRCS "${exclude_srcs}" EXCLUDE_SRCS "${exclude_srcs}"
INCLUDE_DIRS "${public_include_dirs}" INCLUDE_DIRS "${public_include_dirs}"
PRIV_INCLUDE_DIRS "${private_include_dirs}" PRIV_INCLUDE_DIRS "${private_include_dirs}"
REQUIRES esp_netif lwip driver REQUIRES esp_netif lwip esp_driver_uart driver
LDFRAGMENTS linker.lf LDFRAGMENTS linker.lf
PRIV_REQUIRES console esp_event esp_partition esp_timer PRIV_REQUIRES console esp_event esp_partition esp_timer
ieee802154 mbedtls nvs_flash) ieee802154 mbedtls nvs_flash)

View File

@@ -20,6 +20,7 @@
#include "esp_vfs_dev.h" #include "esp_vfs_dev.h"
#include "common/logging.hpp" #include "common/logging.hpp"
#include "driver/uart.h" #include "driver/uart.h"
#include "driver/uart_vfs.h"
#include "utils/uart.h" #include "utils/uart.h"
#include "esp_vfs_usb_serial_jtag.h" #include "esp_vfs_usb_serial_jtag.h"
#include "driver/usb_serial_jtag.h" #include "driver/usb_serial_jtag.h"
@@ -68,7 +69,7 @@ esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *conf
OT_PLAT_LOG_TAG, "uart_set_pin failed"); OT_PLAT_LOG_TAG, "uart_set_pin failed");
ESP_RETURN_ON_ERROR(uart_driver_install(config->port, ESP_OPENTHREAD_UART_BUFFER_SIZE, 0, 0, NULL, 0), ESP_RETURN_ON_ERROR(uart_driver_install(config->port, ESP_OPENTHREAD_UART_BUFFER_SIZE, 0, 0, NULL, 0),
OT_PLAT_LOG_TAG, "uart_driver_install failed"); OT_PLAT_LOG_TAG, "uart_driver_install failed");
esp_vfs_dev_uart_use_driver(config->port); uart_vfs_dev_use_driver(config->port);
return ESP_OK; return ESP_OK;
} }
@@ -90,7 +91,7 @@ esp_err_t esp_openthread_host_cli_usb_init(const esp_openthread_platform_config_
ret = usb_serial_jtag_driver_install((usb_serial_jtag_driver_config_t *)&config->host_config.host_usb_config); ret = usb_serial_jtag_driver_install((usb_serial_jtag_driver_config_t *)&config->host_config.host_usb_config);
esp_vfs_usb_serial_jtag_use_driver(); esp_vfs_usb_serial_jtag_use_driver();
esp_vfs_dev_uart_register(); uart_vfs_dev_register();
return ret; return ret;
} }
#endif #endif
@@ -113,8 +114,8 @@ esp_err_t esp_openthread_host_rcp_uart_init(const esp_openthread_platform_config
ESP_RETURN_ON_ERROR(esp_openthread_uart_init_port(&config->host_config.host_uart_config), OT_PLAT_LOG_TAG, ESP_RETURN_ON_ERROR(esp_openthread_uart_init_port(&config->host_config.host_uart_config), OT_PLAT_LOG_TAG,
"esp_openthread_uart_init_port failed"); "esp_openthread_uart_init_port failed");
esp_vfs_dev_uart_port_set_rx_line_endings(s_uart_port, ESP_LINE_ENDINGS_LF); uart_vfs_dev_port_set_rx_line_endings(s_uart_port, ESP_LINE_ENDINGS_LF);
esp_vfs_dev_uart_port_set_tx_line_endings(s_uart_port, ESP_LINE_ENDINGS_LF); uart_vfs_dev_port_set_tx_line_endings(s_uart_port, ESP_LINE_ENDINGS_LF);
snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", s_uart_port); snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", s_uart_port);
s_uart_fd = open(uart_path, O_RDWR | O_NONBLOCK); s_uart_fd = open(uart_path, O_RDWR | O_NONBLOCK);
ESP_RETURN_ON_FALSE(s_uart_fd >= 0, ESP_FAIL, OT_PLAT_LOG_TAG, "open uart_path failed"); ESP_RETURN_ON_FALSE(s_uart_fd >= 0, ESP_FAIL, OT_PLAT_LOG_TAG, "open uart_path failed");

View File

@@ -17,7 +17,7 @@
#include "esp_openthread_common_macro.h" #include "esp_openthread_common_macro.h"
#include "esp_openthread_types.h" #include "esp_openthread_types.h"
#include "esp_openthread_uart.h" #include "esp_openthread_uart.h"
#include "esp_vfs_dev.h" #include "driver/uart_vfs.h"
#include "core/common/code_utils.hpp" #include "core/common/code_utils.hpp"
#include "core/common/logging.hpp" #include "core/common/logging.hpp"
#include "driver/uart.h" #include "driver/uart.h"
@@ -265,8 +265,8 @@ esp_err_t UartSpinelInterface::InitUart(const esp_openthread_uart_config_t &radi
ESP_RETURN_ON_ERROR(esp_openthread_uart_init_port(&radio_uart_config), OT_PLAT_LOG_TAG, ESP_RETURN_ON_ERROR(esp_openthread_uart_init_port(&radio_uart_config), OT_PLAT_LOG_TAG,
"esp_openthread_uart_init_port failed"); "esp_openthread_uart_init_port failed");
// We have a driver now installed so set up the read/write functions to use driver also. // We have a driver now installed so set up the read/write functions to use driver also.
esp_vfs_dev_uart_port_set_tx_line_endings(m_uart_config.port, ESP_LINE_ENDINGS_LF); uart_vfs_dev_port_set_tx_line_endings(m_uart_config.port, ESP_LINE_ENDINGS_LF);
esp_vfs_dev_uart_port_set_rx_line_endings(m_uart_config.port, ESP_LINE_ENDINGS_LF); uart_vfs_dev_port_set_rx_line_endings(m_uart_config.port, ESP_LINE_ENDINGS_LF);
snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", radio_uart_config.port); snprintf(uart_path, sizeof(uart_path), "/dev/uart/%d", radio_uart_config.port);
m_uart_fd = open(uart_path, O_RDWR | O_NONBLOCK); m_uart_fd = open(uart_path, O_RDWR | O_NONBLOCK);

View File

@@ -6,12 +6,15 @@ endif()
list(APPEND sources "vfs.c" list(APPEND sources "vfs.c"
"vfs_eventfd.c" "vfs_eventfd.c"
"vfs_uart.c"
"vfs_semihost.c" "vfs_semihost.c"
"vfs_console.c") "vfs_console.c"
)
list(APPEND pr driver list(APPEND pr driver
esp_timer) esp_timer
# for backwards compatibility (TODO: IDF-8799)
esp_driver_uart
)
idf_component_register(SRCS ${sources} idf_component_register(SRCS ${sources}
LDFRAGMENTS "linker.lf" LDFRAGMENTS "linker.lf"
@@ -30,3 +33,8 @@ endif()
# Some newlib syscalls are implemented in vfs.c, make sure these are always # Some newlib syscalls are implemented in vfs.c, make sure these are always
# seen by the linker # seen by the linker
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u vfs_include_syscalls_impl") target_link_libraries(${COMPONENT_LIB} INTERFACE "-u vfs_include_syscalls_impl")
if(CONFIG_VFS_SUPPORT_IO)
# Make sure esp_vfs_console_register gets called at startup stage
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_vfs_include_console_register")
endif()

View File

@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "esp_vfs.h"
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_VFS_SUPPORT_IO
/**
* @brief Set the pointer of primary dev vfs.
*
* This function is called in each vfs dev driver as a system initialization function registered via ESP_SYSTEM_INIT_FN
*
* @param vfs pointer to structure esp_vfs_t
*/
void esp_vfs_set_primary_dev_vfs_def_struct(const esp_vfs_t *vfs);
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
/**
* @brief Set the pointer of secondary dev vfs.
*
* This function is called in each vfs dev driver as a system initialization function registered via ESP_SYSTEM_INIT_FN
*
* @param vfs pointer to structure esp_vfs_t
*/
void esp_vfs_set_secondary_dev_vfs_def_struct(const esp_vfs_t *vfs);
#endif //CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
#endif // CONFIG_VFS_SUPPORT_IO
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -8,12 +8,12 @@
#include "esp_err.h" #include "esp_err.h"
#define ESP_VFS_DEV_CONSOLE "/dev/console"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define ESP_VFS_DEV_CONSOLE "/dev/console"
/** /**
* @brief add uart/usb_serial_jtag/usb_otg_acmcdc virtual filesystem driver * @brief add uart/usb_serial_jtag/usb_otg_acmcdc virtual filesystem driver
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,12 +13,15 @@
extern "C" { extern "C" {
#endif #endif
/** void esp_vfs_dev_uart_register(void) __attribute__((deprecated("Please use uart_vfs_dev_register() instead")));
* @brief add /dev/uart virtual filesystem driver
* void esp_vfs_dev_uart_use_nonblocking(int uart_num) __attribute__((deprecated("Please use uart_vfs_dev_use_nonblocking() instead")));
* This function is called from startup code to enable serial output
*/ void esp_vfs_dev_uart_use_driver(int uart_num) __attribute__((deprecated("Please use uart_vfs_dev_use_driver() instead")));
void esp_vfs_dev_uart_register(void);
int esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode) __attribute__((deprecated("Please use uart_vfs_dev_port_set_rx_line_endings() instead")));
int esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode) __attribute__((deprecated("Please use uart_vfs_dev_port_set_tx_line_endings() instead")));
/** /**
* @brief Set the line endings expected to be received on UART * @brief Set the line endings expected to be received on UART
@@ -34,7 +37,7 @@ void esp_vfs_dev_uart_register(void);
* *
* @param mode line endings expected on UART * @param mode line endings expected on UART
*/ */
void esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode) __attribute__((deprecated("Please use esp_vfs_dev_uart_port_set_rx_line_endings"))); void esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode) __attribute__((deprecated("Please use uart_vfs_dev_port_set_rx_line_endings() instead")));
/** /**
* @brief Set the line endings to sent to UART * @brief Set the line endings to sent to UART
@@ -50,61 +53,7 @@ void esp_vfs_dev_uart_set_rx_line_endings(esp_line_endings_t mode) __attribute__
* *
* @param mode line endings to send to UART * @param mode line endings to send to UART
*/ */
void esp_vfs_dev_uart_set_tx_line_endings(esp_line_endings_t mode) __attribute__((deprecated("Please use esp_vfs_dev_uart_port_set_tx_line_endings"))); void esp_vfs_dev_uart_set_tx_line_endings(esp_line_endings_t mode) __attribute__((deprecated("Please use uart_vfs_dev_port_set_tx_line_endings() instead")));
/**
* @brief Set the line endings expected to be received on specified UART
*
* This specifies the conversion between line endings received on UART and
* newlines ('\n', LF) passed into stdin:
*
* - ESP_LINE_ENDINGS_CRLF: convert CRLF to LF
* - ESP_LINE_ENDINGS_CR: convert CR to LF
* - ESP_LINE_ENDINGS_LF: no modification
*
* @note this function is not thread safe w.r.t. reading from UART
*
* @param uart_num the UART number
* @param mode line endings to send to UART
* @return 0 if successed, or -1
* when an error (specified by errno) have occurred.
*/
int esp_vfs_dev_uart_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode);
/**
* @brief Set the line endings to sent to specified UART
*
* This specifies the conversion between newlines ('\n', LF) on stdout and line
* endings sent over UART:
*
* - ESP_LINE_ENDINGS_CRLF: convert LF to CRLF
* - ESP_LINE_ENDINGS_CR: convert LF to CR
* - ESP_LINE_ENDINGS_LF: no modification
*
* @note this function is not thread safe w.r.t. writing to UART
*
* @param uart_num the UART number
* @param mode line endings to send to UART
* @return 0 if successed, or -1
* when an error (specified by errno) have occurred.
*/
int esp_vfs_dev_uart_port_set_tx_line_endings(int uart_num, esp_line_endings_t mode);
/**
* @brief set VFS to use simple functions for reading and writing UART
* Read is non-blocking, write is busy waiting until TX FIFO has enough space.
* These functions are used by default.
* @param uart_num UART peripheral number
*/
void esp_vfs_dev_uart_use_nonblocking(int uart_num);
/**
* @brief set VFS to use UART driver for reading and writing
* @note application must configure UART driver before calling these functions
* With these functions, read and write are blocking and interrupt-driven.
* @param uart_num UART peripheral number
*/
void esp_vfs_dev_uart_use_driver(int uart_num);
/** /**
* @brief set VFS to use USB-SERIAL-JTAG driver for reading and writing * @brief set VFS to use USB-SERIAL-JTAG driver for reading and writing

View File

@@ -3,4 +3,3 @@ archive: libvfs.a
entries: entries:
if VFS_SELECT_IN_RAM = y: if VFS_SELECT_IN_RAM = y:
vfs:esp_vfs_select_triggered_isr (noflash) vfs:esp_vfs_select_triggered_isr (noflash)
vfs_uart:select_notif_callback_isr (noflash)

View File

@@ -13,7 +13,7 @@ extern "C" {
#endif #endif
#if CONFIG_VFS_SELECT_IN_RAM #if CONFIG_VFS_SELECT_IN_RAM
#define VFS_MALLOC_FLAGS MALLOC_CAP_INTERNAL #define VFS_MALLOC_FLAGS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else #else
#define VFS_MALLOC_FLAGS MALLOC_CAP_DEFAULT #define VFS_MALLOC_FLAGS MALLOC_CAP_DEFAULT
#endif #endif
@@ -26,17 +26,6 @@ typedef struct vfs_entry_ {
int offset; // index of this structure in s_vfs array int offset; // index of this structure in s_vfs array
} vfs_entry_t; } vfs_entry_t;
/**
* @brief get pointer of uart vfs.
*
* This function is called in vfs_console in order to get the vfs implementation
* of uart.
*
* @return pointer to structure esp_vfs_t
*/
const esp_vfs_t *esp_vfs_uart_get_vfs(void);
/** /**
* @brief get pointer of cdcacm vfs. * @brief get pointer of cdcacm vfs.
* *

View File

@@ -2,11 +2,12 @@ set(src "test_app_main.c" "test_vfs_access.c"
"test_vfs_append.c" "test_vfs_eventfd.c" "test_vfs_append.c" "test_vfs_eventfd.c"
"test_vfs_fd.c" "test_vfs_lwip.c" "test_vfs_fd.c" "test_vfs_lwip.c"
"test_vfs_open.c" "test_vfs_paths.c" "test_vfs_open.c" "test_vfs_paths.c"
"test_vfs_select.c" "test_vfs_uart.c" "test_vfs_select.c"
) )
idf_component_register(SRCS ${src} idf_component_register(SRCS ${src}
PRIV_INCLUDE_DIRS . PRIV_INCLUDE_DIRS .
PRIV_REQUIRES test_utils vfs fatfs spiffs unity lwip wear_levelling cmock driver PRIV_REQUIRES test_utils vfs fatfs spiffs unity lwip wear_levelling cmock
esp_driver_gptimer esp_driver_uart
WHOLE_ARCHIVE WHOLE_ARCHIVE
) )

View File

@@ -10,10 +10,9 @@
#include <sys/param.h> #include <sys/param.h>
#include "unity.h" #include "unity.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "soc/uart_struct.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "esp_vfs.h" #include "esp_vfs.h"
#include "esp_vfs_dev.h" #include "driver/uart_vfs.h"
#include "esp_vfs_fat.h" #include "esp_vfs_fat.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
#include "lwip/netdb.h" #include "lwip/netdb.h"
@@ -144,14 +143,14 @@ static void init(int *uart_fd, int *socket_fd)
*uart_fd = open("/dev/uart/1", O_RDWR); *uart_fd = open("/dev/uart/1", O_RDWR);
TEST_ASSERT_NOT_EQUAL_MESSAGE(*uart_fd, -1, "Cannot open UART"); TEST_ASSERT_NOT_EQUAL_MESSAGE(*uart_fd, -1, "Cannot open UART");
esp_vfs_dev_uart_use_driver(1); uart_vfs_dev_use_driver(1);
*socket_fd = socket_init(); *socket_fd = socket_init();
} }
static void deinit(int uart_fd, int socket_fd) static void deinit(int uart_fd, int socket_fd)
{ {
esp_vfs_dev_uart_use_nonblocking(1); uart_vfs_dev_use_nonblocking(1);
close(uart_fd); close(uart_fd);
uart_driver_delete(UART_NUM_1); uart_driver_delete(UART_NUM_1);

View File

@@ -1381,5 +1381,5 @@ void rewinddir(DIR* pdir)
void vfs_include_syscalls_impl(void) void vfs_include_syscalls_impl(void)
{ {
// Linker hook function, exists to make the linker examine this fine // Linker hook function, exists to make the linker examine this file
} }

View File

@@ -1,24 +1,26 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "esp_vfs_console.h" #include "esp_err.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_vfs_cdcacm.h" #include "esp_vfs_cdcacm.h"
#include "esp_vfs_private.h" #include "esp_vfs_private.h"
#include "esp_vfs_usb_serial_jtag.h" #include "esp_vfs_usb_serial_jtag.h"
#include "esp_vfs_dev.h"
#include "esp_private/usb_console.h" #include "esp_private/usb_console.h"
#include "esp_vfs_console.h"
#include "esp_private/esp_vfs_console.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_private/startup_internal.h"
#define STRINGIFY(s) STRINGIFY2(s) #define STRINGIFY(s) STRINGIFY2(s)
#define STRINGIFY2(s) #s #define STRINGIFY2(s) #s
/** /**
* This file is to concentrate all the vfs(UART, USB_SERIAL_JTAG, CDCACM) console into one single file. * This file is to concentrate all the vfs(UART, USB_SERIAL_JTAG, CDCACM) console into one single file.
* Get the vfs information from their component (i.e. vfs_uart.c) through `esp_vfs_usb_xxx_get_console()`, * Get the vfs information from their component (i.e. uart_vfs.c),
* which can help us to output some string to two different ports(i.e both through uart and usb_serial_jtag). * which can help us to output some string to two different ports(i.e both through uart and usb_serial_jtag).
* Usually, we set a port as primary and another as secondary. For primary, it is used for all the features supported by each vfs implementation, * Usually, we set a port as primary and another as secondary. For primary, it is used for all the features supported by each vfs implementation,
* while the secondary is only used for output. * while the secondary is only used for output.
@@ -43,9 +45,11 @@ const static char *primary_path = "/dev/cdcacm";
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG #if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
const static char *secondary_path = "/dev/secondary"; const static char *secondary_path = "/dev/secondary";
static int secondary_vfs_index; static int secondary_vfs_index;
const static esp_vfs_t *secondary_vfs = NULL;
#endif // Secondary part #endif // Secondary part
static int primary_vfs_index; static int primary_vfs_index;
const static esp_vfs_t *primary_vfs = NULL;
static vfs_console_context_t vfs_console= {0}; static vfs_console_context_t vfs_console= {0};
@@ -186,7 +190,7 @@ static const esp_vfs_t vfs = {
#endif // CONFIG_VFS_SUPPORT_TERMIOS #endif // CONFIG_VFS_SUPPORT_TERMIOS
}; };
esp_err_t esp_vfs_dev_console_register(void) static esp_err_t esp_vfs_dev_console_register(void)
{ {
return esp_vfs_register(ESP_VFS_DEV_CONSOLE, &vfs, NULL); return esp_vfs_register(ESP_VFS_DEV_CONSOLE, &vfs, NULL);
} }
@@ -196,27 +200,25 @@ esp_err_t esp_vfs_console_register(void)
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
// Primary register part. // Primary register part.
#ifdef CONFIG_ESP_CONSOLE_UART #ifdef CONFIG_ESP_CONSOLE_UART
const esp_vfs_t *uart_vfs = esp_vfs_uart_get_vfs(); assert(primary_vfs);
err = esp_vfs_register_common(primary_path, strlen(primary_path), uart_vfs, NULL, &primary_vfs_index);
#elif CONFIG_ESP_CONSOLE_USB_CDC #elif CONFIG_ESP_CONSOLE_USB_CDC
const esp_vfs_t *cdcacm_vfs = esp_vfs_cdcacm_get_vfs(); primary_vfs = esp_vfs_cdcacm_get_vfs();
err = esp_usb_console_init(); err = esp_usb_console_init();
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;
} }
err = esp_vfs_register_common(primary_path, strlen(primary_path), cdcacm_vfs, NULL, &primary_vfs_index);
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
const esp_vfs_t *usb_serial_jtag_vfs = esp_vfs_usb_serial_jtag_get_vfs(); primary_vfs = esp_vfs_usb_serial_jtag_get_vfs();
err = esp_vfs_register_common(primary_path, strlen(primary_path), usb_serial_jtag_vfs, NULL, &primary_vfs_index);
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG #endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
err = esp_vfs_register_common(primary_path, strlen(primary_path), primary_vfs, NULL, &primary_vfs_index);
if (err != ESP_OK) { if (err != ESP_OK) {
return err; return err;
} }
// Secondary register part. // Secondary register part.
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG #if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
const esp_vfs_t *usb_serial_jtag_vfs = esp_vfs_usb_serial_jtag_get_vfs(); secondary_vfs = esp_vfs_usb_serial_jtag_get_vfs();
err = esp_vfs_register_common(secondary_path, strlen(secondary_path), usb_serial_jtag_vfs, NULL, &secondary_vfs_index); err = esp_vfs_register_common(secondary_path, strlen(secondary_path), secondary_vfs, NULL, &secondary_vfs_index);
if(err != ESP_OK) { if(err != ESP_OK) {
return err; return err;
} }
@@ -225,4 +227,26 @@ esp_err_t esp_vfs_console_register(void)
return err; return err;
} }
void esp_vfs_set_primary_dev_vfs_def_struct(const esp_vfs_t *vfs)
{
primary_vfs = vfs;
}
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
void esp_vfs_set_secondary_dev_vfs_def_struct(const esp_vfs_t *vfs)
{
secondary_vfs = vfs;
}
#endif
ESP_SYSTEM_INIT_FN(init_vfs_console, CORE, BIT(0), 114)
{
return esp_vfs_console_register();
}
#endif // CONFIG_VFS_SUPPORT_IO #endif // CONFIG_VFS_SUPPORT_IO
void esp_vfs_include_console_register(void)
{
// Linker hook function, exists to make the linker examine this file
}

View File

@@ -78,7 +78,6 @@ INPUT = \
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \ $(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \
$(PROJECT_PATH)/components/driver/touch_sensor/include/driver/touch_sensor_common.h \ $(PROJECT_PATH)/components/driver/touch_sensor/include/driver/touch_sensor_common.h \
$(PROJECT_PATH)/components/driver/twai/include/driver/twai.h \ $(PROJECT_PATH)/components/driver/twai/include/driver/twai.h \
$(PROJECT_PATH)/components/driver/uart/include/driver/uart.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \ $(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h \ $(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \ $(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \
@@ -143,6 +142,8 @@ INPUT = \
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave_hd.h \ $(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave_hd.h \
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave.h \ $(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave.h \
$(PROJECT_PATH)/components/esp_driver_tsens/include/driver/temperature_sensor.h \ $(PROJECT_PATH)/components/esp_driver_tsens/include/driver/temperature_sensor.h \
$(PROJECT_PATH)/components/esp_driver_uart/include/driver/uart.h \
$(PROJECT_PATH)/components/esp_driver_uart/include/driver/uart_vfs.h \
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac.h \

View File

@@ -104,7 +104,7 @@ If you want to use :cpp:func:`select` with a file descriptor belonging to a non-
:cpp:func:`end_select` might be called without a previous :cpp:func:`start_select` call in some rare circumstances. :cpp:func:`end_select` should fail gracefully if this is the case (i.e., should not crash but return an error instead). :cpp:func:`end_select` might be called without a previous :cpp:func:`start_select` call in some rare circumstances. :cpp:func:`end_select` should fail gracefully if this is the case (i.e., should not crash but return an error instead).
Please refer to the reference implementation for the UART peripheral in :component_file:`vfs/vfs_uart.c` and most particularly to the functions :cpp:func:`esp_vfs_dev_uart_register`, :cpp:func:`uart_start_select`, and :cpp:func:`uart_end_select` for more information. Please refer to the reference implementation for the UART peripheral in :component_file:`esp_driver_uart/src/uart_vfs.c` and most particularly to the functions :cpp:func:`uart_vfs_dev_register`, :cpp:func:`uart_start_select`, and :cpp:func:`uart_end_select` for more information.
Please check the following examples that demonstrate the use of :cpp:func:`select` with VFS file descriptors: Please check the following examples that demonstrate the use of :cpp:func:`select` with VFS file descriptors:
@@ -189,9 +189,9 @@ Writing to ``stdout`` or ``stderr`` sends characters to the UART transmit FIFO.
By default, VFS uses simple functions for reading from and writing to UART. Writes busy-wait until all data is put into UART FIFO, and reads are non-blocking, returning only the data present in the FIFO. Due to this non-blocking read behavior, higher level C library calls, such as ``fscanf("%d\n", &var);``, might not have desired results. By default, VFS uses simple functions for reading from and writing to UART. Writes busy-wait until all data is put into UART FIFO, and reads are non-blocking, returning only the data present in the FIFO. Due to this non-blocking read behavior, higher level C library calls, such as ``fscanf("%d\n", &var);``, might not have desired results.
Applications which use the UART driver can instruct VFS to use the driver's interrupt driven, blocking read and write functions instead. This can be done using a call to the ``esp_vfs_dev_uart_use_driver`` function. It is also possible to revert to the basic non-blocking functions using a call to ``esp_vfs_dev_uart_use_nonblocking``. Applications which use the UART driver can instruct VFS to use the driver's interrupt driven, blocking read and write functions instead. This can be done using a call to the :cpp:func:`uart_vfs_dev_use_driver` function. It is also possible to revert to the basic non-blocking functions using a call to :cpp:func:`uart_vfs_dev_use_nonblocking`.
VFS also provides an optional newline conversion feature for input and output. Internally, most applications send and receive lines terminated by the LF (''\n'') character. Different terminal programs may require different line termination, such as CR or CRLF. Applications can configure this separately for input and output either via menuconfig, or by calls to the functions ``esp_vfs_dev_uart_port_set_rx_line_endings`` and ``esp_vfs_dev_uart_port_set_tx_line_endings``. VFS also provides an optional newline conversion feature for input and output. Internally, most applications send and receive lines terminated by the LF (''\n'') character. Different terminal programs may require different line termination, such as CR or CRLF. Applications can configure this separately for input and output either via menuconfig, or by calls to the functions :cpp:func:`uart_vfs_dev_port_set_rx_line_endings` and :cpp:func:`uart_vfs_dev_port_set_tx_line_endings`.
Standard Streams and FreeRTOS Tasks Standard Streams and FreeRTOS Tasks
@@ -235,4 +235,6 @@ API Reference
.. include-build-file:: inc/esp_vfs_dev.inc .. include-build-file:: inc/esp_vfs_dev.inc
.. include-build-file:: inc/uart_vfs.inc
.. include-build-file:: inc/esp_vfs_eventfd.inc .. include-build-file:: inc/esp_vfs_eventfd.inc

View File

@@ -7,4 +7,5 @@ Migration from 5.2 to 5.3
:maxdepth: 1 :maxdepth: 1
peripherals peripherals
storage
system system

View File

@@ -20,6 +20,7 @@ In order to control the dependence of other components on drivers at a smaller g
- `esp_driver_tsens` - Driver for Temperature Sensor - `esp_driver_tsens` - Driver for Temperature Sensor
- `esp_driver_sdm` - Driver for Sigma-Delta Modulator - `esp_driver_sdm` - Driver for Sigma-Delta Modulator
- `esp_driver_i2c` - Driver for I2C - `esp_driver_i2c` - Driver for I2C
- `esp_driver_uart` - Driver for UART
For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on. For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on.

View File

@@ -0,0 +1,18 @@
Storage
=======
:link_to_translation:`zh_CN:[中文]`
VFS
---
The UART implementation of VFS operators has been moved from `vfs` component to `esp_driver_uart` component.
APIs with `esp_vfs_dev_uart_` prefix are all deprecated, replaced with new APIs in `uart_vfs.h` starting with `uart_vfs_dev_` prefix. Specifically,
- ``esp_vfs_dev_uart_register`` has been renamed to ``uart_vfs_dev_register``
- ``esp_vfs_dev_uart_port_set_rx_line_endings`` has been renamed to ``uart_vfs_dev_port_set_rx_line_endings``
- ``esp_vfs_dev_uart_port_set_tx_line_endings`` has been renamed to ``uart_vfs_dev_port_set_tx_line_endings``
- ``esp_vfs_dev_uart_use_nonblocking`` has been renamed to ``uart_vfs_dev_use_nonblocking``
- ``esp_vfs_dev_uart_use_driver`` has been renamed to ``uart_vfs_dev_use_driver``
For compatibility, `vfs` component still registers `esp_driver_uart` as its private dependency. In other words, you do not need to modify the CMake file of an existing project.

View File

@@ -103,7 +103,7 @@ VFS 组件支持通过 :cpp:func:`select` 进行同步输入/输出多路复用
.. note:: .. note::
在少数情况下,在调用 :cpp:func:`end_select` 之前可能并没有调用过 :cpp:func:`start_select`。因此 :cpp:func:`end_select` 的实现必须在该情况下返回错误而不能崩溃。 在少数情况下,在调用 :cpp:func:`end_select` 之前可能并没有调用过 :cpp:func:`start_select`。因此 :cpp:func:`end_select` 的实现必须在该情况下返回错误而不能崩溃。
如需获取更多信息,请参考 :component_file:`vfs/vfs_uart.c` 中 UART 外设的 VFS 驱动,尤其是函数 :cpp:func:`esp_vfs_dev_uart_register`:cpp:func:`uart_start_select`:cpp:func:`uart_end_select` 如需获取更多信息,请参考 :component_file:`esp_driver_uart/src/uart_vfs.c` 中 UART 外设的 VFS 驱动,尤其是函数 :cpp:func:`uart_vfs_dev_register`:cpp:func:`uart_start_select`:cpp:func:`uart_end_select`
请参考以下示例,查看如何使用 VFS 文件描述符调用 :cpp:func:`select` 请参考以下示例,查看如何使用 VFS 文件描述符调用 :cpp:func:`select`
@@ -189,9 +189,9 @@ VFS 对文件路径长度没有限制,但文件系统路径前缀受 ``ESP_VFS
默认情况下VFS 使用简单的函数对 UART 进行读写操作。在所有数据放进 UART FIFO 之前,写操作将处于 busy-wait 状态,读操处于非阻塞状态,仅返回 FIFO 中已有数据。由于读操作为非阻塞,高层级 C 库函数调用(如 ``fscanf("%d\n", &var);``)可能获取不到所需结果。 默认情况下VFS 使用简单的函数对 UART 进行读写操作。在所有数据放进 UART FIFO 之前,写操作将处于 busy-wait 状态,读操处于非阻塞状态,仅返回 FIFO 中已有数据。由于读操作为非阻塞,高层级 C 库函数调用(如 ``fscanf("%d\n", &var);``)可能获取不到所需结果。
如果应用程序使用 UART 驱动,则可以调用 ``esp_vfs_dev_uart_use_driver`` 函数来指导 VFS 使用驱动中断、读写阻塞功能等,也可以调用 ``esp_vfs_dev_uart_use_nonblocking`` 来恢复非阻塞函数。 如果应用程序使用 UART 驱动,则可以调用 :cpp:func:`uart_vfs_dev_use_driver` 函数来指导 VFS 使用驱动中断、读写阻塞功能等,也可以调用 :cpp:func:`uart_vfs_dev_use_nonblocking` 来恢复非阻塞函数。
VFS 还为输入和输出提供换行符转换功能(可选)。多数应用程序在程序内部发送或接收以 LF (''\n'') 结尾的行,但不同的终端程序可能需要不同的换行符,比如 CR 或 CRLF。应用程序可以通过 menuconfig 或者调用 ``esp_vfs_dev_uart_port_set_rx_line_endings````esp_vfs_dev_uart_port_set_tx_line_endings`` 为输入输出配置换行符。 VFS 还为输入和输出提供换行符转换功能(可选)。多数应用程序在程序内部发送或接收以 LF (''\n'') 结尾的行,但不同的终端程序可能需要不同的换行符,比如 CR 或 CRLF。应用程序可以通过 menuconfig 或者调用 :cpp:func:`uart_vfs_dev_port_set_rx_line_endings`:cpp:func:`uart_vfs_dev_port_set_tx_line_endings` 为输入输出配置换行符。
标准流和 FreeRTOS 任务 标准流和 FreeRTOS 任务
@@ -235,4 +235,6 @@ API 参考
.. include-build-file:: inc/esp_vfs_dev.inc .. include-build-file:: inc/esp_vfs_dev.inc
.. include-build-file:: inc/uart_vfs.inc
.. include-build-file:: inc/esp_vfs_eventfd.inc .. include-build-file:: inc/esp_vfs_eventfd.inc

View File

@@ -7,4 +7,5 @@
:maxdepth: 1 :maxdepth: 1
peripherals peripherals
storage
system system

View File

@@ -20,6 +20,7 @@
- `esp_driver_tsens` - 温度传感器驱动 - `esp_driver_tsens` - 温度传感器驱动
- `esp_driver_sdm` - Sigma-Delta 调制器驱动 - `esp_driver_sdm` - Sigma-Delta 调制器驱动
- `esp_driver_i2c` - I2C 驱动 - `esp_driver_i2c` - I2C 驱动
- `esp_driver_uart` - UART 驱动
为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。 为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。

View File

@@ -0,0 +1,18 @@
存储
=======
:link_to_translation:`en:[English]`
VFS
---
VFS 操作符的 UART 具体实现函数从 `vfs` 组件挪到了 `esp_driver_uart` 组件中。
所有以 `esp_vfs_dev_uart_` 前缀开头的 API 已被弃用, 更新成在 `uart_vfs.h` 文件中定义的以 `uart_vfs_dev_` 为前缀的一组 API。具体来说
- ``esp_vfs_dev_uart_register`` 更名为 ``uart_vfs_dev_register``
- ``esp_vfs_dev_uart_port_set_rx_line_endings`` 更名为 ``uart_vfs_dev_port_set_rx_line_endings``
- ``esp_vfs_dev_uart_port_set_tx_line_endings`` 更名为 ``uart_vfs_dev_port_set_tx_line_endings``
- ``esp_vfs_dev_uart_use_nonblocking`` 更名为 ``uart_vfs_dev_use_nonblocking``
- ``esp_vfs_dev_uart_use_driver`` 更名为 ``uart_vfs_dev_use_driver``
为了兼容性,`vfs` 组件依旧将 `esp_driver_uart` 注册成了其私有依赖。换句话说,你无需修改既有项目的 CMake 文件。

View File

@@ -43,9 +43,9 @@ examples/bluetooth/bluedroid/classic_bt:
- vfs - vfs
- esp_driver_gpio - esp_driver_gpio
- esp_driver_i2s - esp_driver_i2s
- esp_driver_uart
depends_filepatterns: depends_filepatterns:
- components/driver/dac/**/* - components/driver/dac/**/*
- components/driver/uart/**/*
examples/bluetooth/bluedroid/coex/a2dp_gatts_coex: examples/bluetooth/bluedroid/coex/a2dp_gatts_coex:
<<: *bt_default_depends <<: *bt_default_depends
@@ -134,15 +134,15 @@ examples/bluetooth/hci/controller_hci_uart_esp32:
<<: *bt_default_depends <<: *bt_default_depends
enable: enable:
- if: IDF_TARGET == "esp32" - if: IDF_TARGET == "esp32"
depends_filepatterns: depends_components:
- components/driver/uart/**/* - esp_driver_uart
examples/bluetooth/hci/controller_hci_uart_esp32c3_and_esp32s3: examples/bluetooth/hci/controller_hci_uart_esp32c3_and_esp32s3:
<<: *bt_default_depends <<: *bt_default_depends
enable: enable:
- if: IDF_TARGET in ["esp32c3", "esp32s3"] - if: IDF_TARGET in ["esp32c3", "esp32s3"]
depends_filepatterns: depends_components:
- components/driver/uart/**/* - esp_driver_uart
# config BT_NIMBLE_ENABLED does not depends on any soc cap # config BT_NIMBLE_ENABLED does not depends on any soc cap
@@ -256,7 +256,7 @@ examples/bluetooth/nimble/throughput_app:
- if: SOC_BLE_SUPPORTED != 1 - if: SOC_BLE_SUPPORTED != 1
depends_components: depends_components:
- esp_driver_gpio - esp_driver_gpio
- esp_driver_uart
depends_filepatterns: depends_filepatterns:
- examples/bluetooth/nimble/common/**/* - examples/bluetooth/nimble/common/**/*
- examples/bluetooth/nimble/throughput_app/blecent_throughput/components/**/* - examples/bluetooth/nimble/throughput_app/blecent_throughput/components/**/*
- components/driver/uart/**/*

View File

@@ -9,7 +9,7 @@
#include "protocol_examples_common.h" #include "protocol_examples_common.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_vfs_dev.h" #include "driver/uart_vfs.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@@ -25,10 +25,10 @@ esp_err_t example_configure_stdin_stdout(void)
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM, ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) ); 256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */ /* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */ /* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
configured = true; configured = true;
return ESP_OK; return ESP_OK;
} }

View File

@@ -14,8 +14,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_vfs.h" #include "driver/uart_vfs.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h" #include "driver/uart.h"
static const char* TAG = "uart_select_example"; static const char* TAG = "uart_select_example";
@@ -48,7 +47,7 @@ static void uart_select_task(void *arg)
} }
// We have a driver now installed so set up the read/write functions to use driver also. // We have a driver now installed so set up the read/write functions to use driver also.
esp_vfs_dev_uart_use_driver(0); uart_vfs_dev_use_driver(0);
while (1) { while (1) {
int s; int s;

View File

@@ -9,10 +9,11 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "esp_system.h" #include "esp_system.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_console.h" #include "esp_console.h"
#include "esp_vfs_dev.h" #include "driver/uart_vfs.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "linenoise/linenoise.h" #include "linenoise/linenoise.h"
#include "argtable3/argtable3.h" #include "argtable3/argtable3.h"
@@ -90,9 +91,9 @@ static void initialize_console(void)
setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdin, NULL, _IONBF, 0);
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */ /* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
/* Configure UART. Note that REF_TICK is used so that the baud rate remains /* Configure UART. Note that REF_TICK is used so that the baud rate remains
* correct while APB frequency is changing in light sleep mode. * correct while APB frequency is changing in light sleep mode.
@@ -114,7 +115,7 @@ static void initialize_console(void)
ESP_ERROR_CHECK( uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config) ); ESP_ERROR_CHECK( uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config) );
/* Tell VFS to use UART driver */ /* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
/* Initialize the console */ /* Initialize the console */
esp_console_config_t console_config = { esp_console_config_t console_config = {

View File

@@ -15,8 +15,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_vfs.h" #include "driver/uart_vfs.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "esp_netif.h" #include "esp_netif.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
@@ -107,7 +106,7 @@ static void uart1_init(void)
uart1_deinit(); uart1_deinit();
} }
esp_vfs_dev_uart_use_driver(1); uart_vfs_dev_use_driver(1);
} }
static void uart1_write_task(void *param) static void uart1_write_task(void *param)

View File

@@ -65,8 +65,8 @@ examples/wifi/power_save:
<<: *wifi_depends_default <<: *wifi_depends_default
disable: disable:
- if: SOC_WIFI_SUPPORTED != 1 - if: SOC_WIFI_SUPPORTED != 1
depends_filepatterns: depends_components:
- components/driver/uart/**/* - esp_driver_uart
examples/wifi/wifi_aware: examples/wifi/wifi_aware:
disable: disable:

View File

@@ -6,7 +6,7 @@
#include <string.h> #include <string.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_vfs_dev.h" #include "driver/uart_vfs.h"
#include "driver/uart.h" #include "driver/uart.h"
#if CONFIG_EXAMPLE_GET_AP_INFO_FROM_STDIN #if CONFIG_EXAMPLE_GET_AP_INFO_FROM_STDIN
@@ -23,10 +23,10 @@ void get_ap_info_from_stdin(void)
256, 0, 0, NULL, 0) ); 256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */ /* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */ /* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
ESP_LOGI(TAG, "Input SSID:"); ESP_LOGI(TAG, "Input SSID:");
@@ -44,7 +44,7 @@ void get_ap_info_from_stdin(void)
} }
/* Back to use non-blocking vfs console*/ /* Back to use non-blocking vfs console*/
esp_vfs_dev_uart_use_nonblocking(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_nonblocking(CONFIG_ESP_CONSOLE_UART_NUM);
uart_driver_delete(CONFIG_ESP_CONSOLE_UART_NUM); uart_driver_delete(CONFIG_ESP_CONSOLE_UART_NUM);
} }
#endif #endif

View File

@@ -46,6 +46,7 @@
#include "esp_vfs_eventfd.h" #include "esp_vfs_eventfd.h"
#include "esp_vfs_dev.h" #include "esp_vfs_dev.h"
#include "esp_vfs_usb_serial_jtag.h" #include "esp_vfs_usb_serial_jtag.h"
#include "driver/uart_vfs.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "protocol_examples_common.h" #include "protocol_examples_common.h"
@@ -77,7 +78,7 @@ esp_err_t esp_zb_gateway_console_init(void)
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(); usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config); ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config);
esp_vfs_usb_serial_jtag_use_driver(); esp_vfs_usb_serial_jtag_use_driver();
esp_vfs_dev_uart_register(); uart_vfs_dev_register();
return ret; return ret;
} }
#endif #endif

View File

@@ -3,11 +3,12 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <string.h>
#include "esp_netif.h" #include "esp_netif.h"
#include "esp_log.h" #include "esp_log.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "driver/uart_vfs.h"
#include "esp_console.h" #include "esp_console.h"
#include "esp_vfs_dev.h"
#include "linenoise/linenoise.h" #include "linenoise/linenoise.h"
// //
@@ -139,10 +140,10 @@ void * netsuite_io_new(void)
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM, ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) ); 256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */ /* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */ /* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
linenoiseSetDumbMode(1); linenoiseSetDumbMode(1);
return (void *)&s_driver_base; return (void *)&s_driver_base;
} }