0

シリアル経由でコマンドを送信し、コマンドに基づいて応答を受信し、受信したメッセージに基づいて何かを実行する必要があります。これは非同期操作であるため、コールバックを使用する必要があると言われました。

2つのスレッドがあります。1つはメッセージを送信でき、もう1つはメッセージを受信します。

例:

//Thread 1
sendMessage("Initialize");

//Thread 2 
while(1)
{
    checkForMessages();
}

特定のメッセージに対して初期化され、受信したメッセージを処理する関数を作成するにはどうすればよいですか。

例:

CommHandle(Command,MsgReceived)
{
  if(command)
  {
    if(MsgReceived == ok)
    ...
    if(MsgReceived == error)
    ...
  }

}

4

1 に答える 1

1

これは非同期操作であるため、コールバックを使用する必要があると言われました。

必ずしも。Windows には「非同期 I/O」と呼ばれるものがあります。これは Windows の内部用語と見なされ、「オーバーラップ I/O」と同義です (説明はこちら)。オーバーラップ I/O を使用している場合、送信が終了するとコールバックが返されます。これは CPU の負荷を軽減するので便利ですが、プログラムが待機中に行うべきことが何もない場合は、実際には必要ありません。したがって、アプリケーションの性質によって異なります。

しかし、アプリケーションの性質に関係なく、メインの GUI スレッドが厄介な方法でフリーズしないように、スレッドを介してすべてのシリアル通信を処理する必要があります。

ただし、1 つの rx スレッドと 1 つの tx スレッドがあると、ジレンマが発生します。それらは同じポート ハンドルを使用しており、スレッドセーフではないため、自由にアクセスできません。解決策は、すべての送信を処理する 1 つのスーパー スレッドを作成するか、ミューテックスを介してポート ハンドルを保護することです。

どの方法が最適かはわかりません。推奨はありません。私自身は「スーパースレッド」のみを使用しました。明らかな利点の 1 つは、「スレッドを殺す」、「ポートが開いている」、「ポートが閉じている」などの WaitFor 命令を 1 か所に集中できることです。しかし同時に、コードはかなり複雑であることが判明しました。

特定のメッセージ用に初期化され、受信したメッセージを処理する関数を作成するにはどうすればよいですか。

スレッドが受信したデータをいくつかのバッファにシャベルします。tx バッファーと rx バッファー。シリアル プロトコルとパフォーマンスによっては、ダブル バッファーを使用する必要がある場合があります。1 つは現在の送信に使用され、もう 1 つは最近受信したデータを含みます。

次に、メインから、バッファからデータを取得します。それらはスレッドセーフである必要があります。そこまで到達したら、任意の形式のデータで行うようにパーサーを作成し、そこからアクションを実行するだけです

于 2012-10-23T09:56:54.523 に答える