读取串行端口异步增强 [英] Reading a Serial Port Asynchronously Boost
问题描述
void foo()
{
boost :: asio :: io_service io_svc;
boost :: asio :: serial_port ser_port(io_svc,/ dev / ttyS0);
boost :: asio :: deadline_timer timeout(io_svc);
unsigned char my_buffer [2];
bool data_available = false;
ser_port.async_read_some(boost :: asio :: buffer(my_buffer),
boost :: bind(& read_callback,boost :: ref(data_available),
boost: :ref(timeout),boost :: asio :: placeholder :: error(),
boost :: asio :: placeholder :: bytes_transferred()));
timeout.expires_from_now(boost :: posix_time :: seconds(30));
timeout.async_wait(boost :: bind(& wait_callback,boost :: ref(ser_port),boost :: asio :: placeholders :: error()));
io_svc.run();
io_svc。
if(!data_available)
{
ser_port.close();
cout<<< ser_port被关闭了;
}
}
void read_callback(bool& data_available,boost :: asio :: deadline_timer& timeout,const boost :: system :: error_code& error, std :: size_t bytes_transferred)
{
if(error ||!bytes_transferred)
{
//没有数据被读取!
data_available = false;
return;
}
timeout.cancel();
data_available = true;
}
void wait_callback(boost :: asio :: serial_port& ser_port,const boost :: system :: error_code& error)
{
if(error)
{
//数据被读取,此超时被取消
return;
}
ser_port.cancel();
}
在 read_callback
你取消你的计时器,不要开始新的读取。
那么你期望ASIO做什么。你刚刚取消了所有的处理程序,就像文档一样,运行方法会在没有处理程序的时候返回。
所以如果你想拥有更多的数据而不仅仅是一个字节你收到你可以做两件事情:
首先只是发出另一个调用asio来从端口中读取更多的信息。
void read_callback(bool& data_available,boost :: asio :: deadline_timer& timeout,const boost :: system :: error_code& error,std :: size_t bytes_transferred)
{
if(error | |!bytes_transferred)
{
//没有数据被读取!
data_available = false;
return;
}
//使用刚刚读取的数据执行某些操作
ser_port.async_read_some(boost :: asio :: buffer(my_buffer),
boost :: bind(& read_callback ,boost :: ref(data_available),
boost :: ref(timeout),boost :: asio :: placeholder :: error(),
boost :: asio :: placeholders :: bytes_transferred() ));
//重启你的计时器
data_available = true;
}
或者您可以添加使用 transfer_at_least
至少获得所需的数据量。
I am trying to read several bytes asynchronously from a serial port. Currently the code I am using (source is How do I perform a nonblocking read using asio?), only allows me to read 1 byte and then it exits. How do I get it so that the code keeps reading until there is no more incoming data in the serial port? Thanks :)
void foo()
{
boost::asio::io_service io_svc;
boost::asio::serial_port ser_port(io_svc, "/dev/ttyS0");
boost::asio::deadline_timer timeout(io_svc);
unsigned char my_buffer[2];
bool data_available = false;
ser_port.async_read_some(boost::asio::buffer(my_buffer),
boost::bind(&read_callback, boost::ref(data_available),
boost::ref(timeout),boost::asio::placeholders::error(),
boost::asio::placeholders::bytes_transferred()));
timeout.expires_from_now(boost::posix_time::seconds(30));
timeout.async_wait(boost::bind(&wait_callback, boost::ref(ser_port),boost::asio::placeholders::error()));
io_svc.run();
io_svc.
if(!data_available)
{
ser_port.close();
cout << "ser_port was closed";
}
}
void read_callback(bool& data_available, boost::asio::deadline_timer& timeout, const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (error || !bytes_transferred)
{
// No data was read!
data_available = false;
return;
}
timeout.cancel();
data_available = true;
}
void wait_callback(boost::asio::serial_port& ser_port, const boost::system::error_code& error)
{
if (error)
{
// Data was read and this timeout was cancelled
return;
}
ser_port.cancel();
}
In your read_callback
you cancel your timer and do not start a new read.
So what do you expect ASIO to do. You just canceled all handlers and like the documentation states, the run method will return when no handlers are left.
So if you want to have more data than just the one byte you receive you can do two things:
First just issue another call to asio to read more from the port.
void read_callback(bool& data_available, boost::asio::deadline_timer& timeout, const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (error || !bytes_transferred)
{
// No data was read!
data_available = false;
return;
}
// do something with the data you just read
ser_port.async_read_some(boost::asio::buffer(my_buffer),
boost::bind(&read_callback, boost::ref(data_available),
boost::ref(timeout),boost::asio::placeholders::error(),
boost::asio::placeholders::bytes_transferred()));
//restart your timer
data_available = true;
}
or you can add use transfer_at_least
to get at least the amount of data you need.
这篇关于读取串行端口异步增强的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!