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 "rom/ets_sys.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "driver/uart_select.h"
#define portYIELD_FROM_ISR() taskYIELD() #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_tot; /*!< Total length of current item in ring buffer*/
uint32_t tx_len_cur; uint32_t tx_len_cur;
bool wait_tx_done_flg; bool wait_tx_done_flg;
uart_select_notif_callback_t uart_select_notif_callback; /*!< Notification about select() events */
} uart_obj_t; } uart_obj_t;
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; 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; BaseType_t task_woken = 0;
while (uart_intr_status != 0x0) { while (uart_intr_status != 0x0) {
uart_select_notif_t notify = UART_SELECT_ERROR_NOTIF;
buf_idx = 0; buf_idx = 0;
uart_event.type = UART_EVENT_MAX; 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; p_uart->rx_buffered_len += p_uart->rx_stash_len;
} }
notify = UART_SELECT_READ_NOTIF;
if (task_woken == pdTRUE) { if (task_woken == pdTRUE) {
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
@ -640,17 +645,32 @@ static void uart_rx_intr_handler_default(void *param)
uart_reset_rx_fifo(uart_num); uart_reset_rx_fifo(uart_num);
uart_reg->int_clr.rxfifo_ovf = 1; uart_reg->int_clr.rxfifo_ovf = 1;
uart_event.type = UART_FIFO_OVF; uart_event.type = UART_FIFO_OVF;
notify = UART_SELECT_ERROR_NOTIF;
} else if (uart_intr_status & UART_FRM_ERR_INT_ST_M) { } else if (uart_intr_status & UART_FRM_ERR_INT_ST_M) {
uart_reg->int_clr.frm_err = 1; uart_reg->int_clr.frm_err = 1;
uart_event.type = UART_FRAME_ERR; uart_event.type = UART_FRAME_ERR;
notify = UART_SELECT_ERROR_NOTIF;
} else if (uart_intr_status & UART_PARITY_ERR_INT_ST_M) { } else if (uart_intr_status & UART_PARITY_ERR_INT_ST_M) {
uart_reg->int_clr.parity_err = 1; uart_reg->int_clr.parity_err = 1;
uart_event.type = UART_PARITY_ERR; uart_event.type = UART_PARITY_ERR;
notify = UART_SELECT_ERROR_NOTIF;
} else { } else {
uart_reg->int_clr.val = uart_intr_status; // simply clear all other intr status uart_reg->int_clr.val = uart_intr_status; // simply clear all other intr status
uart_event.type = UART_EVENT_MAX; 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 (uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart) {
if (pdFALSE == xQueueSendFromISR(p_uart->xQueueUart, (void *)&uart_event, &task_woken)) { if (pdFALSE == xQueueSendFromISR(p_uart->xQueueUart, (void *)&uart_event, &task_woken)) {
ESP_EARLY_LOGV(UART_TAG, "UART event queue full"); 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_ring_buf = NULL;
p_uart_obj[uart_num]->tx_buf_size = 0; p_uart_obj[uart_num]->tx_buf_size = 0;
} }
p_uart_obj[uart_num]->uart_select_notif_callback = NULL;
} else { } else {
ESP_LOGE(UART_TAG, "UART driver already installed"); ESP_LOGE(UART_TAG, "UART driver already installed");
return ESP_FAIL; return ESP_FAIL;
@ -1039,6 +1061,13 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
return ESP_OK; 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) 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); 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 * @brief Get mutex guarding select() notifications
*/ */
portMUX_TYPE *uart_get_selectlock(); void *uart_get_selectlock();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

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

View File

@ -20,6 +20,10 @@ COMPONENT_SRCDIRS += apps/dhcpserver \
port/esp8266/freertos \ port/esp8266/freertos \
port/esp8266/netif 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 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 lwip/src/apps/sntp/sntp.o: CFLAGS += -Wno-implicit-function-declaration

View File

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

View File

@ -448,7 +448,9 @@ typedef struct fd_set
} fd_set; } fd_set;
#elif LWIP_SOCKET_OFFSET #elif LWIP_SOCKET_OFFSET
#ifndef CONFIG_USING_ESP_VFS
#error LWIP_SOCKET_OFFSET does not work with external FD_SET! #error LWIP_SOCKET_OFFSET does not work with external FD_SET!
#endif
#elif FD_SETSIZE < MEMP_NUM_NETCONN #elif FD_SETSIZE < MEMP_NUM_NETCONN
#error "external FD_SETSIZE too small for number of sockets" #error "external FD_SETSIZE too small for number of sockets"
#endif /* FD_SET */ #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 * @param sem the semaphore to signal
*/ */
void sys_sem_signal(sys_sem_t *sem); 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 * @ingroup sys_sem
* Wait for a semaphore for the specified timeout * Wait for a semaphore for the specified timeout

