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

Linux TTY输入队列太慢,无法返回数据,linux,serial-port,embedded-linux,tty,Linux,Serial Port,Embedded Linux,Tty,我最近注意到在AT91SAM9G15上运行的系统上有一个非常奇怪的行为:尽管我一直在读取串行端口,但TTY驱动程序有时需要1,2秒才能从输入队列中传递数据。 问题是:我并没有丢失任何数据,只是需要太多的调用才能读取数据 也许我的代码可以帮助解释这个问题 首先,我设置了我的串行端口: /* 8N1 */ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; /** Parity bit (none) */ tty.c_cflag &= ~(PARE

我最近注意到在AT91SAM9G15上运行的系统上有一个非常奇怪的行为:尽管我一直在读取串行端口,但TTY驱动程序有时需要1,2秒才能从输入队列中传递数据。 问题是:我并没有丢失任何数据,只是需要太多的调用才能读取数据

也许我的代码可以帮助解释这个问题

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

/* 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;
稍后,将调用select:

s_ret = select(rfid_fd + 1, &set, NULL, NULL, &port_timeval);
因此,阅读可以发挥它的魔力:

...
 if ((rd_ret = read(rfid_fd, &recv_buff[u16_recv_len], (u16_req_len - u16_recv_len))) > 0)
...
就在那之后,如果我持续读取串行端口15秒,比如说,好几次我都看不到有数据出现,而我知道数据是按时到达的,并且有时间戳,但是数据出现得很晚。从输入队列获取数据的延迟可能从300ms到1,5s不等

我已经尝试了我能想到的各种设置。现在很棘手,因为我不知道at91 UART驱动程序是否没有向tty驱动程序发送数据,或者tty驱动程序没有获取数据?哪一个在这里


任何帮助都将不胜感激。

设置端口标志的正常过程是读取termios结构,将其保存以供以后还原,在其副本中修改要更改的标志,然后执行tcsetattr调用。您已初始化c_lflag=0;这可能会对你的问题产生一些副作用

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


经过这么多的猜测,您还没有发布任何可复制的代码来检查您所说的内容,因此这是我们能为您提供的最大帮助。

也许我的代码将有助于解释问题-不,这些微小的代码片段是不够的。对于一个可运行的串行终端,您所显示的可能是不完整的。请参阅,为什么您认为设置c_lflag=0;将终端置于y原始模式。你确定吗?没有其他可能依赖于实现的标志在中间吗?当然为什么不使用tcgetattr->mask flags->tcsetattr,因为这是推荐的方法?顺便说一句,将VMIN和VTIME都设置为0会使您全速消耗cpu,因为您只会在cpu可用时获得输入。这应该更好