驱动程序CH341 USB适配器串行端口或QSerialPort不适用于Linux

以下代码在Windows中正确工作,但Linux不起作用。 我使用的是同一台PC,两种操作系统都是本机安装的。 我不使用虚拟机。 我需要在Linux上工作。 我已经尝试在不同的Linux发行版,并不能在任何地方工作。

// In the main class: QSerialPortInfo info = XXXX; // Generally in Linux: /dev/ttyUSB0, in win: COM1 QSerialPort serial; QObject::connect(&serial, SIGNAL(readyRead()), this, SLOT(onReadyRead()), Qt::DirectConnection); QObject::connect(&serial, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)), Qt::DirectConnection); QObject::connect(&serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onError(QSerialPort::SerialPortError)), Qt::DirectConnection); // Slot void MyClass::onReadyRead() { qDebug()<<"Signal onReadyRead"; buffer_mutex.lock(); buffer += serial.readAll(); qDebug()<<"Read: "<<qstr_to_hexstr(buffer); bufferNotEmpty.wakeAll(); buffer_mutex.unlock(); } void MyClass::onError(QSerialPort::SerialPortError error) { qCritical()<<"Serial Port Error: "<<(int)error; } void MyClass::onBytesWritten(qint64 size){ qDebug()<<"onBytesWritten: "<<size; } // In another place I did: serial.setPort(info); if(!serial.open(QIODevice::ReadWrite)) return false; qDebug()<<"Init Setting!..."; if(!serial.setBaudRate(QSerialPort::Baud9600)) qCritical()<<"Error in setBaudRate"; if(!serial.setDataBits(QSerialPort::Data8)) qCritical()<<"Error in setDataBits"; if(!serial.setParity(QSerialPort::EvenParity)) qCritical()<<"Error in setParity"; if(!serial.setStopBits(QSerialPort::OneStop)) qCritical()<<"Error in setStopBits"; if(!serial.setFlowControl(QSerialPort::SoftwareControl)) qCritical()<<"Error in setFlowControl"; if(!serial.setDataTerminalReady(true)) qCritical()<<"Error in setDataTerminalReady"; qDebug()<<"Setting ready!..."; 

如果发送1个字节,则设备响应并正确发送数据。

例:

 // In the main class: const char enq[2] = {0x05, '\0'}; serial.write (enq); // In onReadyRead: serial.readAll(); // Works on Win / Linux 

如果发送超过1字节的设备不响应​​在linux的请求。

例:

 // In the main class: const char command[6] = {0x02, 'S', '1', 0x03, 'a', '\0'}; serial.write(command); // In onReadyRead serial.readAll(); // Works only in Win 

此事件仅在窗口中触发。 在Linux中,它永远不会工作,没有收到或以错误的格式到达,永远不会识别远程设备。

我在Windows中login:

 {Debug} Init Setting!... {Debug} Setting ready!... {Debug} Write: " 0x05 " {Debug} onBytesWritten: 1 {Debug} buffer wait!... {Debug} Signal onReadyRead {Debug} Read: " 0x02 `@ 0x03 #" {Debug} buffer size: 5 {Critical} Serial Port Error: 0 {Debug} Write: " 0x02 S1 0x03 a" {Debug} onBytesWritten: 5 {Debug} buffer wait!... {Debug} Signal onReadyRead {Debug} Read: " 0x02 S100 0x0A 00000000000000000 0x0A 00000479" {Debug} buffer size: 32 {Debug} buffer wait!... {Debug} Signal onReadyRead {Debug} Read: " 0x02 S100 0x0A 00000000000000000 0x0A 00000479 0x0A 00000 0x0A 00000330 0x0A 00000 0x0A 0061 0x0A 0000 0x0A " {Debug} buffer size: 64 {Debug} Signal onReadyRead {Debug} buffer wait!... {Debug} Read: " 0x02 S100 0x0A 00000000000000000 0x0A 00000479 0x0A 00000 0x0A 00000330 0x0A 00000 0x0A 0061 0x0A 0000 0x0A X-XXXXXXXX 0x0A XXXXXXXXX 0x0A 221715 0x0A 120414 0x0A 0x03 0x1B " {Debug} buffer size: 103 {Critical} Serial Port Error: 0 

(我用“X”字符replace设备的实际响应)

我在Linux上login:

 {Debug} Init Setting!... {Debug} Setting ready!... {Debug} Write: " 0x05 " {Debug} onBytesWritten: 1 {Debug} buffer wait!... {Debug} Signal onReadyRead {Debug} Read: " 0x02 `@ 0x03 #" {Debug} buffer size: 5 {Critical} Serial Port Error: 0 {Debug} Write: " 0x02 S1 0x03 a" {Debug} onBytesWritten: 5 {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} buffer wait!... {Debug} timeout!... (15 sec for timeout) 

USB串行适配器:CH340

 In Windows: USB\VID_1A86&PID_7523&REV_0254 In Linux: Apr 13 01:16:58 kali kernel: [47844.260136] usb 2-1: new full-speed USB device number 16 using uhci_hcd Apr 13 01:16:58 kali kernel: [47844.428098] usb 2-1: New USB device found, idVendor=1a86, idProduct=7523 Apr 13 01:16:58 kali kernel: [47844.428115] usb 2-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0 Apr 13 01:16:58 kali kernel: [47844.428126] usb 2-1: Product: USB2.0-Ser! Apr 13 01:16:58 kali kernel: [47844.431268] ch341 2-1:1.0: ch341-uart converter detected Apr 13 01:16:58 kali kernel: [47844.445398] usb 2-1: ch341-uart converter now attached to ttyUSB0 Apr 13 01:16:58 kali mtp-probe: checking bus 2, device 16: "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1" Apr 13 01:16:58 kali mtp-probe: bus: 2, device: 16 was not an MTP device 

