Linux打开设备时串口缓冲区不为空

Posted

技术标签:

【中文标题】Linux打开设备时串口缓冲区不为空【英文标题】:Linux serial port buffer not empty when opening device 【发布时间】:2011-11-10 18:55:42 【问题描述】:

我有一个系统,在该系统中,我发现串行端口的异常行为是我没想到的。我以前在使用 USB 转串口适配器时偶尔会看到这种情况,但现在我在本机串口上也看到了这种情况,而且频率要高得多。

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

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

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

【问题讨论】:

【参考方案1】:

即使没有打开,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");

【讨论】:

我在想可能是这样。那么,为什么我只在部分时间看到这种行为?我正在使用 pyserial 进行测试,并将包含的 miniterm.py 脚本用作交互式终端。有问题的不仅仅是一个串行端口。似乎交替出现。所有串行端口在关闭时都会有数据传入,但只有一个端口会在我打开它时缓冲。也许波特率只是在那个上正确设置? @djs:端口速度是我首先想到的。也可能是gpsdlogind 正在访问封闭的端口以寻找 GPS 设备或登录连接,并推测性地更改端口速度。 这些服务都没有运行。 stty 在我检查之前报告了 115200 的所有端口,发现其中只有一个保留了缓冲区。这是检查波特率的正确工具吗? @djs: stty -F /dev/ttyWhatever 是我一直使用的,从来没有遇到过问题。 我仍然无法很好地解释为什么我通常不会在串行端口上看到这种行为。我已经调整了测试框架以在启动时清除缓冲区,这解决了问题,如果不是我的好奇心......

以上是关于Linux打开设备时串口缓冲区不为空的主要内容,如果未能解决你的问题,请参考以下文章

linux读串口一直返回最后一包数据

串口应用编程

为啥麦克风关闭时基频和幅度不为零?

串口使用和CSerial类

linux如何清空串口接收缓冲区和发送缓冲区数据

检查使用O_NONBLOCK打开的文件描述符是否准备就绪