这个问题已经回答了,见文末和评论。
为什么 libserial SerialStream 在打开流时会抛出“错误的文件描述符”?
这个问题已经在包括这里在内的不同论坛上多次提出。这些答案都不能解决我的问题。
运行下面的简单代码会使 iostream(SerialStream 的父级)抛出“错误文件描述符”。
我已经尽可能地隔离了这里提出的问题。设置是:
- WmWare 播放器 16 中的 Lubunto 20.04(最新)
- 代码在 Eclipse 中作为托管项目运行
- 链接库是串行的(libserial)
- 串口连接到一个 ftdi usb-to-serial dongle
- libserial 在 v 1.0.0.something
- GCC C++14
- 编译和链接没有错误和警告
- 调试和步进工作
#include <libserial/SerialPort.h>
#include <libserial/SerialStream.h>
#include <iostream>
using namespace std;
using namespace LibSerial;
int main() {
SerialPort aPort;
SerialStream aStream;
try {
aPort.Open("/dev/ttyUSB0");
aStream.Open("/dev/ttyUSB0"); // <-- This fails
} catch (exception& e) {
cout << e.what() << endl;
}
return 0;
}
制作输出
21:46:34 **** 构建配置调试项目测试 **** 制作
所有构建文件:../src/test.cpp 调用:GCC C++ 编译器 g++
-std=c++1y -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test.d" -MT"src/test.o" -o "src/test.o" "../src/test.cpp " 完成构建:../src /test.cpp 构建目标:测试调用:
GCC C++ 链接器 g++ -o "test" ./src/test.o -lserial完成
构建目标:测试 21:46:35 构建完成。0 个错误,0 个警告。
(耗时 108 毫秒)
运行它会从 e.what() 中产生“错误的文件描述符”,并由 aStream.Open("/dev/ttyUSB0"); 抛出。观察 aPort.Open("/dev/ttyUSB0"); 让它通过。
所以其他一些事实也是:
- 将 gtkterm 连接到“/dev/ttyUSB0”工作正常,物理输出已验证
- 测试设备名称和用户权限给出:
agda@agda-virtual:~$ dmesg | grep tty
[0.073253] printk: 控制台 [tty0] 启用 [0.755452] 00:05: ttyS0 在 I/O 0x3f8 (irq = 4, base_baud = 115200) 是 16550A [0.794338] tty tty4: 哈希匹配 [3.909769] usb 2 -2.1:FTDI USB 串行设备转换器现在连接到 ttyUSB0
agda@agda-virtual:~$ groups agda
agda : agda adm dialout cdrom sudo dip plugdev lpadmin sambashare
agda@agda-virtual:~$ ls -l /dev/ ttyUSB0
crw-rw---- 1 root dialout 188 , 0 Mar 24 18:56 /dev/ttyUSB0
我的结论是,串行加密狗已安装并作为“/dev/ttyUSB0”工作。权限正确,组正确。
调用树没有给我任何线索:
线程#1 [测试] 4978 [核心:2](暂停:信号:SIGABRT:Aborted)__GI_raise() at raise.c:50 0x7ffff7bc818b
__GI_abort() at abort.c:79 0x7ffff7ba7859
0x7ffff7e2d951
0x7ffff7e3947c at raise.c
::terminate() 0x7ffff7e394e7
__cxa_rethrow() at 0x7ffff7e397ed
0x7ffff7f7a28a
main() at test.cpp:19 0x5555555553f6
我在这里想念什么?
如果我无法在我的特定系统上解决这个问题,任何关于其他方式进行 USB 异步通信的建议都将受到赞赏。
答:正如codo在评论中所说,不可能两次打开同一个串行通道。我已经纠正了这个问题,现在它在实际代码中可以正常工作。这是由于阅读文档草率而导致的错误,而是从一个糟糕的示例中复制代码。
对于遇到相同问题的任何人:SerialPort 和 SerialStream 是使用 libserial 访问串行端口的两种替代方法。使用其中之一。