Search code examples
clinuxusbraspbianusbserial

Why does read not terminate for my USB device?


I have an USB-device connected with my RaspberryPi 3 B+ (Raspbian Buster Lite 2019-07-10). I also write an small program to read data from the USB Device. The device has an custom, CDC conform firmware, so the device is detected correctly by the OS and and tty is attached.

But when I call 'read' for the device, the syscall never terminates. The odd thing is, when I access the device with MiniCom, CuteCom or even H-Term, it works correct.

I already tried the answers from the following questions:

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 of them worked.

I also tried to flush the tty with tcflush and tcdrain.

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

I expect a result, 12 bytes long, but read just blocks. If I try the O_NONBLOCK/O_NDELAY option, read terminates with the EAGAIN error.

Of course I checked the result values from every syscall and library function, they all returned/terminated as expected. And as I mentioned above, when connected with a terminal program the device works how it should, so it can't be the firmware.

Also I traced with strace what minicom and cutecom did, but they also did nothing more than open, write and read and of course I tried everything with sudo, so the rights are not the problem.


Solution

  • I found the Answer myself: the ICANON bit in the termios struct, c_lflag field musst be cleared and the VMIN field in the c_cc array should be set to 1.

    Further explanations are found here:

    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

    (be carefull, some parts of this documentary are a little bit outdated, for example the CCTS_OFLOW Flag does not exist on Raspbian-Buster)