为什么读取不终止我的 USB 设备?
Why does read not terminate for my USB device?
我有一个 USB 设备连接到我的 RaspberryPi 3 B+ (Raspbian Buster Lite 2019-07-10)。我还编写了一个小程序来从 USB 设备读取数据。该设备有一个自定义的、符合 CDC 标准的固件,因此 OS 可以正确检测到该设备,并且已连接 tty。
但是当我为设备调用 'read' 时,系统调用永远不会终止。奇怪的是,当我使用 MiniCom、CuteCom 甚至 H-Term 访问设备时,它都能正常工作。
我已经尝试过以下问题的答案:
Reading and writing to serial port in C on Linux
How to open, read, and write from serial port in C?
C program to read data from USB device connected to the system
None 他们成功了。
我还尝试用 tcflush 和 tcdrain 刷新 tty。
int dev = open("/dev/ttyACM0", O_RWDR | O_NOCTTY);
// I tried to adapt the device parameters with termios, see above
uint8_t req[] = {0x21, 0x42, 0x00, 0x12}; // the actual request
write(dev, req, 4);
uint8_t resp[12];
read(dev, resp, 8); // does not terminate
我希望得到一个 12 字节长的结果,但只读取块。如果我尝试 O_NONBLOCK/O_NDELAY 选项,读取会因 EAGAIN 错误而终止。
当然,我检查了每个系统调用和库函数的结果值,它们都returned/terminated符合预期。正如我上面提到的,当连接到终端程序时,设备会正常工作,所以它不可能是固件。
我还用 strace 跟踪了 minicom 和 cutecom 做了什么,但它们也只是打开、写入和读取,当然我用 sudo 尝试了一切,所以权限不是问题。
似乎设备从未接受过请求,因此它从未处理过并被阻止。因此,请求的编写方式可能存在问题。您是否尝试设置 port/interface 的速度?
我自己找到了答案:必须清除 termios 结构中的 ICANON 位,c_lflag 字段并且 c_cc 数组中的 VMIN 字段应设置为 1。
进一步的解释可以在这里找到:
https://www.gnu.org/software/libc/manual/html_node/Local-Modes.html#Local-Modes
https://www.gnu.org/software/libc/manual/html_node/Mode-Data-Types.html
(请注意,这部纪录片的某些部分有点过时,例如 CCTS_OFLOW Flag 在 Raspbian-Buster 上不存在)
我有一个 USB 设备连接到我的 RaspberryPi 3 B+ (Raspbian Buster Lite 2019-07-10)。我还编写了一个小程序来从 USB 设备读取数据。该设备有一个自定义的、符合 CDC 标准的固件,因此 OS 可以正确检测到该设备,并且已连接 tty。
但是当我为设备调用 'read' 时,系统调用永远不会终止。奇怪的是,当我使用 MiniCom、CuteCom 甚至 H-Term 访问设备时,它都能正常工作。
我已经尝试过以下问题的答案:
Reading and writing to serial port in C on Linux
How to open, read, and write from serial port in C?
C program to read data from USB device connected to the system
None 他们成功了。
我还尝试用 tcflush 和 tcdrain 刷新 tty。
int dev = open("/dev/ttyACM0", O_RWDR | O_NOCTTY);
// I tried to adapt the device parameters with termios, see above
uint8_t req[] = {0x21, 0x42, 0x00, 0x12}; // the actual request
write(dev, req, 4);
uint8_t resp[12];
read(dev, resp, 8); // does not terminate
我希望得到一个 12 字节长的结果,但只读取块。如果我尝试 O_NONBLOCK/O_NDELAY 选项,读取会因 EAGAIN 错误而终止。
当然,我检查了每个系统调用和库函数的结果值,它们都returned/terminated符合预期。正如我上面提到的,当连接到终端程序时,设备会正常工作,所以它不可能是固件。
我还用 strace 跟踪了 minicom 和 cutecom 做了什么,但它们也只是打开、写入和读取,当然我用 sudo 尝试了一切,所以权限不是问题。
似乎设备从未接受过请求,因此它从未处理过并被阻止。因此,请求的编写方式可能存在问题。您是否尝试设置 port/interface 的速度?
我自己找到了答案:必须清除 termios 结构中的 ICANON 位,c_lflag 字段并且 c_cc 数组中的 VMIN 字段应设置为 1。
进一步的解释可以在这里找到:
https://www.gnu.org/software/libc/manual/html_node/Local-Modes.html#Local-Modes https://www.gnu.org/software/libc/manual/html_node/Mode-Data-Types.html
(请注意,这部纪录片的某些部分有点过时,例如 CCTS_OFLOW Flag 在 Raspbian-Buster 上不存在)