8

を使用して、シリアルポートで受信データパッケージを確認したいと思いますboost.asio。各データパケットは、1バイト長のヘッダーで始まり、送信されたメッセージのタイプを指定します。異なるタイプのメッセージにはそれぞれ独自の長さがあります。私が書きたい関数は、新しい着信メッセージを継続的にリッスンする必要があり、メッセージが見つかったらそれを読み取り、他の関数を呼び出して解析する必要があります。私の現在のコードは次のとおりです。

void check_for_incoming_messages()
{
    boost::asio::streambuf response;
    boost::system::error_code error;
    std::string s1, s2;
    if (boost::asio::read(port, response, boost::asio::transfer_at_least(0), error)) {
        s1 = streambuf_to_string(response);
        int msg_code = s1[0];
        if (msg_code < 0 || msg_code >= NUM_MESSAGES) {
            // Handle error, invalid message header
        }
        if (boost::asio::read(port, response, boost::asio::transfer_at_least(message_lengths[msg_code]-s1.length()), error)) {
            s2 = streambuf_to_string(response);
            // Handle the content of s1 and s2
        }
        else if (error != boost::asio::error::eof) {
            throw boost::system::system_error(error);
        }
    }
    else if (error != boost::asio::error::eof) {
        throw boost::system::system_error(error);
    }
}

boost::asio::streambuf使用するのに適切なツールですか?そして、メッセージを解析できるように、そこからデータを抽出するにはどうすればよいですか?また、この関数を呼び出すだけの別のスレッドが必要かどうかを知りたいので、より頻繁に呼び出されます。トラフィックが多く、シリアルポートのバッファが不足しているために、関数への2つの呼び出しの間にデータが失われることを心配する必要がありますか?私はGUIにQtのライブラリを使用していますが、すべてのイベントを処理するのにどれくらいの時間がかかるのか本当にわかりません。

編集:興味深い質問は、シリアルポートに着信データがあるかどうかを確認するにはどうすればよいですか?着信データがない場合、関数をブロックしたくありません...

4

2 に答える 2

24

この記事は、ASIOをシリアルポートと非同期で使用する方法を理解するのに役立ちます。

更新(2019-03)

私がリンクしていた元の記事はもう利用できず、インターネットアーカイブでも見つけるのは困難です。(ここにスナップショットがあります。)シリアルI/OにASIOを使用することに関する新しい記事が検索で簡単に見つかりましたが、この古い記事はまだ非常に役立ちます。迷子にならないように、私はそれを公開の要点に入れています:

この記事で説明されているコードは、次の場所にコピーされているようです。

作者はC++11用に更新したようです。この記事はもともとfede.tftによって書かれたと思います。

于 2010-06-06T21:50:40.807 に答える
3

ジェイソン、

アプリケーションに適している場合は、コールバックベースの非同期シリアルRXを実装することを強くお勧めします。asioを使用してノンブロッキング読み取りを実行するにはどうすればよいですか?タイムアウト付きの非同期シリアルを実装する方法の素晴らしい小さな例があります。ご存知のように、パフォーマンスの利点を得るにはマルチスレッドの実装が必要になるため、大量のコピーを行わないように、受信したデータがバッファリングされる場所を検討する必要があります。

boost::streambuff個人的には、メモリをchar配列としてブロックし 、ターゲットバッファをに渡すためにchar m_RXBuffer[m_RXBuffSize]使用することを好みます。特にRS232の場合、基礎となるデータがバイトストリームであるという事実は、より複雑なデータ構造よりも単純なchar配列に自然にマッピングされることがわかりました。boost::asio::buffer(m_RXBuffer, m_RXBuffSize)async_read_some

幸運を!

于 2012-03-12T05:57:40.640 に答える