2017-06-05 24 views
0

私は、Qtのシリアルポートを通じて約2週間は通信するというプロジェクトに苦労しています。最初に信号/スロット方式を試しましたが、いくつかのデータが欠落していました。それでは、スレッドを使うことにしましたが、同じ結果が得られました。ウィンドウのバーにマウスの左ボタンを置いても、アプリケーションのウィンドウがサイズ変更または最大化/最小化されている間に、データが欠落していました。この状態を助けてください。QSerialPort with thread

メインウィンドウコンストラクタ:

void SerialPort::newData() 
{ 
    mutex.lock(); 
    bArray.insert(bArray.length(),serial->readAll()); 
    mutex.unlock(); 

    emit getData(&bArray,&mutex); 
} 

SERIALPORTコンストラクタ:

SerialPort *serial= new SerialPort(); 
serial->moveToThread(&cThread); 

connect(this , &MainWindow::finished, &cThread, &QThread::quit); 
connect(this , &MainWindow::destroyed, this, &SerialPort::deleteLater); 
connect(serial, &SerialPort::getData, this, &MainWindow::displayData); 

cThread.start(); 

シリアルポートは、スレッドを読ん

serial = new QSerialPort(); 
connect(serial, &QSerialPort::readyRead, this, &SerialPort::newData); 

bArray.clear(); 

fill_serial_ports(); 
portName = find_stm32_port(); 

serial->setReadBufferSize(20*1024*1024); // it's a huge buffer. 
bArray.reserve(20*1024*1024); // it's a huge buffer. 

open_serial_port(); 

はまた、私はこれがどのようなバグでできることを考えましたいくつかのデータが失われ、バグトラッカーに書き込まれました。譲受人は、QSerialPortはデータを失うことはなく、私のコードは間違っていると言いました。私は非常に混乱している、私は間違いをどこにするか分からない。どうぞ、私の他の解決策をチェックできますか?間違いはどこですか?

私のバグトラッカーレポート(受け入れられない):https://bugreports.qt.io/browse/QTBUG-61233

+2

いくつかのコード例を参考にしてください。 –

+1

トピックをオフにしていますが...もしあなたのシングルスレッドコードがポートからデータを失っていたら、そのコードを別のスレッドに移動させるだけで*本当の*問題をデバッグするのが難しくなると感じるのを助けることはできません。 –

+0

シリアルポートから巨大なデータを受信する場合は、いくつかのreadyRead信号から受信したデータを蓄積する必要があります。 – Jeka

答えて

1

この問題は、Denis Shienkovによってqtbugreportsで解決されました。qsp-no-freeze-workarounを見ることができますd-windows.zipスレッド付きシリアルポートの例。

リンク:https://bugreports.qt.io/browse/QTBUG-61233

0

があまりにもcThreadをスレッドにあなたの内側のQSerialPortオブジェクトserialを移動しよう:内部フィールド上記のコードで

SerialPort *serial = new SerialPort(); 
serial->moveToThread(&cThread); 
serial->serial.moveToThread(&cThread); // move you inner QSerialPort to cThread 

serial->serial.moveToTheThread(...)は魔法を行います。アプリケーションのウィンドウのサイズが変更または最小化/最大化されている間は、でも、ウィンドウのバー上でマウスの左ボタンを押したまま

+0

これを試してみます、これはバグかもしれないと思ってバグトラッカーに書きました。譲受人は、QSerialPortはデータを失うことはなく、私のコードは間違っていると言いました。私は非常に混乱している、私は間違いをどこにするか分からない。どうぞ、私の他の解決策をチェックできますか?間違いはどこですか?私はちょうど私のメインポストへのリンクを追加しました。 –

+0

あなたのコードの問題は以下の通りです: 1. 'SerialPort'が' QThread'から継承されているのはなぜですか? 'SerialPort'クラスの中に3つの責任を混在させました:(a)スレッド化、(b)同期化、(c)シリアルポートラッパー。これは、予測不可能で本当に奇妙なバグにつながる可能性があります。継承の代わりに集約を使用します。 2. 'SerialPort'から' convertData'を継承する理由は何ですか?これは実際の問題の原因となります。代わりに 'Chain of Responsibility'デザインパターンを使用してください。 3. 'serial-> moveToThread(* this)'行を 'SerialPort :: SerialPort()'に追加します。 4.コードをリファクタリングしてもう一度やり直してください。 – dekin

+0

私は今、例ではターミナルプログラムを試してみましたが、MCUを起動するには数行のコードを追加しました。それはあまりにもデータを逃した。USB_Canコンバータの赤いLEDが点灯している場合は、転送が行方不明であることを意味する。しかし、Herculesはシリアルポートのターミナルプログラムを使用していますが、欠落したデータはありません。 これは下のビデオで見ることができます。 リンク:https://drive.google.com/file/d/0B7WvtYBLRY0YVFFmRzZvWWZKVFk/view –

0

は、それが仮想シリアルのペアでそれを開始し、私はthe code you provided to a bug trackerコンパイルし、いくつかのデータ

を逃しましたsocatで作成されたポート:

socat -d -d pty,raw,echo=0 pty,raw,echo=0 

とデータチャンクを送信エミュレート、第1バイトずつ、それらのサイズを大きく:

そして、私はそうで、アプリケーションウィンドウのサイズを変更し、それを移動し、最大化/最小化し、押しボタンとしようとした

"bytearray length:1" 
"bytearray length:2" 
"bytearray length:3" 
"bytearray length:4" 
"bytearray length:5" 
"bytearray length:6" 
"bytearray length:7" 
... 

#!/bin/bash 
for i in {1..1000} 
do 
    dd if=/dev/urandom of=/dev/pts/25 bs=1 count=$i 
    sleep 1 
done 

アプリケーションのログは次のように見えました。これは効果がありません。実際、かなり長いテストセッション中にデータが失われたことはありません(Ubuntu 16.04 x64)。したがって、データがまだ緩んでいる場合は、仮想COMポートに「STMicroelectronics Virtual COM Port」の説明が記載されている可能性があります。

+0

ありがとう、あなたの説明はありますが、あなたのテストは私のアプリケーションよりかなり遅いです。私のアプリケーションのボーレートは1Mbitです(CANbusのため)。 –

+0

申し訳ありませんが、データはどこに失われていると思いますか? convertDataスレッドで発生しますか? – dekin

+0

USBCanデバイスがデータを送信できないというエラーが発生しているため、エラーLEDが点灯しています。 –

0

それはthe commentで明らかにされていますとおり、問題はUSBCanデバイスがデータを送信することはできませんというエラーを与えているので、そのエラーが主導になってきて

ということです。右QSerialPortインスタンスserialを作成した後に次の行を追加

試してみてください。

serial->setFlowControl(QSerialPort::HardwareControl); 

お使いのデバイスがRFC232標準をサポートしている場合、これはRTSを有効にする必要があります(/ CTS(クリア送信するために)ラインと原因の送信要求