我试图将数据从RS232记录到cat:
文件中cat /dev/ttyS0 > rs232.log
结果是除了最后一行之外,我的文件中包含了所有内容。
通过打印到stdout,我能够发现,只有在获得换行符('\ n')时,cat才会写入输出。我发现了同样的事情:
dd bs=1 if=/dev/ttyS0 of=rs232.log
在阅读How can I print text immediately without waiting for a newline in 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-Code结果,这似乎是与Linux内核相关的问题。
答案 0 :(得分:5)
你正在打开一个TTY。当该TTY处于熟(也称为规范)模式时,它执行行处理(例如,退格从缓冲区中删除前一个字符)。您需要将TTY置于原始模式,以便在到达时获取每个字节而不是等待行结束。
来自the man
page:
规范和非规范模式
c_lflag中ICANON canon标志的设置决定了是否 终端以规范模式(ICANON设置)或 非规范模式(ICANON未设置)。默认情况下,ICANON设置。
在规范模式中:
输入逐行可用。输入行可用 什么时候 行分隔符的类型(NL,EOL,EOL2;或EOF开头) 线)。除了EOF的情况,行分隔符包含在 read(2)返回的缓冲区。
启用行编辑(ERASE,KILL;如果IEXTEN标志为 集合:WERASE, REPRINT,LNEXT)。 read(2)最多返回一行输入;如果 read(2)请求的字节数少于当前行中可用的字节数 输入,然后只读取所请求的字节数,剩余的 字符将可供将来阅读(2)。
在非规范模式下,输入立即可用(没有 用户必须键入行分隔符字符)和行编辑 被禁用。
最简单的方法就是致电cfmakeraw
。
答案 1 :(得分: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$