3

我使用以下命令为串行端口创建一对并尝试通过它们发送二进制数据。

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

但是,即使我尝试发送后续二进制文件

数据.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 选项,我可以看到显示的数据正确,所以应该是接收端的问题。

PS 以上所有测试均在 Mac OS X 10.9.2 上进行

4

2 回答 2

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
于 2014-04-19T08:44:51.707 回答
0

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

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

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

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

于 2014-04-18T18:44:12.700 回答