Merge branch 'feat/unify_vfs_api' into 'master'

feat(storage/vfs): Unify VFS API by removing context-less APIs

Closes IDF-15107

See merge request espressif/esp-idf!44161
This commit is contained in:
Tomas Rohlinek
2026-03-13 15:05:04 +01:00
19 changed files with 309 additions and 245 deletions
+25 -25
View File
@@ -147,7 +147,7 @@ static esp_err_t uart_end_select(void *end_select_args);
#endif // CONFIG_VFS_SUPPORT_SELECT
static int uart_open(const char *path, int flags, int mode)
static int uart_open(__attribute__((unused)) void *ctx, const char *path, int flags, int mode)
{
// this is fairly primitive, we should check if file is opened read only,
// and error out if write is requested
@@ -223,7 +223,7 @@ static int uart_rx_char_via_driver(int fd)
return c;
}
static ssize_t uart_write(int fd, const void * data, size_t size)
static ssize_t uart_write(__attribute__((unused)) void *ctx, int fd, const void * data, size_t size)
{
assert(fd >= 0 && fd < 3);
tx_func_t tx_func = s_ctx[fd]->tx_func;
@@ -270,7 +270,7 @@ static void uart_return_char(int fd, int c)
s_ctx[fd]->peek_char = c;
}
static ssize_t uart_read(int fd, void* data, size_t size)
static ssize_t uart_read(__attribute__((unused)) void *ctx, int fd, void* data, size_t size)
{
assert(fd >= 0 && fd < 3);
char *data_c = (char *) data;
@@ -343,7 +343,7 @@ static ssize_t uart_read(int fd, void* data, size_t size)
return -1;
}
static int uart_fstat(int fd, struct stat * st)
static int uart_fstat(__attribute__((unused)) void *ctx, int fd, struct stat * st)
{
assert(fd >= 0 && fd < 3);
memset(st, 0, sizeof(*st));
@@ -351,13 +351,13 @@ static int uart_fstat(int fd, struct stat * st)
return 0;
}
static int uart_close(int fd)
static int uart_close(__attribute__((unused)) void *ctx, int fd)
{
assert(fd >= 0 && fd < 3);
return 0;
}
static int uart_fcntl(int fd, int cmd, int arg)
static int uart_fcntl(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
assert(fd >= 0 && fd < 3);
int result = 0;
@@ -378,7 +378,7 @@ static int uart_fcntl(int fd, int cmd, int arg)
#ifdef CONFIG_VFS_SUPPORT_DIR
static int uart_access(const char *path, int amode)
static int uart_access(__attribute__((unused)) void *ctx, const char *path, int amode)
{
int ret = -1;
@@ -401,7 +401,7 @@ static int uart_access(const char *path, int amode)
#endif // CONFIG_VFS_SUPPORT_DIR
static int uart_fsync(int fd)
static int uart_fsync(__attribute__((unused)) void *ctx, int fd)
{
assert(fd >= 0 && fd < 3);
_lock_acquire_recursive(&s_ctx[fd]->write_lock);
@@ -602,7 +602,7 @@ static esp_err_t uart_end_select(void *end_select_args)
#endif // CONFIG_VFS_SUPPORT_SELECT
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
static int uart_tcsetattr(int fd, int optional_actions, const struct termios *p)
static int uart_tcsetattr(__attribute__((unused)) void *ctx, int fd, int optional_actions, const struct termios *p)
{
if (fd < 0 || fd >= UART_NUM) {
errno = EBADF;
@@ -807,7 +807,7 @@ static int uart_tcsetattr(int fd, int optional_actions, const struct termios *p)
return 0;
}
static int uart_tcgetattr(int fd, struct termios *p)
static int uart_tcgetattr(__attribute__((unused)) void *ctx, int fd, struct termios *p)
{
if (fd < 0 || fd >= UART_NUM) {
errno = EBADF;
@@ -1016,7 +1016,7 @@ static int uart_tcgetattr(int fd, struct termios *p)
return 0;
}
static int uart_tcdrain(int fd)
static int uart_tcdrain(__attribute__((unused)) void *ctx, int fd)
{
if (fd < 0 || fd >= UART_NUM) {
errno = EBADF;
@@ -1031,7 +1031,7 @@ static int uart_tcdrain(int fd)
return 0;
}
static int uart_tcflush(int fd, int select)
static int uart_tcflush(__attribute__((unused)) void *ctx, int fd, int select)
{
if (fd < 0 || fd >= UART_NUM) {
errno = EBADF;
@@ -1055,7 +1055,7 @@ static int uart_tcflush(int fd, int select)
#ifdef CONFIG_VFS_SUPPORT_DIR
static const esp_vfs_dir_ops_t s_vfs_uart_dir = {
.access = &uart_access,
.access_p = &uart_access,
};
#endif // CONFIG_VFS_SUPPORT_DIR
@@ -1068,21 +1068,21 @@ static const esp_vfs_select_ops_t s_vfs_uart_select = {
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_termios_ops_t s_vfs_uart_termios = {
.tcsetattr = &uart_tcsetattr,
.tcgetattr = &uart_tcgetattr,
.tcdrain = &uart_tcdrain,
.tcflush = &uart_tcflush,
.tcsetattr_p = &uart_tcsetattr,
.tcgetattr_p = &uart_tcgetattr,
.tcdrain_p = &uart_tcdrain,
.tcflush_p = &uart_tcflush,
};
#endif // CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_fs_ops_t s_vfs_uart = {
.write = &uart_write,
.open = &uart_open,
.fstat = &uart_fstat,
.close = &uart_close,
.read = &uart_read,
.fcntl = &uart_fcntl,
.fsync = &uart_fsync,
.write_p = &uart_write,
.open_p = &uart_open,
.fstat_p = &uart_fstat,
.close_p = &uart_close,
.read_p = &uart_read,
.fcntl_p = &uart_fcntl,
.fsync_p = &uart_fsync,
#ifdef CONFIG_VFS_SUPPORT_DIR
.dir = &s_vfs_uart_dir,
#endif // CONFIG_VFS_SUPPORT_DIR
@@ -1101,7 +1101,7 @@ const esp_vfs_fs_ops_t *esp_vfs_uart_get_vfs(void)
void uart_vfs_dev_register(void)
{
ESP_ERROR_CHECK(esp_vfs_register_fs("/dev/uart", &s_vfs_uart, ESP_VFS_FLAG_STATIC, NULL));
ESP_ERROR_CHECK(esp_vfs_register_fs("/dev/uart", &s_vfs_uart, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL));
}
int uart_vfs_dev_port_set_rx_line_endings(int uart_num, esp_line_endings_t mode)
@@ -138,7 +138,7 @@ static esp_err_t usb_serial_jtag_end_select(void *end_select_args);
#endif // CONFIG_VFS_SUPPORT_SELECT
static int usb_serial_jtag_open(const char * path, int flags, int mode)
static int usb_serial_jtag_open(__attribute__((unused)) void *ctx, const char * path, int flags, int mode)
{
s_ctx.non_blocking = ((flags & O_NONBLOCK) == O_NONBLOCK);
return USJ_LOCAL_FD;
@@ -179,7 +179,7 @@ static int usb_serial_jtag_rx_char_no_driver(int fd)
return c;
}
static ssize_t usb_serial_jtag_write(int fd, const void * data, size_t size)
static ssize_t usb_serial_jtag_write(__attribute__((unused)) void *ctx, int fd, const void * data, size_t size)
{
if (!usb_serial_jtag_is_connected()) {
// TODO: IDF-14303
@@ -227,7 +227,7 @@ static void usb_serial_jtag_return_char(int fd, int c)
s_ctx.peek_char = c;
}
static ssize_t usb_serial_jtag_read(int fd, void* data, size_t size)
static ssize_t usb_serial_jtag_read(__attribute__((unused)) void *ctx, int fd, void* data, size_t size)
{
if (!usb_serial_jtag_is_connected()) {
// TODO: IDF-14303
@@ -305,19 +305,19 @@ static ssize_t usb_serial_jtag_read(int fd, void* data, size_t size)
return -1;
}
static int usb_serial_jtag_fstat(int fd, struct stat * st)
static int usb_serial_jtag_fstat(__attribute__((unused)) void *ctx, int fd, struct stat * st)
{
memset(st, 0, sizeof(*st));
st->st_mode = S_IFCHR;
return 0;
}
static int usb_serial_jtag_close(int fd)
static int usb_serial_jtag_close(__attribute__((unused)) void *ctx, int fd)
{
return 0;
}
static int usb_serial_jtag_fcntl(int fd, int cmd, int arg)
static int usb_serial_jtag_fcntl(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
int result = 0;
if (cmd == F_GETFL) {
@@ -354,7 +354,7 @@ static int usb_serial_jtag_wait_tx_done_no_driver(int fd)
return EIO;
}
static int usb_serial_jtag_fsync(int fd)
static int usb_serial_jtag_fsync(__attribute__((unused)) void *ctx, int fd)
{
if (!usb_serial_jtag_is_connected()) {
// TODO: IDF-14303
@@ -549,7 +549,7 @@ static esp_err_t usb_serial_jtag_end_select(void *end_select_args)
#endif // CONFIG_VFS_SUPPORT_SELECT
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
static int usb_serial_jtag_tcsetattr(int fd, int optional_actions, const struct termios *p)
static int usb_serial_jtag_tcsetattr(__attribute__((unused)) void *ctx, int fd, int optional_actions, const struct termios *p)
{
if (p == NULL) {
errno = EINVAL;
@@ -561,7 +561,7 @@ static int usb_serial_jtag_tcsetattr(int fd, int optional_actions, const struct
// nothing to do
break;
case TCSADRAIN:
usb_serial_jtag_fsync(fd);
usb_serial_jtag_fsync(ctx, fd);
break;
case TCSAFLUSH:
// Not applicable.
@@ -581,7 +581,7 @@ static int usb_serial_jtag_tcsetattr(int fd, int optional_actions, const struct
return 0;
}
static int usb_serial_jtag_tcgetattr(int fd, struct termios *p)
static int usb_serial_jtag_tcgetattr(__attribute__((unused)) void *ctx, int fd, struct termios *p)
{
if (p == NULL) {
errno = EINVAL;
@@ -606,13 +606,13 @@ static int usb_serial_jtag_tcgetattr(int fd, struct termios *p)
return 0;
}
static int usb_serial_jtag_tcdrain(int fd)
static int usb_serial_jtag_tcdrain(__attribute__((unused)) void *ctx, int fd)
{
usb_serial_jtag_fsync(fd);
usb_serial_jtag_fsync(ctx, fd);
return 0;
}
static int usb_serial_jtag_tcflush(int fd, int select)
static int usb_serial_jtag_tcflush(__attribute__((unused)) void *ctx, int fd, int select)
{
//Flushing is not supported.
errno = EINVAL;
@@ -638,21 +638,21 @@ static const esp_vfs_select_ops_t s_vfs_jtag_select = {
#endif // CONFIG_VFS_SUPPORT_SELECT
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_termios_ops_t s_vfs_jtag_termios = {
.tcsetattr = &usb_serial_jtag_tcsetattr,
.tcgetattr = &usb_serial_jtag_tcgetattr,
.tcdrain = &usb_serial_jtag_tcdrain,
.tcflush = &usb_serial_jtag_tcflush,
.tcsetattr_p = &usb_serial_jtag_tcsetattr,
.tcgetattr_p = &usb_serial_jtag_tcgetattr,
.tcdrain_p = &usb_serial_jtag_tcdrain,
.tcflush_p = &usb_serial_jtag_tcflush,
};
#endif // CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_fs_ops_t s_vfs_jtag = {
.write = &usb_serial_jtag_write,
.open = &usb_serial_jtag_open,
.fstat = &usb_serial_jtag_fstat,
.close = &usb_serial_jtag_close,
.read = &usb_serial_jtag_read,
.fcntl = &usb_serial_jtag_fcntl,
.fsync = &usb_serial_jtag_fsync,
.write_p = &usb_serial_jtag_write,
.open_p = &usb_serial_jtag_open,
.fstat_p = &usb_serial_jtag_fstat,
.close_p = &usb_serial_jtag_close,
.read_p = &usb_serial_jtag_read,
.fcntl_p = &usb_serial_jtag_fcntl,
.fsync_p = &usb_serial_jtag_fsync,
#ifdef CONFIG_VFS_SUPPORT_SELECT
.select = &s_vfs_jtag_select,
@@ -671,7 +671,7 @@ const esp_vfs_fs_ops_t* esp_vfs_usb_serial_jtag_get_vfs(void)
esp_err_t usb_serial_jtag_vfs_register(void)
{
// "/dev/usb_serial_jtag" unfortunately is too long for vfs
return esp_vfs_register_fs("/dev/usbserjtag", &s_vfs_jtag, ESP_VFS_FLAG_STATIC, NULL);
return esp_vfs_register_fs("/dev/usbserjtag", &s_vfs_jtag, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL);
}
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
@@ -686,7 +686,7 @@ ESP_SYSTEM_INIT_FN(init_vfs_usj, CORE, BIT(0), 111)
ESP_SYSTEM_INIT_FN(init_vfs_usj_sec, CORE, BIT(0), 112)
{
// "/dev/seccondary_usb_serial_jtag" unfortunately is too long for vfs
esp_vfs_register_fs("/dev/secondary", &s_vfs_jtag, ESP_VFS_FLAG_STATIC, NULL);
esp_vfs_register_fs("/dev/secondary", &s_vfs_jtag, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL);
return ESP_OK;
}
#endif
+14 -14
View File
@@ -259,7 +259,7 @@ esp_err_t esp_vfs_l2tap_eth_filter_frame(l2tap_iodriver_handle driver_handle, vo
}
/* ====================== vfs ====================== */
static int l2tap_open(const char *path, int flags, int mode)
static int l2tap_open(__attribute__((unused)) void *ctx, const char *path, int flags, int mode)
{
int fd;
@@ -307,7 +307,7 @@ static int l2tap_tx_esp_err_to_errno(esp_err_t esp_err)
}
}
static ssize_t l2tap_write(int fd, const void *data, size_t size)
static ssize_t l2tap_write(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size)
{
void *eth_buff;
l2tap_extended_buff_t *ext_buff;
@@ -402,7 +402,7 @@ static int l2tap_rx_esp_err_to_errno(esp_err_t esp_err)
}
}
static ssize_t l2tap_read(int fd, void *data, size_t size)
static ssize_t l2tap_read(__attribute__((unused)) void *ctx, int fd, void *data, size_t size)
{
// fd might be in process of opening/closing (close was already called but preempted)
if (atomic_load(&s_l2tap_sockets[fd].state) != L2TAP_SOCK_STATE_OPENED) {
@@ -441,7 +441,7 @@ static ssize_t l2tap_read(int fd, void *data, size_t size)
return actual_size;
}
void l2tap_clean_task(void *task_param)
static void l2tap_clean_task(void *task_param)
{
l2tap_context_t *l2tap_socket = (l2tap_context_t *)task_param;
@@ -465,7 +465,7 @@ void l2tap_clean_task(void *task_param)
vTaskDelete(NULL);
}
static int l2tap_close(int fd)
static int l2tap_close(__attribute__((unused)) void *ctx, int fd)
{
if (atomic_load(&s_l2tap_sockets[fd].state) != L2TAP_SOCK_STATE_OPENED) {
// not valid opened fd
@@ -503,7 +503,7 @@ static bool netif_driver_matches(esp_netif_t *netif, void* driver)
return esp_netif_get_io_driver(netif) == driver;
}
static int l2tap_ioctl(int fd, int cmd, va_list args)
static int l2tap_ioctl(__attribute__((unused)) void *ctx, int fd, int cmd, va_list args)
{
esp_netif_t *esp_netif;
switch (cmd) {
@@ -608,7 +608,7 @@ static void l2tap_set_nonblocking(l2tap_context_t *l2tap_socket, bool nonblock)
l2tap_exit_critical();
}
static int l2tap_fcntl(int fd, int cmd, int arg)
static int l2tap_fcntl(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
int result = 0;
if (cmd == F_GETFL) {
@@ -801,12 +801,12 @@ static const esp_vfs_select_ops_t s_vfs_l2tap_select = {
#endif //CONFIG_VFS_SUPPORT_SELECT
static const esp_vfs_fs_ops_t s_vfs_l2tap = {
.write = &l2tap_write,
.open = &l2tap_open,
.close = &l2tap_close,
.read = &l2tap_read,
.fcntl = &l2tap_fcntl,
.ioctl = &l2tap_ioctl,
.write_p = &l2tap_write,
.open_p = &l2tap_open,
.close_p = &l2tap_close,
.read_p = &l2tap_read,
.fcntl_p = &l2tap_fcntl,
.ioctl_p = &l2tap_ioctl,
#ifdef CONFIG_VFS_SUPPORT_SELECT
.select = &s_vfs_l2tap_select,
#endif // CONFIG_VFS_SUPPORT_SELECT
@@ -823,7 +823,7 @@ esp_err_t esp_vfs_l2tap_intf_register(l2tap_vfs_config_t *config)
ESP_RETURN_ON_FALSE(!s_is_registered, ESP_ERR_INVALID_STATE, TAG, "vfs is already registered");
s_is_registered = true;
ESP_RETURN_ON_ERROR(esp_vfs_register_fs(config->base_path, &s_vfs_l2tap, ESP_VFS_FLAG_STATIC, NULL), TAG, "vfs register error");
ESP_RETURN_ON_ERROR(esp_vfs_register_fs(config->base_path, &s_vfs_l2tap, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL), TAG, "vfs register error");
return ESP_OK;
}
+25 -25
View File
@@ -60,7 +60,7 @@ static vfs_console_context_t vfs_console = {0};
static size_t s_open_count = 0;
int console_open(const char * path, int flags, int mode)
int console_open(__attribute__((unused)) void *ctx, const char * path, int flags, int mode)
{
if (s_open_count > 0) {
// Underlying fd is already open, so just increment the open count
@@ -90,7 +90,7 @@ int console_open(const char * path, int flags, int mode)
return 0;
}
ssize_t console_write(int fd, const void *data, size_t size)
ssize_t console_write(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size)
{
write(vfs_console.fd_primary, data, size);
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
@@ -99,12 +99,12 @@ ssize_t console_write(int fd, const void *data, size_t size)
return size;
}
int console_fstat(int fd, struct stat * st)
int console_fstat(__attribute__((unused)) void *ctx, int fd, struct stat * st)
{
return fstat(vfs_console.fd_primary, st);
}
int console_close(int fd)
int console_close(__attribute__((unused)) void *ctx, int fd)
{
if (s_open_count == 0) {
errno = EBADF;
@@ -126,17 +126,17 @@ int console_close(int fd)
return 0;
}
ssize_t console_read(int fd, void * dst, size_t size)
ssize_t console_read(__attribute__((unused)) void *ctx, int fd, void * dst, size_t size)
{
return read(vfs_console.fd_primary, dst, size);
}
int console_fcntl(int fd, int cmd, int arg)
int console_fcntl(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
return fcntl(vfs_console.fd_primary, cmd, arg);
}
int console_fsync(int fd)
int console_fsync(__attribute__((unused)) void *ctx, int fd)
{
const int ret_val = fsync(vfs_console.fd_primary);
#if CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
@@ -146,7 +146,7 @@ int console_fsync(int fd)
}
#ifdef CONFIG_VFS_SUPPORT_DIR
int console_access(const char *path, int amode)
int console_access(__attribute__((unused)) void *ctx, const char *path, int amode)
{
// currently only UART support DIR.
return access("/dev/uart/"STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM), amode);
@@ -179,22 +179,22 @@ esp_err_t console_end_select(void *end_select_args)
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
int console_tcsetattr(int fd, int optional_actions, const struct termios *p)
int console_tcsetattr(__attribute__((unused)) void *ctx, int fd, int optional_actions, const struct termios *p)
{
return tcsetattr(vfs_console.fd_primary, optional_actions, p);
}
int console_tcgetattr(int fd, struct termios *p)
int console_tcgetattr(__attribute__((unused)) void *ctx, int fd, struct termios *p)
{
return tcgetattr(vfs_console.fd_primary, p);
}
int console_tcdrain(int fd)
int console_tcdrain(__attribute__((unused)) void *ctx, int fd)
{
return tcdrain(vfs_console.fd_primary);
}
int console_tcflush(int fd, int select)
int console_tcflush(__attribute__((unused)) void *ctx, int fd, int select)
{
return tcflush(vfs_console.fd_primary, select);
}
@@ -202,7 +202,7 @@ int console_tcflush(int fd, int select)
#ifdef CONFIG_VFS_SUPPORT_DIR
static const esp_vfs_dir_ops_t s_vfs_console_dir = {
.access = &console_access,
.access_p = &console_access,
};
#endif // CONFIG_VFS_SUPPORT_DIR
@@ -215,21 +215,21 @@ static const esp_vfs_select_ops_t s_vfs_console_select = {
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_termios_ops_t s_vfs_console_termios = {
.tcsetattr = &console_tcsetattr,
.tcgetattr = &console_tcgetattr,
.tcdrain = &console_tcdrain,
.tcflush = &console_tcflush,
.tcsetattr_p = &console_tcsetattr,
.tcgetattr_p = &console_tcgetattr,
.tcdrain_p = &console_tcdrain,
.tcflush_p = &console_tcflush,
};
#endif // CONFIG_VFS_SUPPORT_TERMIOS
static const esp_vfs_fs_ops_t s_vfs_console = {
.write = &console_write,
.open = &console_open,
.fstat = &console_fstat,
.close = &console_close,
.read = &console_read,
.fcntl = &console_fcntl,
.fsync = &console_fsync,
.write_p = &console_write,
.open_p = &console_open,
.fstat_p = &console_fstat,
.close_p = &console_close,
.read_p = &console_read,
.fcntl_p = &console_fcntl,
.fsync_p = &console_fsync,
#ifdef CONFIG_VFS_SUPPORT_DIR
.dir = &s_vfs_console_dir,
@@ -246,7 +246,7 @@ static const esp_vfs_fs_ops_t s_vfs_console = {
static esp_err_t esp_vfs_dev_console_register(void)
{
return esp_vfs_register_fs(ESP_VFS_DEV_CONSOLE, &s_vfs_console, ESP_VFS_FLAG_STATIC, NULL);
return esp_vfs_register_fs(ESP_VFS_DEV_CONSOLE, &s_vfs_console, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL);
}
esp_err_t esp_stdio_register(void)
+15 -15
View File
@@ -78,7 +78,7 @@ static esp_err_t cdcacm_end_select(void *end_select_args);
#endif // CONFIG_VFS_SUPPORT_SELECT
static ssize_t cdcacm_write(int fd, const void *data, size_t size)
static ssize_t cdcacm_write(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size)
{
assert(fd == 0);
const char *cdata = (const char *)data;
@@ -101,7 +101,7 @@ static ssize_t cdcacm_write(int fd, const void *data, size_t size)
return size;
}
static int cdcacm_fsync(int fd)
static int cdcacm_fsync(__attribute__((unused)) void *ctx, int fd)
{
assert(fd == 0);
_lock_acquire_recursive(&s_write_lock);
@@ -110,12 +110,12 @@ static int cdcacm_fsync(int fd)
return (written < 0) ? -1 : 0;
}
static int cdcacm_open(const char *path, int flags, int mode)
static int cdcacm_open(__attribute__((unused)) void *ctx, const char *path, int flags, int mode)
{
return USB_CDC_LOCAL_FD; // fd 0
}
static int cdcacm_fstat(int fd, struct stat *st)
static int cdcacm_fstat(__attribute__((unused)) void *ctx, int fd, struct stat *st)
{
assert(fd == 0);
memset(st, 0, sizeof(*st));
@@ -123,7 +123,7 @@ static int cdcacm_fstat(int fd, struct stat *st)
return 0;
}
static int cdcacm_close(int fd)
static int cdcacm_close(__attribute__((unused)) void *ctx, int fd)
{
assert(fd == 0);
return 0;
@@ -174,7 +174,7 @@ static void cdcacm_return_char(int c)
s_peek_char = c;
}
static ssize_t cdcacm_read(int fd, void *data, size_t size)
static ssize_t cdcacm_read(__attribute__((unused)) void *ctx, int fd, void *data, size_t size)
{
assert(fd == USB_CDC_LOCAL_FD);
char *data_c = (char *) data;
@@ -289,7 +289,7 @@ static int cdcacm_disable_blocking(void)
return 0;
}
static int cdcacm_fcntl(int fd, int cmd, int arg)
static int cdcacm_fcntl(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
assert(fd == 0);
int result;
@@ -502,13 +502,13 @@ static const esp_vfs_select_ops_t s_cdcacm_vfs_select = {
#endif // CONFIG_VFS_SUPPORT_SELECT
static const esp_vfs_fs_ops_t s_cdcacm_vfs = {
.write = &cdcacm_write,
.open = &cdcacm_open,
.fstat = &cdcacm_fstat,
.close = &cdcacm_close,
.read = &cdcacm_read,
.fcntl = &cdcacm_fcntl,
.fsync = &cdcacm_fsync,
.write_p = &cdcacm_write,
.open_p = &cdcacm_open,
.fstat_p = &cdcacm_fstat,
.close_p = &cdcacm_close,
.read_p = &cdcacm_read,
.fcntl_p = &cdcacm_fcntl,
.fsync_p = &cdcacm_fsync,
#ifdef CONFIG_VFS_SUPPORT_SELECT
.select = &s_cdcacm_vfs_select,
#endif // CONFIG_VFS_SUPPORT_SELECT
@@ -521,7 +521,7 @@ const esp_vfs_fs_ops_t *esp_vfs_cdcacm_get_vfs(void)
esp_err_t esp_vfs_dev_cdcacm_register(void)
{
return esp_vfs_register_fs("/dev/cdcacm", &s_cdcacm_vfs, ESP_VFS_FLAG_STATIC, NULL);
return esp_vfs_register_fs("/dev/cdcacm", &s_cdcacm_vfs, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL);
}
#if CONFIG_ESP_CONSOLE_USB_CDC
ESP_SYSTEM_INIT_FN(init_vfs_usb_cdc_rom_console, CORE, BIT(0), 113)
+25 -10
View File
@@ -65,17 +65,32 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct
#endif // CONFIG_VFS_SUPPORT_SELECT
static int lwip_fcntl_r_wrapper(int fd, int cmd, int arg)
static int lwip_write_r_wrapper(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size)
{
return lwip_write(fd, data, size);
}
static int lwip_read_r_wrapper(__attribute__((unused)) void *ctx, int fd, void *data, size_t size)
{
return lwip_read(fd, data, size);
}
static int lwip_close_r_wrapper(__attribute__((unused)) void *ctx, int fd)
{
return lwip_close(fd);
}
static int lwip_fcntl_r_wrapper(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
return lwip_fcntl(fd, cmd, arg);
}
static int lwip_ioctl_r_wrapper(int fd, int cmd, va_list args)
static int lwip_ioctl_r_wrapper(__attribute__((unused)) void *ctx, int fd, int cmd, va_list args)
{
return lwip_ioctl(fd, cmd, va_arg(args, void *));
}
static int lwip_fstat(int fd, struct stat * st)
static int lwip_fstat(__attribute__((unused)) void *ctx, int fd, struct stat * st)
{
if (st == NULL || fd < LWIP_SOCKET_OFFSET || fd > (MAX_FDS - 1)) {
errno = EBADF;
@@ -102,12 +117,12 @@ void esp_vfs_lwip_sockets_register(void)
#endif
static const esp_vfs_fs_ops_t s_lwip_vfs = {
.write = &lwip_write,
.read = &lwip_read,
.close = &lwip_close,
.fstat = &lwip_fstat,
.fcntl = &lwip_fcntl_r_wrapper,
.ioctl = &lwip_ioctl_r_wrapper,
.write_p = &lwip_write_r_wrapper,
.read_p = &lwip_read_r_wrapper,
.close_p = &lwip_close_r_wrapper,
.fstat_p = &lwip_fstat,
.fcntl_p = &lwip_fcntl_r_wrapper,
.ioctl_p = &lwip_ioctl_r_wrapper,
#ifdef CONFIG_VFS_SUPPORT_SELECT
.select = &s_lwip_select_ops,
#endif
@@ -120,7 +135,7 @@ void esp_vfs_lwip_sockets_register(void)
* No context pointer needed -> flags have no ESP_VFS_FLAG_CONTEXT_PTR.
*/
ESP_ERROR_CHECK(esp_vfs_register_fd_range(&s_lwip_vfs,
ESP_VFS_FLAG_STATIC,
ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR,
NULL /* ctx */,
LWIP_SOCKET_OFFSET,
MAX_FDS));
+7
View File
@@ -86,6 +86,13 @@ menu "Virtual file system"
help
Define maximum number of virtual filesystems that can be registered.
config VFS_SUPPRESS_CTX_DEPRECATION
bool "Suppress context-less API deprecation warning"
default n
help
The VFS APIs without context pointer are deprecated and will be removed in the next major release.
Please switch to the APIs with context pointer,
or alternatively enable this option to silence the warning.
menu "Host File System I/O (Semihosting)"
depends on VFS_SUPPORT_IO
+51 -39
View File
@@ -1,11 +1,10 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_VFS_H__
#define __ESP_VFS_H__
#pragma once
#include <stdint.h>
#include <stddef.h>
@@ -68,6 +67,17 @@ extern "C" {
*/
#define ESP_VFS_FLAG_STATIC (1 << 3)
#ifndef __DOXYGEN__
# pragma push_macro("deprecated")
# undef deprecated
# if defined(CONFIG_VFS_SUPPRESS_CTX_DEPRECATION) || defined(_VFS_SUPPRESS_CTX_DEPRECATION)
# define deprecated(msg)
# else
# define deprecated(msg) deprecated("Context pointer-less API is deprecated, please use the version with context pointer")
# endif
#endif
/**
* @brief VFS definition structure
* @note Prefer using esp_vfs_fs_ops_t with esp_vfs_register_fs*() instead.
@@ -94,144 +104,144 @@ typedef struct
{
int flags; /*!< ESP_VFS_FLAG_CONTEXT_PTR and/or ESP_VFS_FLAG_READONLY_FS or ESP_VFS_FLAG_DEFAULT */
union {
ssize_t (*write_p)(void* p, int fd, const void * data, size_t size); /*!< Write with context pointer */
ssize_t (*write_p)(void* p, int fd, const void * data, size_t size) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< Write with context pointer */
ssize_t (*write)(int fd, const void * data, size_t size); /*!< Write without context pointer */
};
union {
off_t (*lseek_p)(void* p, int fd, off_t size, int mode); /*!< Seek with context pointer */
off_t (*lseek_p)(void* p, int fd, off_t size, int mode) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< Seek with context pointer */
off_t (*lseek)(int fd, off_t size, int mode); /*!< Seek without context pointer */
};
union {
ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size); /*!< Read with context pointer */
ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< Read with context pointer */
ssize_t (*read)(int fd, void * dst, size_t size); /*!< Read without context pointer */
};
union {
ssize_t (*pread_p)(void *ctx, int fd, void * dst, size_t size, off_t offset); /*!< pread with context pointer */
ssize_t (*pread_p)(void *ctx, int fd, void * dst, size_t size, off_t offset) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< pread with context pointer */
ssize_t (*pread)(int fd, void * dst, size_t size, off_t offset); /*!< pread without context pointer */
};
union {
ssize_t (*pwrite_p)(void *ctx, int fd, const void *src, size_t size, off_t offset); /*!< pwrite with context pointer */
ssize_t (*pwrite_p)(void *ctx, int fd, const void *src, size_t size, off_t offset) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< pwrite with context pointer */
ssize_t (*pwrite)(int fd, const void *src, size_t size, off_t offset); /*!< pwrite without context pointer */
};
union {
int (*open_p)(void* ctx, const char * path, int flags, int mode); /*!< open with context pointer */
int (*open_p)(void* ctx, const char * path, int flags, int mode) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< open with context pointer */
int (*open)(const char * path, int flags, int mode); /*!< open without context pointer */
};
union {
int (*close_p)(void* ctx, int fd); /*!< close with context pointer */
int (*close_p)(void* ctx, int fd) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< close with context pointer */
int (*close)(int fd); /*!< close without context pointer */
};
union {
int (*fstat_p)(void* ctx, int fd, struct stat * st); /*!< fstat with context pointer */
int (*fstat_p)(void* ctx, int fd, struct stat * st) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< fstat with context pointer */
int (*fstat)(int fd, struct stat * st); /*!< fstat without context pointer */
};
#ifdef CONFIG_VFS_SUPPORT_DIR
union {
int (*stat_p)(void* ctx, const char * path, struct stat * st); /*!< stat with context pointer */
int (*stat_p)(void* ctx, const char * path, struct stat * st) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< stat with context pointer */
int (*stat)(const char * path, struct stat * st); /*!< stat without context pointer */
};
union {
int (*link_p)(void* ctx, const char* n1, const char* n2); /*!< link with context pointer */
int (*link_p)(void* ctx, const char* n1, const char* n2) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< link with context pointer */
int (*link)(const char* n1, const char* n2); /*!< link without context pointer */
};
union {
int (*unlink_p)(void* ctx, const char *path); /*!< unlink with context pointer */
int (*unlink_p)(void* ctx, const char *path) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< unlink with context pointer */
int (*unlink)(const char *path); /*!< unlink without context pointer */
};
union {
int (*rename_p)(void* ctx, const char *src, const char *dst); /*!< rename with context pointer */
int (*rename_p)(void* ctx, const char *src, const char *dst) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< rename with context pointer */
int (*rename)(const char *src, const char *dst); /*!< rename without context pointer */
};
union {
DIR* (*opendir_p)(void* ctx, const char* name); /*!< opendir with context pointer */
DIR* (*opendir_p)(void* ctx, const char* name) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< opendir with context pointer */
DIR* (*opendir)(const char* name); /*!< opendir without context pointer */
};
union {
struct dirent* (*readdir_p)(void* ctx, DIR* pdir); /*!< readdir with context pointer */
struct dirent* (*readdir_p)(void* ctx, DIR* pdir) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< readdir with context pointer */
struct dirent* (*readdir)(DIR* pdir); /*!< readdir without context pointer */
};
union {
int (*readdir_r_p)(void* ctx, DIR* pdir, struct dirent* entry, struct dirent** out_dirent); /*!< readdir_r with context pointer */
int (*readdir_r_p)(void* ctx, DIR* pdir, struct dirent* entry, struct dirent** out_dirent) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< readdir_r with context pointer */
int (*readdir_r)(DIR* pdir, struct dirent* entry, struct dirent** out_dirent); /*!< readdir_r without context pointer */
};
union {
long (*telldir_p)(void* ctx, DIR* pdir); /*!< telldir with context pointer */
long (*telldir_p)(void* ctx, DIR* pdir) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< telldir with context pointer */
long (*telldir)(DIR* pdir); /*!< telldir without context pointer */
};
union {
void (*seekdir_p)(void* ctx, DIR* pdir, long offset); /*!< seekdir with context pointer */
void (*seekdir_p)(void* ctx, DIR* pdir, long offset) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< seekdir with context pointer */
void (*seekdir)(DIR* pdir, long offset); /*!< seekdir without context pointer */
};
union {
int (*closedir_p)(void* ctx, DIR* pdir); /*!< closedir with context pointer */
int (*closedir_p)(void* ctx, DIR* pdir) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< closedir with context pointer */
int (*closedir)(DIR* pdir); /*!< closedir without context pointer */
};
union {
int (*mkdir_p)(void* ctx, const char* name, mode_t mode); /*!< mkdir with context pointer */
int (*mkdir_p)(void* ctx, const char* name, mode_t mode) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< mkdir with context pointer */
int (*mkdir)(const char* name, mode_t mode); /*!< mkdir without context pointer */
};
union {
int (*rmdir_p)(void* ctx, const char* name); /*!< rmdir with context pointer */
int (*rmdir_p)(void* ctx, const char* name) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< rmdir with context pointer */
int (*rmdir)(const char* name); /*!< rmdir without context pointer */
};
#endif // CONFIG_VFS_SUPPORT_DIR
union {
int (*fcntl_p)(void* ctx, int fd, int cmd, int arg); /*!< fcntl with context pointer */
int (*fcntl_p)(void* ctx, int fd, int cmd, int arg) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< fcntl with context pointer */
int (*fcntl)(int fd, int cmd, int arg); /*!< fcntl without context pointer */
};
union {
int (*ioctl_p)(void* ctx, int fd, int cmd, va_list args); /*!< ioctl with context pointer */
int (*ioctl_p)(void* ctx, int fd, int cmd, va_list args) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< ioctl with context pointer */
int (*ioctl)(int fd, int cmd, va_list args); /*!< ioctl without context pointer */
};
union {
int (*fsync_p)(void* ctx, int fd); /*!< fsync with context pointer */
int (*fsync_p)(void* ctx, int fd) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< fsync with context pointer */
int (*fsync)(int fd); /*!< fsync without context pointer */
};
#ifdef CONFIG_VFS_SUPPORT_DIR
union {
int (*access_p)(void* ctx, const char *path, int amode); /*!< access with context pointer */
int (*access_p)(void* ctx, const char *path, int amode) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< access with context pointer */
int (*access)(const char *path, int amode); /*!< access without context pointer */
};
union {
int (*truncate_p)(void* ctx, const char *path, off_t length); /*!< truncate with context pointer */
int (*truncate_p)(void* ctx, const char *path, off_t length) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< truncate with context pointer */
int (*truncate)(const char *path, off_t length); /*!< truncate without context pointer */
};
union {
int (*ftruncate_p)(void* ctx, int fd, off_t length); /*!< ftruncate with context pointer */
int (*ftruncate_p)(void* ctx, int fd, off_t length) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< ftruncate with context pointer */
int (*ftruncate)(int fd, off_t length); /*!< ftruncate without context pointer */
};
union {
int (*utime_p)(void* ctx, const char *path, const struct utimbuf *times); /*!< utime with context pointer */
int (*utime_p)(void* ctx, const char *path, const struct utimbuf *times) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< utime with context pointer */
int (*utime)(const char *path, const struct utimbuf *times); /*!< utime without context pointer */
};
#endif // CONFIG_VFS_SUPPORT_DIR
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
union {
int (*tcsetattr_p)(void *ctx, int fd, int optional_actions, const struct termios *p); /*!< tcsetattr with context pointer */
int (*tcsetattr_p)(void *ctx, int fd, int optional_actions, const struct termios *p) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcsetattr with context pointer */
int (*tcsetattr)(int fd, int optional_actions, const struct termios *p); /*!< tcsetattr without context pointer */
};
union {
int (*tcgetattr_p)(void *ctx, int fd, struct termios *p); /*!< tcgetattr with context pointer */
int (*tcgetattr_p)(void *ctx, int fd, struct termios *p) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcgetattr with context pointer */
int (*tcgetattr)(int fd, struct termios *p); /*!< tcgetattr without context pointer */
};
union {
int (*tcdrain_p)(void *ctx, int fd); /*!< tcdrain with context pointer */
int (*tcdrain_p)(void *ctx, int fd) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcdrain with context pointer */
int (*tcdrain)(int fd); /*!< tcdrain without context pointer */
};
union {
int (*tcflush_p)(void *ctx, int fd, int select); /*!< tcflush with context pointer */
int (*tcflush_p)(void *ctx, int fd, int select) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcflush with context pointer */
int (*tcflush)(int fd, int select); /*!< tcflush without context pointer */
};
union {
int (*tcflow_p)(void *ctx, int fd, int action); /*!< tcflow with context pointer */
int (*tcflow_p)(void *ctx, int fd, int action) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcflow with context pointer */
int (*tcflow)(int fd, int action); /*!< tcflow without context pointer */
};
union {
pid_t (*tcgetsid_p)(void *ctx, int fd); /*!< tcgetsid with context pointer */
pid_t (*tcgetsid_p)(void *ctx, int fd) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcgetsid with context pointer */
pid_t (*tcgetsid)(int fd); /*!< tcgetsid without context pointer */
};
union {
int (*tcsendbreak_p)(void *ctx, int fd, int duration); /*!< tcsendbreak with context pointer */
int (*tcsendbreak_p)(void *ctx, int fd, int duration) __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcsendbreak with context pointer */
int (*tcsendbreak)(int fd, int duration); /*!< tcsendbreak without context pointer */
};
#endif // CONFIG_VFS_SUPPORT_TERMIOS
@@ -502,8 +512,10 @@ void esp_vfs_dump_fds(FILE *fp);
*/
void esp_vfs_dump_registered_paths(FILE *fp);
#if !defined(__DOXYGEN__)
#pragma pop_macro("deprecated")
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__ESP_VFS_H__
+48 -39
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -27,10 +27,15 @@
extern "C" {
#endif
#ifndef CONFIG_IDF_TARGET_LINUX
#ifndef _SYS_TYPES_FD_SET
#error "VFS should be used with FD_SETSIZE and FD_SET from sys/types.h"
#endif
#ifndef __DOXYGEN__
# pragma push_macro("deprecated")
# undef deprecated
# if defined(CONFIG_VFS_SUPPRESS_CTX_DEPRECATION) || defined(_VFS_SUPPRESS_CTX_DEPRECATION)
# define deprecated(msg)
# else
# define deprecated(msg) deprecated("Context pointer-less API is deprecated, please use the version with context pointer")
# endif
#endif
/*
@@ -91,67 +96,67 @@ typedef int (*esp_vfs_utime_op_t) ( const char *pat
typedef struct {
union {
const esp_vfs_stat_ctx_op_t stat_p; /*!< stat with context pointer */
const esp_vfs_stat_op_t stat; /*!< stat without context pointer */
const esp_vfs_stat_op_t stat __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< stat without context pointer */
};
union {
const esp_vfs_link_ctx_op_t link_p; /*!< link with context pointer */
const esp_vfs_link_op_t link; /*!< link without context pointer */
const esp_vfs_link_op_t link __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< link without context pointer */
};
union {
const esp_vfs_unlink_ctx_op_t unlink_p; /*!< unlink with context pointer */
const esp_vfs_unlink_op_t unlink; /*!< unlink without context pointer */
const esp_vfs_unlink_op_t unlink __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< unlink without context pointer */
};
union {
const esp_vfs_rename_ctx_op_t rename_p; /*!< rename with context pointer */
const esp_vfs_rename_op_t rename; /*!< rename without context pointer */
const esp_vfs_rename_op_t rename __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< rename without context pointer */
};
union {
const esp_vfs_opendir_ctx_op_t opendir_p; /*!< opendir with context pointer */
const esp_vfs_opendir_op_t opendir; /*!< opendir without context pointer */
const esp_vfs_opendir_op_t opendir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< opendir without context pointer */
};
union {
const esp_vfs_readdir_ctx_op_t readdir_p; /*!< readdir with context pointer */
const esp_vfs_readdir_op_t readdir; /*!< readdir without context pointer */
const esp_vfs_readdir_op_t readdir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< readdir without context pointer */
};
union {
const esp_vfs_readdir_r_ctx_op_t readdir_r_p; /*!< readdir_r with context pointer */
const esp_vfs_readdir_r_op_t readdir_r; /*!< readdir_r without context pointer */
const esp_vfs_readdir_r_op_t readdir_r __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< readdir_r without context pointer */
};
union {
const esp_vfs_telldir_ctx_op_t telldir_p; /*!< telldir with context pointer */
const esp_vfs_telldir_op_t telldir; /*!< telldir without context pointer */
const esp_vfs_telldir_op_t telldir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< telldir without context pointer */
};
union {
const esp_vfs_seekdir_ctx_op_t seekdir_p; /*!< seekdir with context pointer */
const esp_vfs_seekdir_op_t seekdir; /*!< seekdir without context pointer */
const esp_vfs_seekdir_op_t seekdir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< seekdir without context pointer */
};
union {
const esp_vfs_closedir_ctx_op_t closedir_p; /*!< closedir with context pointer */
const esp_vfs_closedir_op_t closedir; /*!< closedir without context pointer */
const esp_vfs_closedir_op_t closedir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< closedir without context pointer */
};
union {
const esp_vfs_mkdir_ctx_op_t mkdir_p; /*!< mkdir with context pointer */
const esp_vfs_mkdir_op_t mkdir; /*!< mkdir without context pointer */
const esp_vfs_mkdir_op_t mkdir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< mkdir without context pointer */
};
union {
const esp_vfs_rmdir_ctx_op_t rmdir_p; /*!< rmdir with context pointer */
const esp_vfs_rmdir_op_t rmdir; /*!< rmdir without context pointer */
const esp_vfs_rmdir_op_t rmdir __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< rmdir without context pointer */
};
union {
const esp_vfs_access_ctx_op_t access_p; /*!< access with context pointer */
const esp_vfs_access_op_t access; /*!< access without context pointer */
const esp_vfs_access_op_t access __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< access without context pointer */
};
union {
const esp_vfs_truncate_ctx_op_t truncate_p; /*!< truncate with context pointer */
const esp_vfs_truncate_op_t truncate; /*!< truncate without context pointer */
const esp_vfs_truncate_op_t truncate __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< truncate without context pointer */
};
union {
const esp_vfs_ftruncate_ctx_op_t ftruncate_p; /*!< ftruncate with context pointer */
const esp_vfs_ftruncate_op_t ftruncate; /*!< ftruncate without context pointer */
const esp_vfs_ftruncate_op_t ftruncate __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< ftruncate without context pointer */
};
union {
const esp_vfs_utime_ctx_op_t utime_p; /*!< utime with context pointer */
const esp_vfs_utime_op_t utime; /*!< utime without context pointer */
const esp_vfs_utime_op_t utime __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< utime without context pointer */
};
} esp_vfs_dir_ops_t;
@@ -181,31 +186,31 @@ typedef int (*esp_vfs_tcsendbreak_op_t) ( int fd, int duration);
typedef struct {
union {
const esp_vfs_tcsetattr_ctx_op_t tcsetattr_p; /*!< tcsetattr with context pointer */
const esp_vfs_tcsetattr_op_t tcsetattr; /*!< tcsetattr without context pointer */
const esp_vfs_tcsetattr_op_t tcsetattr __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcsetattr without context pointer */
};
union {
const esp_vfs_tcgetattr_ctx_op_t tcgetattr_p; /*!< tcgetattr with context pointer */
const esp_vfs_tcgetattr_op_t tcgetattr; /*!< tcgetattr without context pointer */
const esp_vfs_tcgetattr_op_t tcgetattr __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcgetattr without context pointer */
};
union {
const esp_vfs_tcdrain_ctx_op_t tcdrain_p; /*!< tcdrain with context pointer */
const esp_vfs_tcdrain_op_t tcdrain; /*!< tcdrain without context pointer */
const esp_vfs_tcdrain_op_t tcdrain __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcdrain without context pointer */
};
union {
const esp_vfs_tcflush_ctx_op_t tcflush_p; /*!< tcflush with context pointer */
const esp_vfs_tcflush_op_t tcflush; /*!< tcflush without context pointer */
const esp_vfs_tcflush_op_t tcflush __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcflush without context pointer */
};
union {
const esp_vfs_tcflow_ctx_op_t tcflow_p; /*!< tcflow with context pointer */
const esp_vfs_tcflow_op_t tcflow; /*!< tcflow without context pointer */
const esp_vfs_tcflow_op_t tcflow __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcflow without context pointer */
};
union {
const esp_vfs_tcgetsid_ctx_op_t tcgetsid_p; /*!< tcgetsid with context pointer */
const esp_vfs_tcgetsid_op_t tcgetsid; /*!< tcgetsid without context pointer */
const esp_vfs_tcgetsid_op_t tcgetsid __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcgetsid without context pointer */
};
union {
const esp_vfs_tcsendbreak_ctx_op_t tcsendbreak_p; /*!< tcsendbreak with context pointer */
const esp_vfs_tcsendbreak_op_t tcsendbreak; /*!< tcsendbreak without context pointer */
const esp_vfs_tcsendbreak_op_t tcsendbreak __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< tcsendbreak without context pointer */
};
} esp_vfs_termios_ops_t;
@@ -276,47 +281,47 @@ typedef int (*esp_vfs_fsync_op_t) ( int fd);
typedef struct {
union {
const esp_vfs_write_ctx_op_t write_p; /*!< Write with context pointer */
const esp_vfs_write_op_t write; /*!< Write without context pointer */
const esp_vfs_write_op_t write __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< Write without context pointer */
};
union {
const esp_vfs_lseek_ctx_op_t lseek_p; /*!< Seek with context pointer */
const esp_vfs_lseek_op_t lseek; /*!< Seek without context pointer */
const esp_vfs_lseek_op_t lseek __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< Seek without context pointer */
};
union {
const esp_vfs_read_ctx_op_t read_p; /*!< Read with context pointer */
const esp_vfs_read_op_t read; /*!< Read without context pointer */
const esp_vfs_read_op_t read __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< Read without context pointer */
};
union {
const esp_vfs_pread_ctx_op_t pread_p; /*!< pread with context pointer */
const esp_vfs_pread_op_t pread; /*!< pread without context pointer */
const esp_vfs_pread_op_t pread __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< pread without context pointer */
};
union {
const esp_vfs_pwrite_ctx_op_t pwrite_p; /*!< pwrite with context pointer */
const esp_vfs_pwrite_op_t pwrite; /*!< pwrite without context pointer */
const esp_vfs_pwrite_op_t pwrite __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< pwrite without context pointer */
};
union {
const esp_vfs_open_ctx_op_t open_p; /*!< open with context pointer */
const esp_vfs_open_op_t open; /*!< open without context pointer */
const esp_vfs_open_op_t open __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< open without context pointer */
};
union {
const esp_vfs_close_ctx_op_t close_p; /*!< close with context pointer */
const esp_vfs_close_op_t close; /*!< close without context pointer */
const esp_vfs_close_op_t close __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< close without context pointer */
};
union {
const esp_vfs_fstat_ctx_op_t fstat_p; /*!< fstat with context pointer */
const esp_vfs_fstat_op_t fstat; /*!< fstat without context pointer */
const esp_vfs_fstat_op_t fstat __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< fstat without context pointer */
};
union {
const esp_vfs_fcntl_ctx_op_t fcntl_p; /*!< fcntl with context pointer */
const esp_vfs_fcntl_op_t fcntl; /*!< fcntl without context pointer */
const esp_vfs_fcntl_op_t fcntl __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< fcntl without context pointer */
};
union {
const esp_vfs_ioctl_ctx_op_t ioctl_p; /*!< ioctl with context pointer */
const esp_vfs_ioctl_op_t ioctl; /*!< ioctl without context pointer */
const esp_vfs_ioctl_op_t ioctl __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< ioctl without context pointer */
};
union {
const esp_vfs_fsync_ctx_op_t fsync_p; /*!< fsync with context pointer */
const esp_vfs_fsync_op_t fsync; /*!< fsync without context pointer */
const esp_vfs_fsync_op_t fsync __attribute__((deprecated("Context pointer-less API is deprecated"))); /*!< fsync without context pointer */
};
#ifdef CONFIG_VFS_SUPPORT_DIR
@@ -380,6 +385,10 @@ esp_err_t esp_vfs_unregister_fs(const char *base_path);
*/
esp_err_t esp_vfs_unregister_fs_with_id(esp_vfs_id_t id);
#if !defined(__DOXYGEN__)
#pragma pop_macro("deprecated")
#endif
#ifdef __cplusplus
}
#endif
+38 -38
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -54,39 +54,39 @@ static const char* TAG = "nullfs";
static vfs_null_ctx_t g_fds = 0;
static ssize_t vfs_null_write(int fd, const void *data, size_t size);
static off_t vfs_null_lseek(int fd, off_t offset, int whence);
static ssize_t vfs_null_read(int fd, void *data, size_t size);
static ssize_t vfs_null_pread(int fd, void *data, size_t size, off_t offset);
static ssize_t vfs_null_pwrite(int fd, const void *data, size_t size, off_t offset);
static int vfs_null_open(const char* path, int flags, int mode);
static int vfs_null_close(int fd);
static int vfs_null_fstat(int fd, struct stat *st);
static ssize_t vfs_null_write(void *ctx, int fd, const void *data, size_t size);
static off_t vfs_null_lseek(void *ctx, int fd, off_t offset, int whence);
static ssize_t vfs_null_read(void *ctx, int fd, void *data, size_t size);
static ssize_t vfs_null_pread(void *ctx, int fd, void *data, size_t size, off_t offset);
static ssize_t vfs_null_pwrite(void *ctx, int fd, const void *data, size_t size, off_t offset);
static int vfs_null_open(void *ctx, const char* path, int flags, int mode);
static int vfs_null_close(void *ctx, int fd);
static int vfs_null_fstat(void *ctx, int fd, struct stat *st);
#if CONFIG_VFS_SUPPORT_DIR
static int vfs_null_stat(const char* path, struct stat *st);
static int vfs_null_stat(void *ctx, const char* path, struct stat *st);
#endif // CONFIG_VFS_SUPPORT_DIR
static int vfs_null_fcntl(int fd, int cmd, int arg);
static int vfs_null_ioctl(int fd, int cmd, va_list args);
static int vfs_null_fsync(int fd);
static int vfs_null_fcntl(void *ctx, int fd, int cmd, int arg);
static int vfs_null_ioctl(void *ctx, int fd, int cmd, va_list args);
static int vfs_null_fsync(void *ctx, int fd);
#if CONFIG_VFS_SUPPORT_DIR
static const esp_vfs_dir_ops_t s_vfs_null_dir = {
.stat = &vfs_null_stat,
.stat_p = &vfs_null_stat,
};
#endif // CONFIG_VFS_SUPPORT_DIR
static const esp_vfs_fs_ops_t s_vfs_null = {
.write = &vfs_null_write,
.lseek = &vfs_null_lseek,
.read = &vfs_null_read,
.pread = &vfs_null_pread,
.pwrite = &vfs_null_pwrite,
.open = &vfs_null_open,
.close = &vfs_null_close,
.fstat = &vfs_null_fstat,
.fcntl = &vfs_null_fcntl,
.ioctl = &vfs_null_ioctl,
.fsync = &vfs_null_fsync,
.write_p = &vfs_null_write,
.lseek_p = &vfs_null_lseek,
.read_p = &vfs_null_read,
.pread_p = &vfs_null_pread,
.pwrite_p = &vfs_null_pwrite,
.open_p = &vfs_null_open,
.close_p = &vfs_null_close,
.fstat_p = &vfs_null_fstat,
.fcntl_p = &vfs_null_fcntl,
.ioctl_p = &vfs_null_ioctl,
.fsync_p = &vfs_null_fsync,
#if CONFIG_VFS_SUPPORT_DIR
.dir = &s_vfs_null_dir,
#endif // CONFIG_VFS_SUPPORT_DIR
@@ -99,10 +99,10 @@ const esp_vfs_fs_ops_t *esp_vfs_null_get_vfs(void)
esp_err_t esp_vfs_null_register(void)
{
return esp_vfs_register_fs("/dev/null", &s_vfs_null, ESP_VFS_FLAG_STATIC, NULL);
return esp_vfs_register_fs("/dev/null", &s_vfs_null, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL);
}
static ssize_t vfs_null_write(int fd, const void *data, size_t size)
static ssize_t vfs_null_write(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size)
{
UNUSED(data);
@@ -114,7 +114,7 @@ static ssize_t vfs_null_write(int fd, const void *data, size_t size)
return -1;
}
static off_t vfs_null_lseek(int fd, off_t offset, int whence)
static off_t vfs_null_lseek(__attribute__((unused)) void *ctx, int fd, off_t offset, int whence)
{
UNUSED(offset);
@@ -134,7 +134,7 @@ static off_t vfs_null_lseek(int fd, off_t offset, int whence)
}
}
static ssize_t vfs_null_read(int fd, void *data, size_t size)
static ssize_t vfs_null_read(__attribute__((unused)) void *ctx, int fd, void *data, size_t size)
{
UNUSED(data);
@@ -148,7 +148,7 @@ static ssize_t vfs_null_read(int fd, void *data, size_t size)
return -1;
}
static int vfs_null_pread(int fd, void *data, size_t size, off_t offset)
static int vfs_null_pread(__attribute__((unused)) void *ctx, int fd, void *data, size_t size, off_t offset)
{
UNUSED(data);
UNUSED(size);
@@ -165,7 +165,7 @@ static int vfs_null_pread(int fd, void *data, size_t size, off_t offset)
}
static int vfs_null_pwrite(int fd, const void *data, size_t size, off_t offset)
static int vfs_null_pwrite(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size, off_t offset)
{
UNUSED(data);
UNUSED(offset);
@@ -191,7 +191,7 @@ static int vfs_null_get_empty_fd(void)
return -1;
}
static int vfs_null_open(const char* path, int flags, int mode)
static int vfs_null_open(__attribute__((unused)) void *ctx, const char* path, int flags, int mode)
{
UNUSED(mode);
@@ -226,7 +226,7 @@ static int vfs_null_open(const char* path, int flags, int mode)
return fd;
}
static int vfs_null_close(int fd)
static int vfs_null_close(__attribute__((unused)) void *ctx, int fd)
{
if (!FD_IN_RANGE(fd)) {
errno = EBADF;
@@ -237,7 +237,7 @@ static int vfs_null_close(int fd)
return 0;
}
static int vfs_null_fstat(int fd, struct stat *st)
static int vfs_null_fstat(__attribute__((unused)) void *ctx, int fd, struct stat *st)
{
if (!FD_IN_RANGE(fd)) {
errno = EBADF;
@@ -256,7 +256,7 @@ static int vfs_null_fstat(int fd, struct stat *st)
#if CONFIG_VFS_SUPPORT_DIR
static int vfs_null_stat(const char* path, struct stat *st)
static int vfs_null_stat(__attribute__((unused)) void *ctx, const char* path, struct stat *st)
{
if (strcmp(path, "/") != 0) {
errno = ENOENT;
@@ -275,7 +275,7 @@ static int vfs_null_stat(const char* path, struct stat *st)
#endif // CONFIG_VFS_SUPPORT_DIR
static int vfs_null_fcntl(int fd, int cmd, int arg)
static int vfs_null_fcntl(__attribute__((unused)) void *ctx, int fd, int cmd, int arg)
{
UNUSED(arg);
@@ -291,7 +291,7 @@ static int vfs_null_fcntl(int fd, int cmd, int arg)
}
}
static int vfs_null_ioctl(int fd, int cmd, va_list args)
static int vfs_null_ioctl(__attribute__((unused)) void *ctx, int fd, int cmd, va_list args)
{
UNUSED(args);
@@ -307,7 +307,7 @@ static int vfs_null_ioctl(int fd, int cmd, va_list args)
}
}
static int vfs_null_fsync(int fd)
static int vfs_null_fsync(__attribute__((unused)) void *ctx, int fd)
{
if (!FD_IN_RANGE(fd)) {
errno = EBADF;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -18,7 +18,7 @@
* It is enough to check just one of them for NULL, as both variants are part of a union.
*/
#define CHECK_AND_CALL(ret, r, pvfs, func, ...) \
if (pvfs->vfs->func == NULL) { \
if (pvfs->vfs->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return -1; \
} \
@@ -29,7 +29,7 @@
}
#define CHECK_AND_CALL_SUBCOMPONENT(ret, r, pvfs, component, func, ...) \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func == NULL) { \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return -1; \
} \
@@ -40,7 +40,7 @@
}
#define CHECK_AND_CALLV(r, pvfs, func, ...) \
if (pvfs->vfs->func == NULL) { \
if (pvfs->vfs->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return; \
} \
@@ -51,7 +51,7 @@
}
#define CHECK_AND_CALL_SUBCOMPONENTV(r, pvfs, component, func, ...) \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func == NULL) { \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return; \
} \
@@ -62,7 +62,7 @@
}
#define CHECK_AND_CALLP(ret, r, pvfs, func, ...) \
if (pvfs->vfs->func == NULL) { \
if (pvfs->vfs->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return NULL; \
} \
@@ -73,7 +73,7 @@
}
#define CHECK_AND_CALL_SUBCOMPONENTP(ret, r, pvfs, component, func, ...) \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func == NULL) { \
if (pvfs->vfs->component == NULL || pvfs->vfs->component->func ## _p == NULL) { \
__errno_r(r) = ENOSYS; \
return NULL; \
} \
@@ -9,3 +9,6 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_VFS_MAX_COUNT=10
# We should still run tests for all variants...
CONFIG_VFS_SUPPRESS_CTX_DEPRECATION=y
+3
View File
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define _VFS_SUPPRESS_CTX_DEPRECATION
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
@@ -16,6 +18,7 @@
#include "esp_vfs.h"
#include "esp_vfs_private.h"
#include "esp_private/socket.h"
#include "sdkconfig.h"
// Warn about using deprecated option
+3
View File
@@ -3,6 +3,9 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#define _VFS_SUPPRESS_CTX_DEPRECATION
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+7 -7
View File
@@ -243,7 +243,7 @@ static ssize_t signal_event_fd_from_isr(int fd, const void *data, size_t size)
return ret;
}
static ssize_t event_write(int fd, const void *data, size_t size)
static ssize_t event_write(__attribute__((unused)) void *ctx, int fd, const void *data, size_t size)
{
ssize_t ret = -1;
@@ -284,7 +284,7 @@ static ssize_t event_write(int fd, const void *data, size_t size)
return ret;
}
static ssize_t event_read(int fd, void *data, size_t size)
static ssize_t event_read(__attribute__((unused)) void *ctx, int fd, void *data, size_t size)
{
ssize_t ret = -1;
@@ -318,7 +318,7 @@ static ssize_t event_read(int fd, void *data, size_t size)
return ret;
}
static int event_close(int fd)
static int event_close(__attribute__((unused)) void *ctx, int fd)
{
int ret = -1;
@@ -359,9 +359,9 @@ static const esp_vfs_select_ops_t s_vfs_eventfd_select = {
#endif
static const esp_vfs_fs_ops_t s_vfs_eventfd = {
.write = &event_write,
.read = &event_read,
.close = &event_close,
.write_p = &event_write,
.read_p = &event_read,
.close_p = &event_close,
#ifdef CONFIG_VFS_SUPPORT_SELECT
.select = &s_vfs_eventfd_select,
#endif
@@ -383,7 +383,7 @@ esp_err_t esp_vfs_eventfd_register(const esp_vfs_eventfd_config_t *config)
s_events[i].fd = FD_INVALID;
}
return esp_vfs_register_fs_with_id(&s_vfs_eventfd, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_STATIC, NULL, &s_eventfd_vfs_id);
return esp_vfs_register_fs_with_id(&s_vfs_eventfd, ESP_VFS_FLAG_STATIC | ESP_VFS_FLAG_CONTEXT_PTR, NULL, &s_eventfd_vfs_id);
}
esp_err_t esp_vfs_eventfd_unregister(void)
+5
View File
@@ -19,6 +19,10 @@ FS Registration
To register an FS driver, an application needs to define an instance of the :cpp:type:`esp_vfs_fs_ops_t` structure and populate it with function pointers to FS APIs:
.. warning::
The API version without a context pointer is deprecated, and will be removed in the future. See :ref:`context_api` for details.
.. highlight:: c
::
@@ -65,6 +69,7 @@ The recommended approach for registering filesystem is to use statically allocat
ESP_ERROR_CHECK(esp_vfs_register_fs("/data", &myfs, ESP_VFS_FLAG_DEFAULT, NULL));
}
.. _context_api:
Context Aware Filesystem
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,6 +19,7 @@ VFS
- ``esp_vfs_register_fd_range`` is now considered private and its signature was changed to match the new VFS API style. Projects that still rely on this internal helper must include ``esp_private/socket.h`` and should be aware that the API may change without notice.
- Legacy VFS APIs (such as ``esp_vfs_register``) that operate on ``esp_vfs_t`` instead of ``esp_vfs_fs_ops_t`` are deprecated and will be removed in the next major release. Switch to the new ``esp_vfs_fs_ops_t``-based APIs.
- TERMIOS support is now disabled by default. Re-enable :ref:`CONFIG_VFS_SUPPORT_TERMIOS` in menuconfig if your application calls POSIX ``termios`` APIs, such as ``tcsetattr``/``tcgetattr`` for UART configuration.
- Context-less VFS function pointers are deprecated. Switch to the context-aware ``*_p`` callbacks, register the VFS with ``ESP_VFS_FLAG_CONTEXT_PTR``, and pass ``NULL`` as the context pointer if the driver does not need per-instance state. This change simplifies the API surface and reduces runtime overhead in the VFS call path.
``esp_vfs_console``
+5
View File
@@ -19,6 +19,10 @@ VFS 组件支持 C 库函数(如 fopen 和 fprintf 等)与文件系统 (FS)
如需注册 FS 驱动程序,应用程序首先要定义一个 :cpp:type:`esp_vfs_fs_ops_t` 结构体实例,并用指向 FS API 的函数指针填充它。
.. warning::
不带上下文指针的 API 版本已弃用,未来将被移除,请参见 :ref:`context_api`
.. highlight:: c
::
@@ -65,6 +69,7 @@ VFS 组件支持 C 库函数(如 fopen 和 fprintf 等)与文件系统 (FS)
ESP_ERROR_CHECK(esp_vfs_register_fs("/data", &myfs, ESP_VFS_FLAG_DEFAULT, NULL));
}
.. _context_api:
上下文感知文件系统
^^^^^^^^^^^^^^^^^^
@@ -19,6 +19,7 @@ VFS
- ``esp_vfs_register_fd_range`` 现被视为私有接口,其函数签名已调整为匹配新的 VFS API 风格。仍依赖此内部辅助函数的项目需包含 ``esp_private/socket.h`` 头文件,并请注意该 API 可能在不另行通知的情况下发生变更。
- 基于 ``esp_vfs_t`` 而非 ``esp_vfs_fs_ops_t`` 的传统 VFS API(如 ``esp_vfs_register``)已弃用,并将在下一个主版本中移除。请迁移至基于 ``esp_vfs_fs_ops_t`` 的新 API。
- TERMIOS 支持现已默认禁用。若应用程序需调用 POSIX ``termios`` API(例如用于 UART 配置的 ``tcsetattr``/``tcgetattr`` 接口),请在 menuconfig 中重新启用 :ref:`CONFIG_VFS_SUPPORT_TERMIOS` 选项。
- 不带上下文的 VFS 函数指针已弃用。请切换到带上下文感知的 ``*_p`` 系列回调函数,并使用 ``ESP_VFS_FLAG_CONTEXT_PTR`` 标志注册 VFS。如果驱动不需要每个实例各自的状态,则将上下文指针传入 ``NULL`` 即可。此项变更简化了 API 接口,并减少了 VFS 调用路径中的运行时开销。
``esp_vfs_console``
--------------------