PD:对不起,我的英语,尽力与谷歌翻译:(…

更多信息1:

 Apr 13 04:10:55 kali kernel: [ 4872.627980] tty ttyUSB0: serial_write - 1 byte(s) Apr 13 04:10:55 kali kernel: [ 4872.629763] tty ttyUSB0: serial_chars_in_buffer Apr 13 04:10:55 kali kernel: [ 4872.629778] tty ttyUSB0: serial_wait_until_sent Apr 13 04:10:55 kali kernel: [ 4872.638252] tty ttyUSB0: serial_chars_in_buffer Apr 13 04:10:55 kali kernel: [ 4872.638267] tty ttyUSB0: serial_write_room Apr 13 04:10:55 kali kernel: [ 4872.638278] tty ttyUSB0: serial_chars_in_buffer Apr 13 04:10:55 kali kernel: [ 4872.638287] tty ttyUSB0: serial_write_room Apr 13 04:10:55 kali kernel: [ 4872.639438] tty ttyUSB0: serial_chars_in_buffer Apr 13 04:10:55 kali kernel: [ 4872.639458] tty ttyUSB0: serial_write_room Apr 13 04:10:55 kali kernel: [ 4872.639475] tty ttyUSB0: serial_chars_in_buffer Apr 13 04:10:55 kali kernel: [ 4872.639488] tty ttyUSB0: serial_write_room Apr 13 04:10:56 kali kernel: [ 4873.641799] tty ttyUSB0: serial_ioctl - cmd 0x540b Apr 13 04:10:56 kali kernel: [ 4873.646884] tty ttyUSB0: serial_write - 5 byte(s) Apr 13 04:10:56 kali kernel: [ 4873.647152] ch341-uart ttyUSB0: ch341_update_line_status - multiple status change Apr 13 04:10:56 kali kernel: [ 4873.647176] ch341-uart ttyUSB0: ch341_update_line_status - delta=0x01 Apr 13 04:10:56 kali kernel: [ 4873.647384] tty ttyUSB0: serial_chars_in_buffer Apr 13 04:10:56 kali kernel: [ 4873.647401] tty ttyUSB0: serial_wait_until_sent Apr 13 04:10:56 kali kernel: [ 4873.649144] ch341-uart ttyUSB0: ch341_update_line_status - multiple status change Apr 13 04:10:56 kali kernel: [ 4873.649166] ch341-uart ttyUSB0: ch341_update_line_status - delta=0x01 Apr 13 04:10:56 kali kernel: [ 4873.692152] ch341-uart ttyUSB0: ch341_update_line_status - multiple status change Apr 13 04:10:56 kali kernel: [ 4873.692170] ch341-uart ttyUSB0: ch341_update_line_status - delta=0x01 Apr 13 04:10:56 kali kernel: [ 4873.694133] ch341-uart ttyUSB0: ch341_update_line_status - multiple status change Apr 13 04:10:56 kali kernel: [ 4873.694148] ch341-uart ttyUSB0: ch341_update_line_status - delta=0x01 

我重buildch341.c并添加:

 if (!delta) return; dev_info(&port->dev, "%s - delta=0x%02X\n", __func__, delta); // <---- New Line if (delta & CH341_BIT_CTS) port->icount.cts++; if (delta & CH341_BIT_DSR) port->icount.dsr++; if (delta & CH341_BIT_RI) port->icount.rng++; if (delta & CH341_BIT_DCD) { port->icount.dcd++; tty = tty_port_tty_get(&port->port); if (tty) { usb_serial_handle_dcd_change(port, tty, status & CH341_BIT_DCD); tty_kref_put(tty); } } 

日志中的delta = 0x01是标志:

 #define CH341_BIT_CTS 0x01 

更多信息2:

在写/读的线程我希望wakeAll,运行onReadyRead。 如果在检查缓冲区是否为空之前再次传递一个readAll。 例:

 // In the main class: QWaitCondition bufferNotEmpty; // In my function write/read: serial.write(data, size); buffer_mutex.lock(); while(time(NULL)-timeStart<timeoutWait && serial.isOpen()) { buffer += serial.readAll(); if(buffer.count()>0){ qDebug()<<"buffer size: "<<buffer.count(); //Interprete the buffer here... if(bufferComplete) break; } qDebug()<<"buffer wait!..."; bufferNotEmpty.wait(&buffer_mutex, 1000); } buffer.clear(); buffer_mutex.unlock(); 

更多信息3:

我的内核是3.12.6,但我从GitHub更新这个文件重build这个驱动程序:

https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c https://github.com/torvalds/linux/blob/master/drivers/usb/serial/usb-serial .c (提交d9a38a8741fdffabc32e6d0943b1cdcf22712bec)

Solutions Collecting From Web of "驱动程序CH341 USB适配器串行端口或QSerialPort不适用于Linux"

感谢Linux的开发者,解决了我的问题,没有在maillist中实现奇偶校验的CH34x驱动是PATCH,对于那些将来有这个问题的人来说,不是他们是否适用于官方的内核,现在唯一的办法就是重建驱动程序。

http://marc.info/?l=linux-serial&m=139749273432052&w=2