提高:: ASIO :: serial_port阅读重新连接装置后,
-
22-08-2019 - |
题
我与升压::从GPS设备(USB串行)ASIO :: serial_port类阅读的问题。从端口连接设备和读取从它工作得很好,但是当我断开并重新连接设备,read_some不读取任何字节。
由于升压不缝检测串行端口消失(IS_OPEN()返回true),我定期取消(),close()方法和开放(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;
}
,我。即如果CloseHandle()
由于某种原因失败(或挂起),内部把手值不beign分配给INVALID_HANDLE_VALUE
和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
需要在Windows 7中点击要特别小心
我有类似的问题和挺过来了通过重置boost::asio::io_service
的实例,io_service_.reset()
。结果
我可以异步读取数据,但它无法从第二次尝试做同样的事情。结果
事实上,这是读功能本身没有问题,注册异步读取失败,从而导致从boost::asio::io_service::run()
在第二次尝试立即返回。
我不知道这是同一个问题,因为原来的海报了,因为我使用的这些天新的Boost库。结果 反正这里是我的解决方案:
// 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.