The correct initialization sequence for the Linux serial port

I wrote an application that should use serial ports on Linux, especially ttyUSB. The read and write operations are performed with the standard select () / read () and write () loops, and there is probably nothing wrong with them, but the initialization code (or the absence of any part) damages something in the tty subsystem. Here he is:

vuxboot(string filename, unsigned baud = B115200) : _debug(false) { _fd = open(filename.c_str(), O_RDWR | O_NOCTTY); if(_fd < 0) throw new io_error("cannot open port"); // Serial initialization was written with FTDI USB-to-serial converters // in mind. Anyway, who wants to use non-8n1 protocol? tcgetattr(_fd, &_termios); termios tio = {0}; tio.c_iflag = IGNPAR; tio.c_oflag = 0; tio.c_cflag = baud | CLOCAL | CREAD | CS8; tio.c_lflag = 0; tcflush(_fd, TCIFLUSH); tcsetattr(_fd, TCSANOW, &tio); } 

Another tcsetattr(_fd, TCSANOW, &_termios) is in the destructor, but that doesn't matter.

With or without termios initialization, strange things happen in the system after the application exits. Sometimes a regular cat (or hd ) immediately prints nothing or the same material every time, sometimes it waits and does not display any data that is necessarily sent to the port; and close() ( read() too, but not every time) emits a weird WARNING in dmesg referencing usb-serial.c .

I checked the hardware and firmware dozens of times (even on different machines), and I'm sure it works as intended; Also, I uninstalled the firmware just to print the same message again and again.

How can I use a serial port without destroying anything? Thanks.

+6
c linux tty serial-port
source share
5 answers

Good. This may not be the perfect solution ... it is definitely not. I just threw away the FT232 converter (actually fried it) and used CP2102. Now it works (and also 6 times cheaper).

0
source share

Pressing the WARN_ON line may indicate that you are in a kernel error. I know that lately a lot of work has been done to improve the USB-series driver; I suggest trying a new kernel and / or request a mailing list linux-usb@vger.kernel.org.

+2
source share

I'm not sure what is wrong with your code snippet, but it can come in handy if you have not seen it: Sequential Programming Guide for POSIX Operating Systems

I had to bind the serial port interface a bit more recently, and this library worked fine, which may serve as another example.

+1
source share

As with the side note, checking for an error on open not entirely correct - the error conditions are signaled by a return value of -1. (0 is a perfectly valid fd, usually associated with stdin.)

0
source share

You might want to try:

  vuxboot(string filename, unsigned baud = B115200) : _debug(false) { _fd = open(filename.c_str(), O_RDWR | O_NOCTTY); if(_fd < 0) throw new io_error("cannot open port"); // Serial initialization was written with FTDI USB-to-serial converters // in mind. Anyway, who wants to use non-8n1 protocol? tcgetattr(_fd, &_termios); - termios tio; + termios tio; + memcpy(&tio, &_termios, sizeof(struct termios)); tio.c_iflag = IGNPAR; tio.c_oflag = 0; tio.c_cflag = baud | CLOCAL | CREAD | CS8; tio.c_lflag = 0; tcflush(_fd, TCIFLUSH); tcsetattr(_fd, TCSANOW, &tio); } 

This makes sure that any unexpected termios fields on your system get somewhat reasonable values.

0
source share

All Articles