4

我试图将来自 RS232 的数据记录到带有 cat 的文件中:

cat /dev/ttyS0 > rs232.log

结果是我的文件中除了最后一行之外的所有内容。

通过打印到标准输出,我发现,只有当 cat 获得换行符('\n')时,它才会写入输出。我发现了同样的情况:

dd bs=1 if=/dev/ttyS0 of=rs232.log

阅读后如何在不等待 Perl 换行符的情况下立即打印文本?我开始思考,这是否可能是 Linux-Kernel 或 coreutils 包的缓冲问题。

根据 TJD 的评论,我用 C 编写了自己的程序,但仍然遇到同样的问题:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* args[])
{
    char buffer;
    FILE* serial;
    serial = fopen(args[1],"r");
    while(1)
    {
        buffer = fgetc(serial);
        printf("%c",buffer);
    }
}

根据我自己的 C 代码的结果,这似乎是与 Linux 内核相关的问题。

4

2 回答 2

6

您正在打开 TTY。当该 TTY 处于熟(又名规范)模式时,它会执行行处理(例如,退格从缓冲区中删除前一个字符)。您需要将 TTY 置于原始模式,以便在每个字节到达时获取每个字节,而不是等待行尾。

页面_man

规范和非规范模式

c_lflag 中的 ICANON 规范标志的设置决定了终端是在规范模式(ICANON 设置)还是非规范模式(ICANON 未设置)下运行。默认情况下,设置 ICANON。

在规范模式下:

  • 输入是逐行提供的。输入行分隔符(NL、EOL、EOL2;或在行首的 EOF)时,输入行可用。除了 EOF 的情况外,行分隔符包含在 read(2) 返回的缓冲区中。

  • 启用行编辑(ERASE、KILL;如果设置了 IEXTEN 标志:WERASE、REPRINT、LNEXT)。read(2) 最多返回一行输入;如果 read(2) 请求的字节数少于当前输入行中可用的字节数,则只读取请求的字节数,剩余的字符将可用于未来的 read(2)。

在非规范模式下,输入立即可用(用户无需键入行分隔符),并且行编辑被禁用。

最简单的方法就是调用cfmakeraw.

于 2012-10-03T15:28:53.250 回答
0

这行得通吗?

perl -e 'open(IN, "/dev/ttyS0") || die; while (sysread(IN, $c, 1)) { print "$c" }'

这确实有效:

$ echo -n ccc|perl -e 'while (sysread(STDIN, $c, 1)) { print "$c" } '
ccc$
于 2012-10-03T14:49:23.113 回答