ブ::asio::serial_port読後の再投入装置
-
22-08-2019 - |
質問
している問題のブ::asio::serial_portクラスからの読み出しのGPSデバイス(USB-シリアル).接続デバイスからの読み出しで動作してしまっているんですけど切り再投入する装置read_someなの読み込みバイトからのポートです。
向かないシーム検出のシリアルポートがなくなった(is_open()がtrueを返す)、定期的に解除()があり、()でオープン(GPS_PORT)のデバイスが得られませんデータのリセットポートオプションです。このはならないか、入力バッファのご滞在は空になります。
私を見落とさないよう、やろうという誤ったが、このプログラムにバグasio?ある標準的な方法を検出するポートは行ってしまったのでしょうか。
解決
これはあなたのケースでは正確な理由は何か言うのは難しいのですが、実際には、あなたが頻繁にあなたのシリアルポートにRTS
感度を無効にする必要があることを示しています。
RTS
は、他の側の装置がオンのときにある実際のRS-232
インターフェースのピンである。
serial_port::read_some
は、この信号に見えます基本的なWindows API
関数を呼び出します。
RS-323
デバイスを持っていないので、は、障害のある(残念ながら、多くの場合とである)であってもよい。この信号のドライバエミュレーションに依存する必要があります。
これを無効にするには、serial_port::set_option(DCB)
に設定RTSControl
で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;
}
、I。電子。 CloseHandle()
が何らかの理由で失敗した(またはハング)場合、内部のハンドル値がINVALID_HANDLE_VALUE
するために割り当てられbeignされていないとis_open()
は常にtrue
を返します。
は右is_open()
'ing後close()
を確認し、これを回避するには、それがtrue
を返す場合、boost::asio::serial_port
の全インスタンスを破棄して再作成します。
他のヒント
通常は、もはやときboost::system::system_error
が準備できないタイプread_some
の例外を取得する必要があります。多分それはエラーを返し、ちょうど戻らない、代わりにread
を使用してみてください。また、非同期メソッドを試みることができます。デバイスが切断されたときに、この場合にハンドラがエラーオブジェクトを取得する必要があります。
Alterantivelyあなたはnative()
機能を使用してポートへのハンドルを取得し、その上で()ClearCommErrorを呼び出すことができます。それがエラーを返す場合があります。
ものの取り扱いの容易さのasio boost::ip:tcp
, と思い取り扱いブ serial_port
必要と特別な注意Windows7です。
私は同様の問題 た上でリセットのインスタンス boost::asio::io_service
, io_service_.reset()
.
できるデータを読み込むための非同期が失敗したいものについてです。
実際に、この読み機能そのものを登録す非同期読みに失敗したり、即座に返す boost::asio::io_service::run()
第二についてです。
私にはこの問題として独自のポスターをたので私が使ってい新しいブ図書館のこれらの日です。
とにかくここは私の解
// port open step
port_ = boost::shared_ptr<boost::asio::serial_port>
(new boost::asio::serial_port(io_service_));
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service_));
port_->async_read_some(....);
.......
// port close step
port_->cancel();
port_->close();
port_.reset();
io_service_.stop();
io_service_.reset(); // <-- IMPORTANT: this makes serial_port works in repeat use.