feat(vfs): Modify for esp8266

This commit is contained in:
dongheng
2019-03-07 14:58:44 +08:00
parent e36706d776
commit d11543400e
25 changed files with 225 additions and 51 deletions

View File

@ -33,6 +33,7 @@
#include "rom/ets_sys.h"
#include "driver/uart.h"
#include "driver/uart_select.h"
#define portYIELD_FROM_ISR() taskYIELD()
@ -88,6 +89,7 @@ typedef struct {
uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/
uint32_t tx_len_cur;
bool wait_tx_done_flg;
uart_select_notif_callback_t uart_select_notif_callback; /*!< Notification about select() events */
} uart_obj_t;
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
@ -502,6 +504,7 @@ static void uart_rx_intr_handler_default(void *param)
BaseType_t task_woken = 0;
while (uart_intr_status != 0x0) {
uart_select_notif_t notify = UART_SELECT_ERROR_NOTIF;
buf_idx = 0;
uart_event.type = UART_EVENT_MAX;
@ -628,6 +631,8 @@ static void uart_rx_intr_handler_default(void *param)
p_uart->rx_buffered_len += p_uart->rx_stash_len;
}
notify = UART_SELECT_READ_NOTIF;
if (task_woken == pdTRUE) {
portYIELD_FROM_ISR();
}
@ -640,17 +645,32 @@ static void uart_rx_intr_handler_default(void *param)
uart_reset_rx_fifo(uart_num);
uart_reg->int_clr.rxfifo_ovf = 1;
uart_event.type = UART_FIFO_OVF;
notify = UART_SELECT_ERROR_NOTIF;
} else if (uart_intr_status & UART_FRM_ERR_INT_ST_M) {
uart_reg->int_clr.frm_err = 1;
uart_event.type = UART_FRAME_ERR;
notify = UART_SELECT_ERROR_NOTIF;
} else if (uart_intr_status & UART_PARITY_ERR_INT_ST_M) {
uart_reg->int_clr.parity_err = 1;
uart_event.type = UART_PARITY_ERR;
notify = UART_SELECT_ERROR_NOTIF;
} else {
uart_reg->int_clr.val = uart_intr_status; // simply clear all other intr status
uart_event.type = UART_EVENT_MAX;
notify = UART_SELECT_ERROR_NOTIF;
}
#ifdef CONFIG_USING_ESP_VFS
if (uart_event.type != UART_EVENT_MAX && p_uart->uart_select_notif_callback) {
p_uart->uart_select_notif_callback(uart_num, notify, &task_woken);
if (task_woken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
#else
(void)notify;
#endif
if (uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart) {
if (pdFALSE == xQueueSendFromISR(p_uart->xQueueUart, (void *)&uart_event, &task_woken)) {
ESP_EARLY_LOGV(UART_TAG, "UART event queue full");
@ -950,6 +970,8 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
p_uart_obj[uart_num]->tx_ring_buf = NULL;
p_uart_obj[uart_num]->tx_buf_size = 0;
}
p_uart_obj[uart_num]->uart_select_notif_callback = NULL;
} else {
ESP_LOGE(UART_TAG, "UART driver already installed");
return ESP_FAIL;
@ -1039,6 +1061,13 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
return ESP_OK;
}
void uart_set_select_notif_callback(uart_port_t uart_num, uart_select_notif_callback_t uart_select_notif_callback)
{
if (uart_num < UART_NUM_MAX && p_uart_obj[uart_num]) {
p_uart_obj[uart_num]->uart_select_notif_callback = (uart_select_notif_callback_t) uart_select_notif_callback;
}
}
esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);

View File

@ -40,7 +40,7 @@ void uart_set_select_notif_callback(uart_port_t uart_num, uart_select_notif_call
/**
* @brief Get mutex guarding select() notifications
*/
portMUX_TYPE *uart_get_selectlock();
void *uart_get_selectlock();
#ifdef __cplusplus
}

View File

@ -60,7 +60,6 @@
#define lwip_select lwip_select_esp
#define lwip_ioctlsocket lwip_ioctl_esp
#if LWIP_POSIX_SOCKETS_IO_NAMES
#undef lwip_read
#undef lwip_write
#undef lwip_writev
@ -75,7 +74,6 @@
#define lwip_close lwip_close_esp
#define lwip_fcntl lwip_fcntl_esp
#define lwip_ioctl lwip_ioctl_esp
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
#include "../../lwip/src/api/sockets.c"
@ -100,7 +98,6 @@
#undef lwip_select
#undef lwip_ioctlsocket
#if LWIP_POSIX_SOCKETS_IO_NAMES
#undef lwip_read
#undef lwip_write
#undef lwip_writev
@ -108,7 +105,6 @@
#undef closesocket
#undef lwip_fcntl
#undef lwip_ioctl
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
/********************************************************************/
#define LWIP_SYNC_MT_SLEEP_MS 10

View File

@ -20,6 +20,10 @@ COMPONENT_SRCDIRS += apps/dhcpserver \
port/esp8266/freertos \
port/esp8266/netif
ifdef CONFIG_USING_ESP_VFS
COMPONENT_SRCDIRS += port
endif
CFLAGS += -Wno-address #lots of LWIP source files evaluate macros that check address of stack variables
lwip/src/apps/sntp/sntp.o: CFLAGS += -Wno-implicit-function-declaration

View File

@ -347,6 +347,11 @@ lwip_init(void)
/* Modules initialization */
stats_init();
#ifdef CONFIG_USING_ESP_VFS
esp_vfs_lwip_sockets_register();
#endif
#if !NO_SYS
sys_init();
#endif /* !NO_SYS */

View File

@ -448,7 +448,9 @@ typedef struct fd_set
} fd_set;
#elif LWIP_SOCKET_OFFSET
#ifndef CONFIG_USING_ESP_VFS
#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
#endif
#elif FD_SETSIZE < MEMP_NUM_NETCONN
#error "external FD_SETSIZE too small for number of sockets"
#endif /* FD_SET */

