Serial port 通过socat创建的虚拟串行端口对传输二进制数据时缺少0xF和0x16

Serial port 通过socat创建的虚拟串行端口对传输二进制数据时缺少0xF和0x16,serial-port,socat,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个字节的文

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

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)

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

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

有人知道是什么导致缺少0x16和0xF吗? 如何传输包含0x16和0xF的二进制数据

其他测试用例:

测试用例1

发送:

收到:

0x16 0x0 0x0 0x0 0x0 0x16
0xf 0x0 0x0 0x0 0x0
测试用例2

发送:

收到:

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


另外,上述所有测试都是在Mac OS X 10.9.2上进行的,这里的问题很可能与设备刷新缓冲区的方式有关。
cat
功能只需打开、写入字节,然后关闭设备,而无需等待数据完全耗尽

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

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


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

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

我不认为这是由刷新行为引起的,改变波特率也不能解决这个问题(至少我尝试过不同的波特率,从9600到115200)。因此,如果我发送了二进制数据“0x16 0x16 0x0 0x0 0x0 0x0 0x0 0x0 0x16 0x16 0x16”,我只能接收“0x16 0x0 0x0 0x0 0x0 0x0 0x16”。很明显,只有两个连续的0x16,结果是一个0x16,但我不确定是什么导致了这种行为。我建议为它编写一个实际的程序,这样您就可以控制发送/接收方法以及COM端口属性。如果你需要帮助,可能会有所帮助。我写了一个简单的串行问题来发送和接收二进制数据,并设置了所有我认为可能相关的termios选项,但结果是一样的。简单地说,我只需要使用cat命令就可以解决这个问题。我发现一个是分析USB数据传输的有用工具。最后我发现这个问题是由IEXTEN在termios的c_lflag中打开引起的,如果我在我的c程序中打开它,或者将-IEXTEN=0传递给socat,这个问题就消失了。这里可以找到具有相同原因的类似问题:termios.clflag中的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=staffI非常希望这能解决我的socat串行网桥吃掉uBlox控制序列(包含0x00字符)的问题,但是,唉,它们仍然在被吃掉。我正在使用:
socat/dev/ttyO0,raw,echo=0,b115200,iexten=0/dev/ttyO4,raw,echo=0,b57600,iexten=0
0xf 0x0 0x0 0x0 0x0
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