读取设备数据流时缺少流量控制数据 (0x13)

发布于 2024-12-14 13:17:09 字数 257 浏览 5 评论 0原文

我写了一个 Linux 应用程序来阅读和阅读通过模拟串行端口的 USB 端口将二进制数据写入远程设备。

当我从设备读取数据时,我有一个USB嗅探器显示这样的二进制数据流(0x01,0x0A......0x13),但是当我的程序读取字节时,0x13不在字节流中- 这是 XOFF 字符,但我没有使用 XON/XOFF 流量控制(我认为)。

尝试了 open read 和 write,以及二进制模式下的 fopen fread 和 fwrite,结果相同。有什么想法吗?

I have written a Linux app to read & write binary data to a remote device over a USB port that is emulating a serial port.

When I read data from the device, I have a USB sniffer that shows a binary data stream like this (0x01, 0x0A......0x13), but when my program reads the bytes, the 0x13 is not in the byte stream - this is the XOFF char, but I am not using XON/XOFF flow control (I think).

Tried both open read and write, as well as fopen fread and fwrite in binary mode, same result. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾城月光淡如水﹏ 2024-12-21 13:17:09

感谢您的任何回复,例如网站。结果 stty 显示:

# stty -F /dev/ttyUSB0

speed 115200 baud;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 0; time = 10;
-brkint -imaxbel
-opost
-isig -icanon -echo -echoe

尽管看起来流量控制已关闭,
解决方案是使用 cfmakeraw 设置来查看所有字符并且忽略任何内容。

cfmakeraw() 将终端设置为类似于旧版本 7 终端驱动程序的“原始”模式:可以逐个字符输入,禁用回显,并且禁用终端输入和输出字符的所有特殊处理。终端属性设置如下:

termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
            | INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

现在可以看到我的所有数据了:)

Thanks for any responses, like the website. Turns out stty showed:

# stty -F /dev/ttyUSB0

speed 115200 baud;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 0; time = 10;
-brkint -imaxbel
-opost
-isig -icanon -echo -echoe

Even though it looked like flow control was off,
The solution was to use cfmakeraw settings to see ALL characters and ignore nothing.

cfmakeraw() sets the terminal to something like the "raw" mode of the old Version 7 terminal driver: input is available character by character, echoing is disabled, and all special processing of terminal input and output characters is disabled. The terminal attributes are set as follows:

termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
            | INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

Can see all my data now :)

左岸枫 2024-12-21 13:17:09

也许最好完全避免通过串行端口发送控制字符,而是稍微修改 Linux 和远程设备上的应用程序以将它们编码/解码为两个字节。例如:

0x00 0x00 -> 0x00
0x00 0x01 -> 0x13 (escape XOFF)
0x00 0x02 -> 0x11 (escape XON) 

考虑到这 3 个字节出现在二进制流中的概率,我认为这不会降低总体吞吐量。

顺便说一下,XON/XOFF 是软件流控制和串行/终端驱动程序的基本功能。实际上这个函数在你的情况下也很有用——为了避免缓冲区溢出和丢失一些有价值的字节,你可以暂停(XOFF)或恢复(XON)传输。

Maybe it's better to avoid control characters being sent through serial port at all, and instead slightly modify app on Linux and remote device to encode/decode them into/from two bytes. For example:

0x00 0x00 -> 0x00
0x00 0x01 -> 0x13 (escape XOFF)
0x00 0x02 -> 0x11 (escape XON) 

Considering the probability of appearing of these 3 bytes in a binary stream this shouldn't decrease the overall throughput I think.

And by the way, XON/XOFF is a software flow control and basic function of serial/terminal drivers. Actually this function can be useful in your case too - to avoid buffers overflow and missing some valuable bytes you can pause (XOFF) or resume (XON) transmission.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文