使用 Boost Asio 从串口读取
我想使用 boost.asio
检查串行端口上的传入数据包.每个数据包都以一个字节长的标头开始,并指定已发送的消息类型.每种不同类型的消息都有自己的长度.我要编写的函数应该不断地监听新的传入消息,当它找到一个它应该读取它,并调用其他函数来解析它.我目前的代码如下:
I'm want to check for incoming data packages on the serial port, using boost.asio
. Each data packet will start with a header that is one byte long, and will specify what type of the message has been sent. Each different type of message has its own length. The function I want to write should listen for new incoming messages continually, and when it finds one it should read it, and call some other function to parse it. My current code is as follows:
void check_for_incoming_messages()
{
boost::asio::streambuf response;
boost::system::error_code error;
std::string s1, s2;
if (boost::asio::read(port, response, boost::asio::transfer_at_least(0), error)) {
s1 = streambuf_to_string(response);
int msg_code = s1[0];
if (msg_code < 0 || msg_code >= NUM_MESSAGES) {
// Handle error, invalid message header
}
if (boost::asio::read(port, response, boost::asio::transfer_at_least(message_lengths[msg_code]-s1.length()), error)) {
s2 = streambuf_to_string(response);
// Handle the content of s1 and s2
}
else if (error != boost::asio::error::eof) {
throw boost::system::system_error(error);
}
}
else if (error != boost::asio::error::eof) {
throw boost::system::system_error(error);
}
}
boost::asio::streambuf
是正确的工具吗?以及如何从中提取数据以便解析消息?我还想知道我是否需要一个单独的线程来只调用这个函数,以便更频繁地调用它.我是否应该担心由于高流量和串行端口缓冲区耗尽而在两次调用函数之间丢失数据?我正在使用 Qt 的 GUI 库,但我真的不知道处理所有事件需要多少时间.
Is boost::asio::streambuf
the right tool to use? And how do I extract the data from it so I can parse the message? I also want to know if I need to have a separate thread which only calls this function, so that it gets called more often. Should I be worried about losing data between two calls to the function because of high traffic and serial port's buffer running out? I'm using Qt's libraries for GUI and I don't really know how much time it takes to process all the events.
有趣的问题是:如何检查串口是否有任何传入数据?如果没有传入数据,我不希望函数阻塞...
The interesting question is: how can I check if there is any incoming data at the serial port? If there is no incoming data, I don't want the function to block...
推荐答案
这篇文章有助于理解ASIO如何与串口异步使用:
This article is helpful in understanding how ASIO can be used asynchronously with serial ports:
- https://gist.github.com/kaliatech/427d57cb1a8e9a8815894413be337cf9
更新(2019-03):
我链接到的原始文章不再可用,即使在 Internet 档案中也很难找到.(这里是 快照.).现在有较新的文章关于使用 ASIO 进行串行 I/O 很容易通过搜索找到,但是这篇较旧的文章仍然非常有用.我把它放在一个公共要点中,这样它就不会丢失:
The original article I had linked to is no longer available and is difficult to find even in Internet Archive. (Here is a snapshot.). There are now newer articles on using ASIO for serial I/O found easily by searching, but this older article is still very useful. I'm putting it in a public gist so that it doesn't get lost:
- https://gist.github.com/kaliatech/427d57cb1a8e9a8815894413be337cf9
文章中描述的代码似乎是复制到这里的:
- https://github.com/fedetft/serial-port
作者似乎已经为 C++11 更新了它.我相信这篇文章是最初由 fede.tft 编写.
相关文章