3

boost::asio::serial_port クラスで GPS デバイス (USB-Serial) からの読み取りに問題があります。デバイスの接続とそこからの読み取りは正常に機能しますが、デバイスを切断して再接続すると、read_some はポートからバイトを読み取りません。

ブーストはシリアルポートがなくなったことを検出できないため ( is_open() が true を返す)、データを取得できない場合は定期的にデバイスをキャンセル()、クローズ()、およびオープン( GPS_PORT )し、ポートオプションをリセットします。途中。しかし、これも役に立ちません。入力バッファーは空のままです。

私は何かを見逃していますか、何か間違っていますか、それとも asio のバグですか? ポートがなくなったことを検出する標準的な方法はありますか?

4

3 に答える 3

3

あなたの場合の正確な理由を言うのは難しいですが、実際にはRTS、シリアルポートの感度を無効にする必要があることがよくあります。

RTSRS-232反対側のデバイスがオンのときにオンになる、実際のインターフェイスのピンです。

serial_port::read_someWindows APIこのシグナルを参照する基になる関数を呼び出します。

実際のRS-323デバイスを持っていないため、この信号のドライバ エミュレーションに依存する必要がありますが、これには問題がある可能性があります (残念ながら、多くの場合そうです)。

serial_port::set_option(DCB)無効にするには、RTSControlset toで呼び出しRTS_CONTROL_DISABLEます。

close()ハンドルを 'ing しても問題が解決しない場合は、 に問題がある可能性がありますboost。のソースコードはclose()次のようになります。

  boost::system::error_code close(implementation_type& impl,
      boost::system::error_code& ec)
  {
    if (is_open(impl))
    {
      if (!::CloseHandle(impl.handle_))
      {
        DWORD last_error = ::GetLastError();
        ec = boost::system::error_code(last_error,
            boost::asio::error::get_system_category());
        return ec;
      }

      impl.handle_ = INVALID_HANDLE_VALUE;
      impl.safe_cancellation_thread_id_ = 0;
    }

    ec = boost::system::error_code();
    return ec;
  }

つまり、CloseHandle()何らかの理由で失敗した (またはハングした) 場合、内部ハンドル値は割り当てられずINVALID_HANDLE_VALUEis_open()常に が返されtrueます。

これを回避するには、'ing のis_open()直後に確認し、 が返された場合は、 のインスタンス全体を破棄し、再度作成します。close()trueboost::asio::serial_port

于 2009-02-12T12:49:24.603 に答える
1

通常、準備ができていないboost::system::system_error場合は、タイプの例外を受け取る必要があります。read_some代わりに使用してみてくださいread。エラーが返され、単に返されない可能性があります。非同期メソッドを試すこともできます。この場合、ハンドラーは、デバイスが切断されたときにエラー オブジェクトを取得する必要があります。

別の方法として、関数を使用してポートへのハンドルを取得し、native()その上で ClearCommError() を呼び出すこともできます。エラーを返す場合があります。

于 2009-02-12T12:53:04.737 に答える