1 /* UART Select Example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 #include <stdio.h>
10 #include <sys/fcntl.h>
11 #include <sys/errno.h>
12 #include <sys/unistd.h>
13 #include <sys/select.h>
14 #include "freertos/FreeRTOS.h"
15 #include "freertos/task.h"
16 #include "esp_log.h"
17 #include "esp_vfs.h"
18 #include "esp_vfs_dev.h"
19 #include "driver/uart.h"
20 
21 static const char* TAG = "uart_select_example";
22 
uart_select_task(void * arg)23 static void uart_select_task(void *arg)
24 {
25     uart_config_t uart_config = {
26         .baud_rate = 115200,
27         .data_bits = UART_DATA_8_BITS,
28         .parity    = UART_PARITY_DISABLE,
29         .stop_bits = UART_STOP_BITS_1,
30         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
31         .source_clk = UART_SCLK_APB,
32     };
33     uart_driver_install(UART_NUM_0, 2*1024, 0, 0, NULL, 0);
34     uart_param_config(UART_NUM_0, &uart_config);
35 
36     while (1) {
37         int fd;
38 
39         if ((fd = open("/dev/uart/0", O_RDWR)) == -1) {
40             ESP_LOGE(TAG, "Cannot open UART");
41             vTaskDelay(5000 / portTICK_PERIOD_MS);
42             continue;
43         }
44 
45         // We have a driver now installed so set up the read/write functions to use driver also.
46         esp_vfs_dev_uart_use_driver(0);
47 
48         while (1) {
49             int s;
50             fd_set rfds;
51             struct timeval tv = {
52                 .tv_sec = 5,
53                 .tv_usec = 0,
54             };
55 
56             FD_ZERO(&rfds);
57             FD_SET(fd, &rfds);
58 
59             s = select(fd + 1, &rfds, NULL, NULL, &tv);
60 
61             if (s < 0) {
62                 ESP_LOGE(TAG, "Select failed: errno %d", errno);
63                 break;
64             } else if (s == 0) {
65                 ESP_LOGI(TAG, "Timeout has been reached and nothing has been received");
66             } else {
67                 if (FD_ISSET(fd, &rfds)) {
68                     char buf;
69                     if (read(fd, &buf, 1) > 0) {
70                         ESP_LOGI(TAG, "Received: %c", buf);
71                         // Note: Only one character was read even the buffer contains more. The other characters will
72                         // be read one-by-one by subsequent calls to select() which will then return immediately
73                         // without timeout.
74                     } else {
75                         ESP_LOGE(TAG, "UART read error");
76                         break;
77                     }
78                 } else {
79                     ESP_LOGE(TAG, "No FD has been set in select()");
80                     break;
81                 }
82             }
83         }
84 
85         close(fd);
86     }
87 
88     vTaskDelete(NULL);
89 }
90 
app_main(void)91 void app_main(void)
92 {
93     xTaskCreate(uart_select_task, "uart_select_task", 4*1024, NULL, 5, NULL);
94 }
95