View File

@ -30,4 +30,11 @@
* *
*/ */
#include "sdkconfig.h"
#include "lwip/sockets.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); 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/task.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "arch/vfs_lwip.h"
typedef xSemaphoreHandle sys_sem_t; typedef xSemaphoreHandle sys_sem_t;
typedef xSemaphoreHandle sys_mutex_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 * 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) * 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 #define LWIP_POSIX_SOCKETS_IO_NAMES 1
#endif
/** /**
* LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n. * 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 * re implement read/write/close/ioctl/fnctl to send the requested action to the right
* library (sharing select will need more work though). * 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 * 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.h"
#include "esp_vfs_dev.h" #include "esp_vfs_dev.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/uart_struct.h" #include "esp8266/uart_struct.h"
#include "lwip/sockets.h" #include "lwip/sockets.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "lwip/sys.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) 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) 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() void esp_vfs_lwip_sockets_register()
{ {
esp_vfs_t vfs = { esp_vfs_t vfs = {
.flags = ESP_VFS_FLAG_DEFAULT, .flags = ESP_VFS_FLAG_DEFAULT,
.write = &lwip_write_r, .write = &lwip_write,
.open = NULL, .open = NULL,
.fstat = NULL, .fstat = NULL,
.close = &lwip_close_r, .close = &lwip_close,
.read = &lwip_read_r, .read = &lwip_read,
.fcntl = &lwip_fcntl_r_wrapper, .fcntl = &lwip_fcntl_r_wrapper,
.ioctl = &lwip_ioctl_r_wrapper, .ioctl = &lwip_ioctl_r_wrapper,
.socket_select = &lwip_select, .socket_select = &lwip_select,

View File

@ -1,3 +1,6 @@
#pragma once
#include <sys/socket.h> #include <sys/socket.h>
#undef fcntl #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 // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "sdkconfig.h"
#include <reent.h> #include <reent.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.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 * @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); 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) if (!_GLOBAL_REENT->_stdout)
goto err; goto err;
_GLOBAL_REENT->_stderr = fopen("uart/0", "w"); _GLOBAL_REENT->_stderr = fopen("/dev/uart/0", "w");
if (!_GLOBAL_REENT->_stderr) if (!_GLOBAL_REENT->_stderr)
goto err_fail; goto err_fail;
_GLOBAL_REENT->_stdin = fopen("uart/0", "r"); _GLOBAL_REENT->_stdin = fopen("/dev/uart/0", "r");
if (!_GLOBAL_REENT->_stdin) if (!_GLOBAL_REENT->_stdin)
goto err_in; goto err_in;

View File

@ -15,6 +15,28 @@
#ifndef __ESP_SYS_SELECT_H__ #ifndef __ESP_SYS_SELECT_H__
#define __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" #include "lwip/sockets.h"
#endif
#endif //__ESP_SYS_SELECT_H__ #endif //__ESP_SYS_SELECT_H__

View File

@ -16,6 +16,7 @@
#include "esp_vfs.h" #include "esp_vfs.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#ifdef CONFIG_USING_ESP_VFS
#ifdef CONFIG_USE_ONLY_LWIP_SELECT #ifdef CONFIG_USE_ONLY_LWIP_SELECT
#include "lwip/sockets.h" #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); return esp_vfs_select(nfds, readfds, writefds, errorfds, timeout);
#endif #endif
} }
#endif /* CONFIG_USING_ESP_VFS */

