TTY输入队列太慢而无法返回数据

时间:2017-02-08 20:34:35

标签: linux serial-port embedded-linux tty

我最近注意到我的系统上有一个非常奇怪的行为(在AT91SAM9G15上运行):尽管我正在连续读取串口,但TTY驱动程序有时需要1,2s来从输入队列传送数据。 事情是:我没有丢失任何数据,它只需要太多的电话来阅读它。

也许我的代码会帮助解释这个问题。

首先,我设置了我的串口:

/* 8N1 */
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
/** Parity bit (none) */
tty.c_cflag &= ~(PARENB | PARODD);
/** Stop bit (1)*/
tty.c_cflag &= ~CSTOPB;
/* Noncanonical mode */
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] =  0;
tty.c_cc[VTIME] = 0;

稍后,选择名为:

s_ret = select(rfid_fd + 1, &set, NULL, NULL, &port_timeval);

所以read()可以做到它的魔力:

...
 if ((rd_ret = read(rfid_fd, &recv_buff[u16_recv_len], (u16_req_len - u16_recv_len))) > 0)
...

之后,如果我继续阅读15秒的串口,我可以看到几次没有数据,而且我知道准时到达的数据(它的时间戳)迟到了。从输入队列中获取数据的延迟可能从300毫秒到1.5秒不等。

我尝试过各种各样的设置。现在这很棘手,因为我不知道at91 UART驱动程序是否没有向tty驱动程序提供数据或tty驱动程序没有获取它?这是哪个?

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

设置端口标志的正常过程是读取termios结构,将其保存以供以后恢复,修改(在其副本中)要更改的标志,并执行tcsetattr()呼叫。您已初始化c_lflag = 0;,这可能会产生与您的问题相关的一些次要影响。

您必须考虑的下一件事是阅读有关VMINVTIME元素的文档。将两者都设置为0会使驱动程序成为非阻塞设备,因此您将在循环中尝试读取缓冲区中的任何内容。但在此之前,请三思而后行,你有两个线程竞争将字符放入缓冲区(你的进程,试图从缓冲区和驱动程序中断例程中获取它,试图将字符只是读取)而不休息。等待一个角色可用会更好(也可能是问题),将VMIN设置为1,将VTIME设置为0。这使得驱动程序在一个角色可用时立即唤醒您的进程,并且可能更接近您想要的角色。

经过所有这些猜测之后,您还没有发布任何可用于检查您所说内容的可重现代码,因此这是我们为您提供的最大帮助。