Allow VFS file descriptors in select()

This commit is contained in:
Roland Dobai
2018-05-03 10:41:10 +02:00
parent d84add4513
commit 18e83bcd53
24 changed files with 1250 additions and 17 deletions
@@ -0,0 +1,8 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := uart_select
include $(IDF_PATH)/make/project.mk
@@ -0,0 +1,13 @@
# UART Select Example
The UART select example is for demonstrating the use of `select()` for
synchronous I/O multiplexing on the UART interface. The example waits for a
character from UART using `select()` until a blocking read without delay or a
successful non-blocking read is possible.
Please note that the same result can be achieved by using `uart_read_bytes()`
but the use of `select()` allows to use it together with other virtual
file system (VFS) drivers, e.g. LWIP sockets. For a more comprehensive example
please refer to `system/select`.
See the README.md file in the upper level 'examples' directory for more information about examples.
@@ -0,0 +1,3 @@
#
# Main Makefile. This is basically the same as a component makefile.
#
@@ -0,0 +1,90 @@
/* UART Select Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <sys/fcntl.h>
#include <sys/errno.h>
#include <sys/unistd.h>
#include <sys/select.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_vfs.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h"
static const char* TAG = "uart_select_example";
static void uart_select_task()
{
uart_config_t uart_config = {
.baud_rate = 115200,
.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);
while (1) {
int fd;
if ((fd = open("/dev/uart/0", O_RDWR)) == -1) {
ESP_LOGE(TAG, "Cannot open UART");
vTaskDelay(5000 / portTICK_PERIOD_MS);
continue;
}
// We have a driver now installed so set up the read/write functions to use driver also.
esp_vfs_dev_uart_use_driver(0);
while (1) {
int s;
fd_set rfds;
struct timeval tv = {
.tv_sec = 5,
.tv_usec = 0,
};
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
s = select(fd + 1, &rfds, NULL, NULL, &tv);
if (s < 0) {
ESP_LOGE(TAG, "Select failed: errno %d", errno);
break;
} else if (s == 0) {
ESP_LOGI(TAG, "Timeout has been reached and nothing has been received");
} else {
if (FD_ISSET(fd, &rfds)) {
char buf;
if (read(fd, &buf, 1) > 0) {
ESP_LOGI(TAG, "Received: %c", buf);
} else {
ESP_LOGE(TAG, "UART read error");
break;
}
} else {
ESP_LOGE(TAG, "No FD has been set in select()");
break;
}
}
}
close(fd);
}
vTaskDelete(NULL);
}
void app_main()
{
xTaskCreate(uart_select_task, "uart_select_task", 4*1024, NULL, 5, NULL);
}