正确的初始化序列为Linux串行端口

我写了一个必须在Linux上使用串口的应用程序,尤其是ttyUSB。 读和写操作是用标准的select()/ read()循环和write()来完成的,它们可能没有错,但是初始化代码(或者某些部分的缺失)会损害tty子系统中的某些东西。 这里是:

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); } 

另一个tcsetattr(_fd, TCSANOW, &_termios)位于析构函数中,但是不相关。

无论是否进行termios初始化, 应用程序退出后系统中都会发生奇怪的事情。 有时候,普通的cat (或者hd )会立即退出,而不是每次都打印一些或者相同的东西,有时候它们正在等待,而不是显示任何确实发送到端口上的数据。 和close()read()也是,但不是每次都会)发出一个奇怪的WARNING给dmesg, 指向usb-serial.c 。

我检查了硬件和固件几十次(即使在不同的机器上),我确信它是按照预期工作的。 此外,我剥离固件只是一遍又一遍地打印相同的消息。

我怎样才能使用串口而不破坏任何东西? 谢谢。

Solutions Collecting From Web of "正确的初始化序列为Linux串行端口"

打到WARN_ON可能意味着你遇到了内核错误。 我知道最近在改进USB串口驱动方面已经做了很多工作, 我建议尝试一个更新的内核,和/或询问linux-usb@vger.kernel.org邮件列表。

我不确定你的代码片段有什么问题,但是如果你还没有看到它,这可能会派上用场: POSIX操作系统的串行编程指南

我不得不在最近做一些串口接口, 这个库工作的很好,可以作为另一个例子。

就像旁注一样,你open的错误检查是不正确的 – 错误条件通过返回值-1来表示。 (0是一个完全有效的fd,通常连接到stdin。)

你可能想尝试:

  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); } 

这使得你的系统上任何意想不到的termios字段都会得到一些合理的值。

好的。 这可能不是一个完美的解决方案…它绝对不是。 我刚推出了FT232转换器(实际上炒了它),而且使用了基于CP2102的转换器。 它现在正常工作(也是便宜6倍)。