从串行端口使用 boost::asio::async_read_until 时截断数据(如果超过 512 字节)
Truncated data (if more than 512 bytes) when using boost::asio::async_read_until from serial port
我正在使用 boost::asio::async_read_until 函数从 Windows 10 中的串行端口读取数据。分隔符是正则表达式模式。只要接收到的数据不大于 512 字节,它就会按预期工作。
如果接收到的数据大于512字节,则直接截断,不会再次调用"readComplete"函数。但是,如果我发送更多数据,1 个字节就足够了,丢失的数据会与新数据一起接收。
我在 tcp/socket 上使用了相同的实现,并且运行完美。 Windows 中的本机串行接口是否有任何限制导致此行为?
编辑 1:我注意到如果波特率从 115200 降低到 28800,则不会丢失任何数据。
// from .h-file: boost::asio::streambuf streamBuf_;
void RS232Instrument::readAsyncChars()
{
boost::asio::async_read_until(
serial_,
streamBuf_,
boost::regex(regexStr_.substr(6, regexStr_.length() - 7)),
boost::bind(
&RS232Instrument::readComplete,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void RS232Instrument::readComplete(const boost::system::error_code& error, size_t bytes_transferred)
{
if(error)
{
// Error handling
}
else
{
std::string rawStr(
boost::asio::buffers_begin(streamBuf_.data()),
boost::asio::buffers_begin(streamBuf_.data()) + bytes_transferred);
// Log the data in rawStr....
// Remove data from beginning until all data sent to log
streamBuf_.consume(bytes_transferred);
if(abort_ == false)
{
readAsyncChars();
}
}
}
既然我知道是这个问题引起的,我会自己回答这个问题。
为了清楚起见,我省略了上面的一些代码,我没有意识到的代码实际上是问题所在。
遗漏的代码示例:
LOG_DEBUG("Rs232Data received");
我使用了 boost:log 功能,并且在日志框架中添加了更多 "sinks"。本例中使用的接收器记录到 ram 中的向量,并在用户输入触发时打印到控制台。
原来日志框架在调用sink中的"consume"函数之前消耗了大约1ms。这足以导致使用async_read_until.
时串口丢失数据
经验教训:不要在 async_read_until
的处理函数中调用任何耗时的任务
我正在使用 boost::asio::async_read_until 函数从 Windows 10 中的串行端口读取数据。分隔符是正则表达式模式。只要接收到的数据不大于 512 字节,它就会按预期工作。
如果接收到的数据大于512字节,则直接截断,不会再次调用"readComplete"函数。但是,如果我发送更多数据,1 个字节就足够了,丢失的数据会与新数据一起接收。
我在 tcp/socket 上使用了相同的实现,并且运行完美。 Windows 中的本机串行接口是否有任何限制导致此行为?
编辑 1:我注意到如果波特率从 115200 降低到 28800,则不会丢失任何数据。
// from .h-file: boost::asio::streambuf streamBuf_;
void RS232Instrument::readAsyncChars()
{
boost::asio::async_read_until(
serial_,
streamBuf_,
boost::regex(regexStr_.substr(6, regexStr_.length() - 7)),
boost::bind(
&RS232Instrument::readComplete,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void RS232Instrument::readComplete(const boost::system::error_code& error, size_t bytes_transferred)
{
if(error)
{
// Error handling
}
else
{
std::string rawStr(
boost::asio::buffers_begin(streamBuf_.data()),
boost::asio::buffers_begin(streamBuf_.data()) + bytes_transferred);
// Log the data in rawStr....
// Remove data from beginning until all data sent to log
streamBuf_.consume(bytes_transferred);
if(abort_ == false)
{
readAsyncChars();
}
}
}
既然我知道是这个问题引起的,我会自己回答这个问题。
为了清楚起见,我省略了上面的一些代码,我没有意识到的代码实际上是问题所在。 遗漏的代码示例:
LOG_DEBUG("Rs232Data received");
我使用了 boost:log 功能,并且在日志框架中添加了更多 "sinks"。本例中使用的接收器记录到 ram 中的向量,并在用户输入触发时打印到控制台。
原来日志框架在调用sink中的"consume"函数之前消耗了大约1ms。这足以导致使用async_read_until.
时串口丢失数据经验教训:不要在 async_read_until
的处理函数中调用任何耗时的任务