Linux serial port buffer is not empty when opening device

I have a system where I see strange behavior with serial ports that I do not expect. Previously, I saw this with usb-to-serial adapters, but now I see it on my native serial ports with a much higher frequency.

The system is configured to run automatic tests and will first perform some tasks that cause a large amount of data to be output from the serial device, while I do not have open ports. The device will also reset. Only tx / rx lines are connected. No flow control.

After completing these tasks, the test software opens the serial ports and immediately crashes because it receives unexpected responses. When I reproduced this, I found that if I open the serial port in the terminal program, I will see that a few kilobytes of old data (which, it seems, were sent when the port was closed), immediately disappeared. As soon as I close this program, I can run the tests as expected.

What can happen? How does Linux handle serial port buffering when the device is closed? If I opened the device, made it send the output, and then closed it without reading it, would that cause the same problem?

+4
source share
1 answer

The Linux terminal driver loads input, even if it is not open. This can be a useful feature, especially if speed / parity / etc. set accordingly.

To reproduce the behavior of smaller operating systems, read all pending input from a port as soon as it is open:

... int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) exit (1); set_blocking (fd, 0); // disable reads blocked when no input ready char buf [10000]; int n; do { n = read (fd, buf, sizeof buf); } while (n > 0); set_blocking (fd, 1); // enable read blocking (if desired) ... // now there is no pending input void set_blocking (int fd, int should_block) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { error ("error %d getting term settings set_blocking", errno); return; } tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = should_block ? 5 : 0; // 0.5 seconds read timeout if (tcsetattr (fd, TCSANOW, &tty) != 0) error ("error setting term %sblocking", should_block ? "" : "no"); } 
+4
source

Source: https://habr.com/ru/post/1380636/


All Articles