0

Javaのシリアルポートからデータを読み取っているときに、奇妙な問題が発生します。

正常に動作しているスレッドでポーリング方式を介してシリアルポートからデータを読み取る必要がありますが、シリアルポートにデータを書き込んでACKを読み戻す必要があるという要件があります。シリアルポートへのデータの書き込みは成功しましたが、データを読み戻すことができません。ここでは、スレッドとメインスレッドの2つの読み取り操作があります。

シリアル書き込みデータを受信したら、フラグを使用してシリアルポートからデータを読み取っているスレッドを一時停止し、書き込みが完了するとシリアルポートからデータの読み取りを再開しましたが、データを読み取ることができません。書き込み操作後にシリアルポートの読み取りを無効にし、スレッドでシリアルポートを読み取るスレッドを有効にしました。ここでは、シリアルポートからのACKデータが表示されています。

このシリアル読み取り操作で何が問題になっているのかを示唆するものはありますか?バッファリングされた読み取り/書き込み操作ではありません。

4

2 に答える 2

0

シリアルポートから読み取ろうとする別のスレッドがあってはなりません。正しいアーキテクチャは、単一のスレッドに読み取りを実行させ、複数のキューを介して受信データを関心のあるクライアントに配布することです。

読み取りスレッドによってデータが与えられる「通常の読み取り処理」スレッドがあります。書き込み/確認シーケンスを実行する必要がある場合、書き込み/確認を実行するスレッドは一時的に自分自身を読み取りスレッドに登録し、データストリームを迂回させます。

データのインターリーブ(つまり、書き込み要求の後、ackが受信される前に受信される通常のデータ)に対処する必要がありますが、それはアプリケーション次第です。

于 2012-06-14T19:09:34.303 に答える
0

シリアルポートの読み取りにアクセスするには、専用のスレッドを1つだけ使用することを強くお勧めします。最も信頼性の高いソリューションは、受信したすべてのデータをスレッドセーフなステートマシンにシャベルで送る割り込みハンドラーでした。複数のスレッドからシリアルポートを読み取ろうとすると、問題が発生します。シリアルポートIOは、ユーザーが「スレッドを一時停止」したことを気にしません。データはすでにフェッチされており、コンテキストスイッチが原因で失われる可能性があります。

したがって、入ってくるものを読み続け、ACKが期待されて取得された場合は、セマフォを介してメインスレッドに通知してください。汚い残酷に単純化された擬似コードでは:

メインスレッドループ:

{
  serialReaderThread.isAckExpected = true
  sendWriteCommand();
  ackReceivedSemaphore.wait();
}

シリアルリーダースレッドループ:

{
  readData();
  if( isAckExpected && data == ack ) {
    mainThread.ackReceivedSemaphore.notify();
    isAckExpected = false
  }
}

書き込みコマンドを送信する前に設定する必要がありisAckExpectedます。シリアルピアが十分に高速である場合、返される前に応答が返される可能性があるためですsendWriteCommand

于 2012-06-14T19:20:44.093 に答える