2011-11-10 51 views
4

我有一个系统,在那里我看到奇怪的串行端口行为,我不期望。我以前曾经在usb-to-serial适配器上看到过这种情况,但现在我在本地串行端口上也可以看到它,频率更高。当打开设备时,Linux串口缓冲区不为空

系统设置为运行自动化测试,并首先执行一些任务,导致从串行设备输出大量数据,而我没有打开端口。该设备也将自行重置。只有tx/rx线路连接。没有流量控制。

完成这些任务后,测试件打开串口并立即失败,因为它会得到意外的响应。当我重现这一点时,我发现如果我在终端程序中打开串行端口,我会看到几千千字节的旧数据(似乎在端口关闭时发送)立即刷新。一旦我关闭了这个程序,我就可以按预期运行测试。

什么可能导致这种情况发生?当设备关闭时,Linux如何处理缓冲串行端口?如果我打开设备,发送输出,然后关闭它而不读取它,这是否会导致同样的问题?

回答

4

Linux终端驱动程序缓冲输入,即使它没有打开。这可能是一个有用的功能,特别是如果速度/奇偶校验等。适当设置。

要复制较小的操作系统的行为,只要它是开放的从端口读取所有未决的输入:

... 
int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC); 
if (fd < 0) 
     exit (1); 

set_blocking (fd, 0); // disable reads blocked when no input ready 

char buf [10000]; 
int n; 
do { 
     n = read (fd, buf, sizeof buf); 
} while (n > 0); 

set_blocking (fd, 1); // enable read blocking (if desired) 

... // now there is no pending input 



void set_blocking (int fd, int should_block) 
{ 
     struct termios tty; 
     memset (&tty, 0, sizeof tty); 
     if (tcgetattr (fd, &tty) != 0) 
     { 
       error ("error %d getting term settings set_blocking", errno); 
       return; 
     } 

     tty.c_cc[VMIN] = should_block ? 1 : 0; 
     tty.c_cc[VTIME] = should_block ? 5 : 0; // 0.5 seconds read timeout 

     if (tcsetattr (fd, TCSANOW, &tty) != 0) 
       error ("error setting term %sblocking", should_block ? "" : "no"); 
} 
+0

我在想,可能是这样。那么,为什么我只看到这种行为的一部分?我使用pyserial进行测试,并将包含的miniterm.py脚本作为交互式终端。这不仅仅是一个串口有问题。它似乎是交替的。所有串行端口在关闭时都会有数据传入,但只有一个端口在我打开它时会缓冲。也许波特率只能在那个波特率上正确设置? – djs

+0

@djs:端口速度是我想到的第一件事。也可能是'gpsd'或'logind'正在访问封闭的端口以寻找GPS设备或登录连接并推测性地改变端口速度。 – wallyk

+0

这些服务都没有运行。 stty在我检查之前报告了115200的所有端口,发现其中只有一个保留了缓冲区。这是用来检查波特率的正确工具吗? – djs