我最近注意到我的系统上有一个非常奇怪的行为(在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驱动程序没有获取它?这是哪个?
任何帮助都将不胜感激。
答案 0 :(得分:0)
设置端口标志的正常过程是读取termios
结构,将其保存以供以后恢复,修改(在其副本中)要更改的标志,并执行tcsetattr()
呼叫。您已初始化c_lflag = 0;
,这可能会产生与您的问题相关的一些次要影响。
您必须考虑的下一件事是阅读有关VMIN
和VTIME
元素的文档。将两者都设置为0
会使驱动程序成为非阻塞设备,因此您将在循环中尝试读取缓冲区中的任何内容。但在此之前,请三思而后行,你有两个线程竞争将字符放入缓冲区(你的进程,试图从缓冲区和驱动程序中断例程中获取它,试图将字符只是读取)而不休息。等待一个角色可用会更好(也可能是问题),将VMIN
设置为1
,将VTIME
设置为0
。这使得驱动程序在一个角色可用时立即唤醒您的进程,并且可能更接近您想要的角色。
经过所有这些猜测之后,您还没有发布任何可用于检查您所说内容的可重现代码,因此这是我们为您提供的最大帮助。