如何防止 libserial 吃掉来自串行设备的 0x0A、0x0D 或 0x0F 等字符?
How do I prevent libserial to eat up characters like 0x0A, 0x0D, or 0x0F coming from my serial device?
当使用 libserial
's SerialStream
对象与 serial-over-USB 设备(用于获取道路交通警报的 GNS FM9 接收器)通信时,我发现并非所有字符都来自设备实际上正在被读取。这就是我总是得到的服务:
3F 00 56 08 37 3F
当使用与 RDS Surveyor app 相同的设备时(写在 Java 中并使用 com.fazecast.jSerialComm.SerialPort
),相同的响应如下所示:
3F 00 00 56 08 0A 37 0C 0D 3F
经过一些研究,我偶然发现了这个帖子:Wrong newline character over the serial port (CR instead of LF)。发帖者没有使用libserial
(而是一些现成的串口通讯app),但他的问题和我的一模一样
这是相关端口的系统端配置:
pi@autoradio:~ $ stty -a
speed 38400 baud; rows 40; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U;
eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0; -parenb -parodd -cmspar
cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr
-igncr icrnl ixon ixoff -iuclc -ixany -imaxbel iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret
-ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh
-xcase -tostop -echoprt echoctl echoke -flusho -extproc
系统是Raspbery Pi 3B,最新生产版本Raspbian运行。在系统端,设备看起来像这样:
pi@autoradio:~ $ ls -al /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Jun 7 17:11 /dev/ttyUSB0
现在,我的问题是:如何让我的 SerialStream 读取所有字符而不进行任何转换,就像它们来自端口一样?我真的不想在这种情况下使用 stty
,因为它的设置在移除和重新连接设备时可能会被覆盖。谢谢。
您需要确保端口处于 "raw" 模式。
快速浏览一下 libserial 文档,它似乎没有设置原始模式的参数。部分选项:
- 修改 libserial 以设置原始模式。
- 不要使用 libserial,使用其他东西。
- 更改操作系统的端口默认值。
libserial 的实现似乎很基础;你最好使用 Boost.asio.
这样的东西
好的,我 opened an issue 和 libserial
的维护者一起得到了 C++ std::iostream
(甚至 LibSerial::SerialStream
!)默认踢出空白字符的答案. CR, LF, FF 都是这样。
他们向我提出了这个解决方案:
SerialStream tmc_receiver_handler ("/dev/ttyUSB0", ios::in | ios::out);
char c = 0x00;
tmc_receiver_handler.SetBaudRate (SerialStreamBuf::BAUD_38400);
tmc_receiver_handler.SetCharSize (SerialStreamBuf::CHAR_SIZE_8);
tmc_receiver_handler.SetFlowControl (SerialStreamBuf::FLOW_CONTROL_NONE);
tmc_receiver_handler.SetParity (SerialStreamBuf::PARITY_NONE);
tmc_receiver_handler.SetNumOfStopBits (SerialPort::STOP_BITS_1);
tmc_receiver_handler >> noskipws >> c;
noskipws
关闭空格抑制。应用后,一切正常。
当使用 libserial
's SerialStream
对象与 serial-over-USB 设备(用于获取道路交通警报的 GNS FM9 接收器)通信时,我发现并非所有字符都来自设备实际上正在被读取。这就是我总是得到的服务:
3F 00 56 08 37 3F
当使用与 RDS Surveyor app 相同的设备时(写在 Java 中并使用 com.fazecast.jSerialComm.SerialPort
),相同的响应如下所示:
3F 00 00 56 08 0A 37 0C 0D 3F
经过一些研究,我偶然发现了这个帖子:Wrong newline character over the serial port (CR instead of LF)。发帖者没有使用libserial
(而是一些现成的串口通讯app),但他的问题和我的一模一样
这是相关端口的系统端配置:
pi@autoradio:~ $ stty -a
speed 38400 baud; rows 40; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U;
eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0; -parenb -parodd -cmspar
cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr
-igncr icrnl ixon ixoff -iuclc -ixany -imaxbel iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret
-ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh
-xcase -tostop -echoprt echoctl echoke -flusho -extproc
系统是Raspbery Pi 3B,最新生产版本Raspbian运行。在系统端,设备看起来像这样:
pi@autoradio:~ $ ls -al /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Jun 7 17:11 /dev/ttyUSB0
现在,我的问题是:如何让我的 SerialStream 读取所有字符而不进行任何转换,就像它们来自端口一样?我真的不想在这种情况下使用 stty
,因为它的设置在移除和重新连接设备时可能会被覆盖。谢谢。
您需要确保端口处于 "raw" 模式。
快速浏览一下 libserial 文档,它似乎没有设置原始模式的参数。部分选项:
- 修改 libserial 以设置原始模式。
- 不要使用 libserial,使用其他东西。
- 更改操作系统的端口默认值。
libserial 的实现似乎很基础;你最好使用 Boost.asio.
这样的东西好的,我 opened an issue 和 libserial
的维护者一起得到了 C++ std::iostream
(甚至 LibSerial::SerialStream
!)默认踢出空白字符的答案. CR, LF, FF 都是这样。
他们向我提出了这个解决方案:
SerialStream tmc_receiver_handler ("/dev/ttyUSB0", ios::in | ios::out);
char c = 0x00;
tmc_receiver_handler.SetBaudRate (SerialStreamBuf::BAUD_38400);
tmc_receiver_handler.SetCharSize (SerialStreamBuf::CHAR_SIZE_8);
tmc_receiver_handler.SetFlowControl (SerialStreamBuf::FLOW_CONTROL_NONE);
tmc_receiver_handler.SetParity (SerialStreamBuf::PARITY_NONE);
tmc_receiver_handler.SetNumOfStopBits (SerialPort::STOP_BITS_1);
tmc_receiver_handler >> noskipws >> c;
noskipws
关闭空格抑制。应用后,一切正常。