mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
vfs: implement fcntl via VFS interface
This commit is contained in:
parent
141b1174c6
commit
1e4587a09f
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/reent.h>
|
#include <sys/reent.h>
|
||||||
@ -140,6 +141,10 @@ typedef struct
|
|||||||
int (*rmdir_p)(void* ctx, const char* name);
|
int (*rmdir_p)(void* ctx, const char* name);
|
||||||
int (*rmdir)(const char* name);
|
int (*rmdir)(const char* name);
|
||||||
};
|
};
|
||||||
|
union {
|
||||||
|
int (*fcntl_p)(void* ctx, int fd, int cmd, va_list args);
|
||||||
|
int (*fcntl)(int fd, int cmd, va_list args);
|
||||||
|
};
|
||||||
} esp_vfs_t;
|
} esp_vfs_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,3 +472,20 @@ int rmdir(const char* name)
|
|||||||
CHECK_AND_CALL(ret, r, vfs, rmdir, path_within_vfs);
|
CHECK_AND_CALL(ret, r, vfs, rmdir, path_within_vfs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fcntl(int fd, int cmd, ...)
|
||||||
|
{
|
||||||
|
const vfs_entry_t* vfs = get_vfs_for_fd(fd);
|
||||||
|
struct _reent* r = __getreent();
|
||||||
|
if (vfs == NULL) {
|
||||||
|
__errno_r(r) = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int local_fd = translate_fd(vfs, fd);
|
||||||
|
int ret;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, cmd);
|
||||||
|
CHECK_AND_CALL(ret, r, vfs, fcntl, local_fd, cmd, args);
|
||||||
|
va_end(args);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -14,11 +14,13 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
#include "esp_vfs.h"
|
#include "esp_vfs.h"
|
||||||
#include "esp_vfs_dev.h"
|
#include "esp_vfs_dev.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "sys/errno.h"
|
|
||||||
#include "sys/lock.h"
|
|
||||||
#include "soc/uart_struct.h"
|
#include "soc/uart_struct.h"
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
@ -48,6 +50,10 @@ static uart_dev_t* s_uarts[UART_NUM] = {&UART0, &UART1, &UART2};
|
|||||||
static _lock_t s_uart_locks[UART_NUM];
|
static _lock_t s_uart_locks[UART_NUM];
|
||||||
// One-character buffer used for newline conversion code, per UART
|
// One-character buffer used for newline conversion code, per UART
|
||||||
static int s_peek_char[UART_NUM] = { NONE, NONE, NONE };
|
static int s_peek_char[UART_NUM] = { NONE, NONE, NONE };
|
||||||
|
// Per-UART non-blocking flag. Note: default implementation does not honor this
|
||||||
|
// flag, all reads are non-blocking. This option becomes effective if UART
|
||||||
|
// driver is used.
|
||||||
|
static bool s_non_blocking[UART_NUM];
|
||||||
|
|
||||||
// Newline conversion mode when transmitting
|
// Newline conversion mode when transmitting
|
||||||
static esp_line_endings_t s_tx_mode =
|
static esp_line_endings_t s_tx_mode =
|
||||||
@ -122,8 +128,9 @@ static int uart_rx_char(int fd)
|
|||||||
static int uart_rx_char_via_driver(int fd)
|
static int uart_rx_char_via_driver(int fd)
|
||||||
{
|
{
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
int n = uart_read_bytes(fd, &c, 1, portMAX_DELAY);
|
int timeout = s_non_blocking[fd] ? 0 : portMAX_DELAY;
|
||||||
if (n == 0) {
|
int n = uart_read_bytes(fd, &c, 1, timeout);
|
||||||
|
if (n <= 0) {
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
@ -203,6 +210,8 @@ static ssize_t uart_read(int fd, void* data, size_t size)
|
|||||||
uart_return_char(fd, c2);
|
uart_return_char(fd, c2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (c == NONE) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
data_c[received] = (char) c;
|
data_c[received] = (char) c;
|
||||||
++received;
|
++received;
|
||||||
@ -231,6 +240,25 @@ static int uart_close(int fd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int uart_fcntl(int fd, int cmd, va_list args)
|
||||||
|
{
|
||||||
|
assert(fd >=0 && fd < 3);
|
||||||
|
int result = 0;
|
||||||
|
if (cmd == F_GETFL) {
|
||||||
|
if (s_non_blocking[fd]) {
|
||||||
|
result |= O_NONBLOCK;
|
||||||
|
}
|
||||||
|
} else if (cmd == F_SETFL) {
|
||||||
|
int arg = va_arg(args, int);
|
||||||
|
s_non_blocking[fd] = (arg & O_NONBLOCK) != 0;
|
||||||
|
} else {
|
||||||
|
// unsupported operation
|
||||||
|
result = -1;
|
||||||
|
errno = ENOSYS;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void esp_vfs_dev_uart_register()
|
void esp_vfs_dev_uart_register()
|
||||||
{
|
{
|
||||||
esp_vfs_t vfs = {
|
esp_vfs_t vfs = {
|
||||||
@ -241,11 +269,7 @@ void esp_vfs_dev_uart_register()
|
|||||||
.fstat = &uart_fstat,
|
.fstat = &uart_fstat,
|
||||||
.close = &uart_close,
|
.close = &uart_close,
|
||||||
.read = &uart_read,
|
.read = &uart_read,
|
||||||
.lseek = NULL,
|
.fcntl = &uart_fcntl
|
||||||
.stat = NULL,
|
|
||||||
.link = NULL,
|
|
||||||
.unlink = NULL,
|
|
||||||
.rename = NULL
|
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &vfs, NULL));
|
ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &vfs, NULL));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user