使用 fgets 从 UART 读取行并选择

问题描述 投票:0回答:1

我正在尝试在 esp-idf 中使用

fgets
从 UART 读取整行。

基本参考代码是选择example。 到目前为止,这是我的代码:

#define DLP_RFID2_BUF_SIZE 256
static char buffer[DLP_RFID2_BUF_SIZE];

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,
    .source_clk = UART_SCLK_DEFAULT,
};

ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, DLP_RFID2_BUF_SIZE * 2, 0, 0, NULL, 0));
ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, PIN_DLP_RFID2_TX, PIN_DLP_RFID2_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

if ((fd = open("/dev/uart/1", O_RDWR)) == -1) 
{
    ESP_LOGE(TAG, "Cannot open UART");
    return fd;
}

uart_vfs_dev_use_driver(UART_NUM_1);

这里是循环函数:

int s;
fd_set rfds;
struct timeval tv = {
    .tv_sec = 0,
    .tv_usec = 20000,
};

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 (%s)", errno, strerror(errno));
} 
else if (s == 0) 
{
    ESP_LOGI(TAG, "Timeout has been reached and nothing has been received");
} 
else 
{
    if (FD_ISSET(fd, &rfds)) 
    {
        if (fgets(buffer, sizeof(buffer), ???))
        {
            // do something
        }
    } 
    else 
    {
        ESP_LOGE(TAG, "No FD has been set in select()");
    }
}

fgets函数需要一个FILE *

变量作为第三个参数。
但我只有
int
fd
s
)和
fd_set
rfds
)。

我尝试更改代码以使用

FILE *

FILE *f = fopen("/dev/uart/1", "rw"); // ... if (fgets(buffer, sizeof(buffer) - 1, f)) { // do something }
由于 

fgets

 阻塞,我需要先检查是否有一些数据。
但现在 
select
 需要 
fd_set
 而不是 
FILE *
:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
如何将 

FILE *

“转换”为 
fd_set
int
 转换为 
FILE *

c file uart esp-idf
1个回答
0
投票
您的问题是您需要为

select

(2) 使用文件描述符,但需要为 
FILE
(3) 使用 
fgets

这里有两种可能性。

给定一个

FILE

 对象,您可以使用函数 
fileno
 来获取相应的文件描述符以在 
select
 中使用。

或者,如果您最初使用

open

(2) 打开文件,以获取文件描述符,您可以使用 
fdopen
(3) 从它创建一个 
FILE
 对象。

我在这两种情况下都说“可能”,因为 C 标准中都没有定义

filenofdopen

,所以如果您处于受限环境中(您提到的 UART 暗示了这一点),它们可能不是可用的。  不过,它们都得到了非常广泛的实现,因此,如果您的库足够大,可以拥有 
fgets
,那么它肯定至少会拥有两者之一。
	

© www.soinside.com 2019 - 2024. All rights reserved.