View File

@ -179,6 +179,14 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count);
* @param sem the semaphore to signal
*/
void sys_sem_signal(sys_sem_t *sem);
#if ESP_LWIP
/** Signals a semaphore (ISR version)
* @param sem the semaphore to signal
* @return non-zero if a higher priority task has been woken */
int sys_sem_signal_isr(sys_sem_t *sem);
#endif
/**
* @ingroup sys_sem
* Wait for a semaphore for the specified timeout

View File

@ -30,4 +30,11 @@
*
*/
#include "sdkconfig.h"
#include "lwip/sockets.h"
#ifdef CONFIG_USING_ESP_VFS
#include <unistd.h>
#include <fcntl.h>
#endif

View File

@ -109,6 +109,14 @@ sys_sem_signal(sys_sem_t *sem)
xSemaphoreGive(*sem);
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore (from ISR)
int sys_sem_signal_isr(sys_sem_t *sem)
{
BaseType_t woken = pdFALSE;
xSemaphoreGiveFromISR(*sem, &woken);
return woken == pdTRUE;
}
/*-----------------------------------------------------------------------------------*/
/*

View File

@ -37,6 +37,7 @@
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "arch/vfs_lwip.h"
typedef xSemaphoreHandle sys_sem_t;
typedef xSemaphoreHandle sys_mutex_t;

View File

@ -1412,7 +1412,11 @@ size_t memp_malloc_get_size(size_t type);
* Disable this option if you use a POSIX operating system that uses the same
* names (read, write & close). (only used if you use sockets.c)
*/
#ifdef CONFIG_USING_ESP_VFS
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#else
#define LWIP_POSIX_SOCKETS_IO_NAMES 1
#endif
/**
* LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n.
@ -1421,7 +1425,7 @@ size_t memp_malloc_get_size(size_t type);
* re implement read/write/close/ioctl/fnctl to send the requested action to the right
* library (sharing select will need more work though).
*/
#define LWIP_SOCKET_OFFSET 0
#define LWIP_SOCKET_OFFSET (FD_SETSIZE - CONFIG_LWIP_MAX_SOCKETS)
/**
* LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT

View File

@ -21,7 +21,7 @@
#include "esp_vfs.h"
#include "esp_vfs_dev.h"
#include "esp_attr.h"
#include "soc/uart_struct.h"
#include "esp8266/uart_struct.h"
#include "lwip/sockets.h"
#include "sdkconfig.h"
#include "lwip/sys.h"
@ -42,23 +42,23 @@ static void lwip_stop_socket_select_isr(BaseType_t *woken)
static int lwip_fcntl_r_wrapper(int fd, int cmd, va_list args)
{
return lwip_fcntl_r(fd, cmd, va_arg(args, int));
return lwip_fcntl(fd, cmd, va_arg(args, int));
}
static int lwip_ioctl_r_wrapper(int fd, int cmd, va_list args)
{
return lwip_ioctl_r(fd, cmd, va_arg(args, void *));
return lwip_ioctl(fd, cmd, va_arg(args, void *));
}
void esp_vfs_lwip_sockets_register()
{
esp_vfs_t vfs = {
.flags = ESP_VFS_FLAG_DEFAULT,
.write = &lwip_write_r,
.write = &lwip_write,
.open = NULL,
.fstat = NULL,
.close = &lwip_close_r,
.read = &lwip_read_r,
.close = &lwip_close,
.read = &lwip_read,
.fcntl = &lwip_fcntl_r_wrapper,
.ioctl = &lwip_ioctl_r_wrapper,
.socket_select = &lwip_select,

View File

@ -1,3 +1,6 @@
#pragma once
#include <sys/socket.h>
#undef fcntl

View File

@ -1,13 +0,0 @@
/* <dirent.h> includes <sys/dirent.h>, which is this file. On a
system which supports <dirent.h>, this file is overridden by
dirent.h in the libc/sys/.../sys directory. On a system which does
not support <dirent.h>, we will get this file which uses #error to force
an error. */
#ifdef __cplusplus
extern "C" {
#endif
//#error "<dirent.h> not supported"
#ifdef __cplusplus
}
#endif

