当二进制数据通过socat创建的虚拟串口对时,缺少0xF和0x16

时间:2014-04-18 14:13:58

标签: serial-port socat

我使用以下命令为串口创建一对并尝试在它们之间发送二进制数据。

sudo socat -d -d pty,link=/dev/tty.vcp0,raw,echo=0,user=myusername,group=staff pty,link=/dev/tty.vcp1,raw,echo=0,user=myusername,group=staff

但是,即使我尝试发送以下二进制文件

data.bin

0x16 0x16 0x16 0x16 0x16 0x16

(基本上只是一个6字节的文件,每个字节的值为0x16)

通过

cat /dev/tty.vcp0 > recv.bin

cat data.bin > /dev/tty.vcp1

我得到的只是3字节的0x16而不是6。

类似的事情发生在字节0xF上。如果我发送一个包含6个字节0xF的二进制文件,我就无法收到任何单个字节。

任何人都知道造成缺失的0x16和0xF的原因是什么? 如何传输包含0x16和0xF的二进制数据?

其他测试用例:

测试案例1

发送:

0x16 0x16 0x16 0x0 0x0 0x0 0x0 0x16 0x16 0x16

收到:

0x16 0x0 0x0 0x0 0x0 0x16

测试案例2

发送:

0xf 0xf 0xf 0x0 0x0 0x0 0x0 0xf 0xf 0xf

收到:

0xf 0x0 0x0 0x0 0x0

我在socat命令中添加了-x选项,我可以看到显示正确的数据,因此它应该是接收方的问题。

P.S。所有上述测试均在Mac OS X 10.9.2上进行。

2 个答案:

答案 0 :(得分:1)

termios.c_lflag中的

IEXTEN标志导致了这个问题。

当IEXTEN打开时,VDISCARD = SI(0xF)和VLNEXT = SYN(0x16)将不会传递到termios手册页中提到的输入。

解决此问题的最简单方法是将iexten = 0传递给socat命令,例如:

sudo socat -d -d pty,link=/dev/tty.vcp0,raw,echo=0,iexten=0,user=myusername,group=staff pty,link=/dev/tty.vcp1,raw,echo=0,iexten=0,user=myusername,group=staff

答案 1 :(得分:0)

这里的问题很可能与设备刷新缓冲区的方式有关。只需打开cat函数,写入字节,然后关闭设备,而不必等待数据完全耗尽。

根据您使用的VCP设备的类型,您可以配置刷新行为,以便在设备关闭时不会刷新数据,而是在收集完成之前它将耗尽收发器。

在实际应用程序中,您可以控制它,并且可以在关闭设备之前等待接收数据。

这种情况的快速解决方法是提高波特率,使数据离开设备足够快,以便在设备关闭时缓冲区中没有任何内容。