打开Linux串口设备时,串口缓冲区未清空。

4
我有一个系统,在串口上发现了一些我不希望看到的奇怪行为。我以前偶尔会在usb转串口适配器上看到这种情况,但现在我更频繁地在本机串口上看到了这种情况。
该系统被设置为运行自动化测试,并且将首先执行一些任务,导致大量数据从串行设备输出,而我没有打开端口。设备也将重置自己。只连接了tx/rx线路。没有流控制。
完成这些任务后,测试软件会打开串口并立即失败,因为它得到了意外的响应。当我重现这个问题时,我发现如果在终端程序中打开串口,我会立即看到几千字节的旧数据(似乎是在关闭端口时发送的)。一旦我关闭了这个程序,我就可以按预期运行测试。
这是什么原因造成的?Linux如何处理关闭设备时串口的缓冲区?如果我打开一个设备,让它输出内容,然后关闭而没有从中读取,这是否会导致同样的问题?
1个回答

5

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
@djs:对我来说,端口速度是首先想到的事情。也可能是gpsdlogind正在访问关闭的端口寻找GPS设备或登录连接,并推测性地更改端口速度规格。 - wallyk
这两个服务都没有在运行。 stty 报告了所有端口的波特率为115200,但在我检查之前只有一个保留了缓冲区。这是检查波特率的正确工具吗? - djs
@djs:我一直使用的是stty -F /dev/ttyWhatever,从未遇到过问题。 - wallyk
@djs:你把事情顺利地搞定了吗? - wallyk
1
我仍然没有一个很好的解释,为什么我通常不会在串口上看到这种行为。我已经调整了测试框架,在开始时清除缓冲区,这解决了问题,但并没有解决我的好奇心... - djs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接