View File

@ -12,11 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef CONFIG_USING_ESP_VFS
#include "esp_vfs_dev.h"
#endif
/*
* @brief Initialize global and thread's private reent object data. We add this instead of
@ -47,15 +51,19 @@ int esp_newlib_init(void)
{
esp_reent_init(_global_impure_ptr);
_GLOBAL_REENT->_stdout = fopen("uart/0", "w");
#ifdef CONFIG_USING_ESP_VFS
esp_vfs_dev_uart_register();
#endif
_GLOBAL_REENT->_stdout = fopen("/dev/uart/0", "w");
if (!_GLOBAL_REENT->_stdout)
goto err;
_GLOBAL_REENT->_stderr = fopen("uart/0", "w");
_GLOBAL_REENT->_stderr = fopen("/dev/uart/0", "w");
if (!_GLOBAL_REENT->_stderr)
goto err_fail;
_GLOBAL_REENT->_stdin = fopen("uart/0", "r");
_GLOBAL_REENT->_stdin = fopen("/dev/uart/0", "r");
if (!_GLOBAL_REENT->_stdin)
goto err_in;

View File

@ -15,6 +15,28 @@
#ifndef __ESP_SYS_SELECT_H__
#define __ESP_SYS_SELECT_H__
#include "sdkconfig.h"
#ifdef CONFIG_USING_ESP_VFS
#include <sys/types.h>
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
#ifdef __cplusplus
} // extern "C"
#endif
#else
#include "lwip/sockets.h"
#endif
#endif //__ESP_SYS_SELECT_H__

View File

@ -16,6 +16,7 @@
#include "esp_vfs.h"
#include "sdkconfig.h"
#ifdef CONFIG_USING_ESP_VFS
#ifdef CONFIG_USE_ONLY_LWIP_SELECT
#include "lwip/sockets.h"
@ -62,3 +63,4 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct
return esp_vfs_select(nfds, readfds, writefds, errorfds, timeout);
#endif
}
#endif /* CONFIG_USING_ESP_VFS */

View File

@ -22,6 +22,57 @@
#include "FreeRTOS.h"
#include "esp_log.h"
#ifdef CONFIG_USING_ESP_VFS
#include "esp_vfs.h"
int _open_r(struct _reent *r, const char *filename, int flags, int mode)
{
return esp_vfs_open(r, filename, flags, mode);
}
_ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len)
{
return esp_vfs_read(r, fd, buf, len);
}
_ssize_t _write_r(struct _reent *r, int fd, const void *buf, size_t len)
{
return esp_vfs_write(r, fd, buf, len);
}
_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence)
{
return esp_vfs_lseek(r, fd, where, whence);
}
int _close_r(struct _reent *r, int fd)
{
return esp_vfs_close(r, fd);
}
int _rename_r(struct _reent *r, const char *from, const char *to)
{
return esp_vfs_rename(r, from, to);
}
int _unlink_r(struct _reent *r, const char *filename)
{
return esp_vfs_unlink(r, filename);
}
int _fstat_r(struct _reent *r, int fd, struct stat *s)
{
return esp_vfs_fstat(r, fd, s);
}
int _stat_r(struct _reent *r, const char *path, struct stat *st)
{
return esp_vfs_stat(r, path, st);
}
#else
int _open_r(struct _reent *r, const char *filename, int flags, int mode)
{
return 0;
@ -70,11 +121,13 @@ int _fstat_r(struct _reent *r, int fd, struct stat *s)
return 0;
}
void *_sbrk_r(struct _reent *r, ptrdiff_t incr)
int _stat_r(struct _reent *r, const char *path, struct stat *st)
{
return NULL;
return 0;
}
#endif /* CONFIG_USING_ESP_VFS */
void *_malloc_r(struct _reent *r, size_t n)
{
void *return_addr = (void *)__builtin_return_address(0);
@ -103,11 +156,6 @@ void _free_r(struct _reent *r, void *ptr)
_heap_caps_free(ptr, return_addr, 0);
}
void _exit(int status)
{
while (1);
}
void abort(void)
{
ESP_LOGE("ABORT","Error found and abort!");
@ -116,4 +164,14 @@ void abort(void)
while (1) {
*((int *)NULL) = 0;
}
}
}
void _exit(int status)
{
abort();
}
void *_sbrk_r(struct _reent *r, ptrdiff_t incr)
{
abort();
}

