Question

Le code suivant fonctionne pour moi correctement sous Windows, mais Linux ne fonctionne pas. J'utilise le même PC, les deux systèmes d'exploitation sont installés comme indigène. Je n'utilise pas la machine virtuelle. J'ai besoin de travailler sur Linux. J'ai essayé différentes distributions Linux et ne travaille nulle part.

// 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!...";

Si vous envoyez 1 octet, l'appareil répond et envoie les données correctement.

Exemple:

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

// In onReadyRead:
serial.readAll(); // Works on Win / Linux

Si envoyé un périphérique de plus de 1 octet ne répond pas à la demande de Linux.

Exemple:

// 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

Cet événement n'est déclenché que dans Windows. Sous Linux, il ne fonctionne jamais, non reçu ni arrive en mauvais format et n'a jamais reconnu le périphérique distant.

Mes logiques Windows:

{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 

(Je remplace la réponse réelle du périphérique par les caractères "x")

Mon journal Linux:

{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)
Adaptateur série 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: Désolé pour mon anglais, essayez de faire de mon mieux avec Google Translator: (...

plus d'informations 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

Je reconstruit CH341.C et ajoutez:

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 dans le journal est indicateur:

#define CH341_BIT_CTS 0x01

Plus d'informations 2:

Dans le fil d'écriture / lecture J'espère que WakeAll, en cours d'exécution sur OneReadyRead. Si vous passez une seconde, faites un readall avant de vérifier si le tampon est vide. Exemple:

// 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();

plus d'informations 3:

Mon noyau est 3.12.6, mais j'ai mis à jour de GitHub ce fichier un reconstruction de ces pilotes:

https://github.com/torvalds/ Linux / Blob / Master / Pilotes / USB / Serial / CH341.C https://github.com/torvalds/linux /blob/master/drivers/susb/serial/usb-serial.c (COMMIT D9A38A8741FDFFABC32E6D0943B1CDCF22712BEC)

Était-ce utile?

La solution

Grâce aux développeurs de Linux, résolu mon problème, le pilote CH34X non mis en œuvre parité dans la mailliste est le patch de liaison pour ceux qui ont ce problème à l'avenir, et non s'ils s'appliquent au noyau officiel, pour la seule façonest reconstruit le pilote.

http://marc.info/?l=Linux-Serial& ;m=139749273432052 & W= 2

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top