读取串口异步升压 [英] Reading a Serial Port Asynchronously Boost
问题描述
我想从一个串口读取异步几个字节。目前,code我使用(来源怎么办我执行使用ASIO?),只允许我读1个字节,然后退出非阻塞读取。我如何得到它,以便在code一直读取直到没有在串口的更多传入的数据?感谢:)
无效美孚()
{
提高:: ASIO :: io_service对象io_svc;
提高:: ASIO :: serial_port ser_port(io_svc的/ dev / ttyS0来);
提高:: ASIO :: deadline_timer超时(io_svc);
unsigned char型my_buffer [2];
布尔data_available = FALSE; ser_port.async_read_some(提高:: ASIO ::缓冲液(my_buffer)
提高::绑定(安培; read_callback,升压:: REF(data_available)
的boost :: REF(超时),提高:: ASIO ::占位符::错误()
提高:: ASIO ::占位符:: bytes_transferred()));
timeout.expires_from_now(升压::了posix_time ::秒(30));
timeout.async_wait(提高::绑定(安培; wait_callback,升压:: REF(ser_port),提高:: ASIO ::占位符::错误())); io_svc.run(); io_svc。 如果(!data_available)
{
ser_port.close();
COUT<< ser_port已关闭;
}}无效read_callback(布尔&安培; data_available,提高:: ASIO :: deadline_timer&放大器;超时,常量的boost ::系统::错误_ code和;错误,的std ::为size_t bytes_transferred)
{
如果(错误||!bytes_transferred)
{
//没有数据被读取!
data_available = FALSE;
返回;
} timeout.cancel();
data_available = TRUE;
}无效wait_callback(升压:: ASIO :: serial_port&放大器; ser_port,常量的boost ::系统::错误_ code&安培;错误)
{
如果(错误)
{
//数据读取和超时被取消 返回;
} ser_port.cancel();
}
在你的 read_callback
您取消计时器,不启动新的读取。结果
所以,你能指望什么ASIO做。你只取消了所有的处理程序和喜欢的文档状态,run方法将不返回处理程序离开的时候。
所以,如果你想拥有的不仅仅是您收到,你可以做两件事情的一个字节更多的数据:结果
最初只是发出另一个呼叫ASIO从端口读更多。
无效read_callback(布尔&安培; data_available,提高:: ASIO :: deadline_timer&放大器;超时,常量的boost ::系统::错误_ code和;错误,的std ::为size_t bytes_transferred)
{
如果(错误||!bytes_transferred)
{
//没有数据被读取!
data_available = FALSE;
返回;
}
//做你刚才读数据的东西
ser_port.async_read_some(提高:: ASIO ::缓冲液(my_buffer)
提高::绑定(安培; read_callback,升压:: REF(data_available)
的boost :: REF(超时),提高:: ASIO ::占位符::错误()
提高:: ASIO ::占位符:: 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屋!