View File

@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "lwip/sockets.h"
#include <sys/socket.h>
#include "lwip/dns.h"
#include "lwip/netdb.h"

View File

@ -1,7 +1,9 @@
set(COMPONENT_SRCS "vfs.c"
"vfs_uart.c")
set(COMPONENT_ADD_INCLUDEDIRS "include")
if(CONFIG_USING_ESP_VFS)
set(COMPONENT_SRCS "vfs.c"
"vfs_uart.c")
set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_REQUIRES)
set(COMPONENT_REQUIRES)
register_component()
register_component()
endif()

View File

@ -1,8 +1,16 @@
menu "Virtual file system"
config USING_ESP_VFS
bool "Using espressif VFS"
default y
help
Enable this option, espressif VFS can be used. Users can use APIs like "open", "read", "write"
and so on to operate I/O device which is registered.
config SUPPRESS_SELECT_DEBUG_OUTPUT
bool "Suppress select() related debug outputs"
default y
depends on USING_ESP_VFS
help
Select() related functions might produce an unconveniently lot of
debug outputs when one sets the default log level to DEBUG or higher.
@ -12,6 +20,7 @@ config SUPPRESS_SELECT_DEBUG_OUTPUT
config SUPPORT_TERMIOS
bool "Add support for termios.h"
default y
depends on USING_ESP_VFS
help
Disabling this option can save memory when the support for termios.h is not required.

View File

@ -3,3 +3,8 @@
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
ifndef CONFIG_USING_ESP_VFS
COMPONENT_ADD_INCLUDEDIRS :=
COMPONENT_SRCDIRS :=
endif

View File

@ -22,13 +22,23 @@
#include "esp_vfs.h"
#include "esp_vfs_dev.h"
#include "esp_attr.h"
#include "soc/uart_struct.h"
#include "esp8266/uart_struct.h"
#include "driver/uart_select.h"
#include "driver/uart.h"
#include "sdkconfig.h"
#include "driver/uart_select.h"
#ifdef portENTER_CRITICAL
#undef portENTER_CRITICAL
#define portENTER_CRITICAL(_lock) vPortEnterCritical()
#endif
#ifdef portEXIT_CRITICAL
#undef portEXIT_CRITICAL
#define portEXIT_CRITICAL(_lock) vPortExitCritical()
#endif
// TODO: make the number of UARTs chip dependent
#define UART_NUM 3
#define UART_NUM 2
// Token signifying that no character is available
#define NONE -1
@ -47,12 +57,12 @@ static void uart_tx_char_via_driver(int fd, int c);
static int uart_rx_char_via_driver(int fd);
// Pointers to UART peripherals
static uart_dev_t* s_uarts[UART_NUM] = {&UART0, &UART1, &UART2};
static uart_dev_t* s_uarts[UART_NUM] = {&uart0, &uart1};
// per-UART locks, lazily initialized
static _lock_t s_uart_read_locks[UART_NUM];
static _lock_t s_uart_write_locks[UART_NUM];
// 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 };
// 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.
@ -94,12 +104,12 @@ static void uart_end_select();
// Functions used to write bytes to UART. Default to "basic" functions.
static tx_func_t s_uart_tx_func[UART_NUM] = {
&uart_tx_char, &uart_tx_char, &uart_tx_char
&uart_tx_char, &uart_tx_char
};
// Functions used to read bytes from UART. Default to "basic" functions.
static rx_func_t s_uart_rx_func[UART_NUM] = {
&uart_rx_char, &uart_rx_char, &uart_rx_char
&uart_rx_char, &uart_rx_char
};

View File

@ -23,14 +23,14 @@ static const char* TAG = "uart_select_example";
static void uart_select_task()
{
uart_config_t uart_config = {
.baud_rate = 115200,
.baud_rate = 74880,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM_0, &uart_config);
uart_driver_install(UART_NUM_0, 2*1024, 0, 0, NULL, 0);
uart_driver_install(UART_NUM_0, 2*1024, 0, 0, NULL);
while (1) {
int fd;

View File

@ -0,0 +1,4 @@
CONFIG_USING_ESP_VFS=y
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
CONFIG_SUPPORT_TERMIOS=y