我使用以下命令为串口创建一对并尝试在它们之间发送二进制数据。
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上进行。
答案 0 :(得分:1)
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设备的类型,您可以配置刷新行为,以便在设备关闭时不会刷新数据,而是在收集完成之前它将耗尽收发器。
在实际应用程序中,您可以控制它,并且可以在关闭设备之前等待接收数据。
这种情况的快速解决方法是提高波特率,使数据离开设备足够快,以便在设备关闭时缓冲区中没有任何内容。