View File

@ -22,6 +22,57 @@
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "esp_log.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) int _open_r(struct _reent *r, const char *filename, int flags, int mode)
{ {
return 0; return 0;
@ -70,11 +121,13 @@ int _fstat_r(struct _reent *r, int fd, struct stat *s)
return 0; 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 *_malloc_r(struct _reent *r, size_t n)
{ {
void *return_addr = (void *)__builtin_return_address(0); 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); _heap_caps_free(ptr, return_addr, 0);
} }
void _exit(int status)
{
while (1);
}
void abort(void) void abort(void)
{ {
ESP_LOGE("ABORT","Error found and abort!"); ESP_LOGE("ABORT","Error found and abort!");
@ -117,3 +165,13 @@ void abort(void)
*((int *)NULL) = 0; *((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 <stdlib.h>
#include <string.h> #include <string.h>
#include "lwip/sockets.h" #include <sys/socket.h>
#include "lwip/dns.h" #include "lwip/dns.h"
#include "lwip/netdb.h" #include "lwip/netdb.h"

View File

@ -1,3 +1,4 @@
if(CONFIG_USING_ESP_VFS)
set(COMPONENT_SRCS "vfs.c" set(COMPONENT_SRCS "vfs.c"
"vfs_uart.c") "vfs_uart.c")
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
@ -5,3 +6,4 @@ 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" 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 config SUPPRESS_SELECT_DEBUG_OUTPUT
bool "Suppress select() related debug outputs" bool "Suppress select() related debug outputs"
default y default y
depends on USING_ESP_VFS
help help
Select() related functions might produce an unconveniently lot of Select() related functions might produce an unconveniently lot of
debug outputs when one sets the default log level to DEBUG or higher. 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 config SUPPORT_TERMIOS
bool "Add support for termios.h" bool "Add support for termios.h"
default y default y
depends on USING_ESP_VFS
help help
Disabling this option can save memory when the support for termios.h is not required. 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.) # (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.h"
#include "esp_vfs_dev.h" #include "esp_vfs_dev.h"
#include "esp_attr.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 "driver/uart.h"
#include "sdkconfig.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 // TODO: make the number of UARTs chip dependent
#define UART_NUM 3 #define UART_NUM 2
// Token signifying that no character is available // Token signifying that no character is available
#define NONE -1 #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); static int uart_rx_char_via_driver(int fd);
// Pointers to UART peripherals // 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 // per-UART locks, lazily initialized
static _lock_t s_uart_read_locks[UART_NUM]; static _lock_t s_uart_read_locks[UART_NUM];
static _lock_t s_uart_write_locks[UART_NUM]; static _lock_t s_uart_write_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 };
// Per-UART non-blocking flag. Note: default implementation does not honor this // Per-UART non-blocking flag. Note: default implementation does not honor this
// flag, all reads are non-blocking. This option becomes effective if UART // flag, all reads are non-blocking. This option becomes effective if UART
// driver is used. // driver is used.
@ -94,12 +104,12 @@ static void uart_end_select();
// Functions used to write bytes to UART. Default to "basic" functions. // Functions used to write bytes to UART. Default to "basic" functions.
static tx_func_t s_uart_tx_func[UART_NUM] = { 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. // Functions used to read bytes from UART. Default to "basic" functions.
static rx_func_t s_uart_rx_func[UART_NUM] = { 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() static void uart_select_task()
{ {
uart_config_t uart_config = { uart_config_t uart_config = {
.baud_rate = 115200, .baud_rate = 74880,
.data_bits = UART_DATA_8_BITS, .data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE, .parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1, .stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
}; };
uart_param_config(UART_NUM_0, &uart_config); 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) { while (1) {
int fd; int fd;

View File

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