[英]Reading the latest data from serial port using boost asio
我有一些需要从串行设备读取的代码。 这是一个轮询函数,由速率r
调用。
该设备以\\r\\n
及其速度(大约100Hz)分隔开的行中吐出数据。 每当我轮询时,我都想读取整个串行缓冲区。 我发现使用boost :: asio很难做到这一点,因为它似乎没有为我提供available()
函数。
我尝试的一种方法是使用read_until()
但它不能解决我的问题,因为在\\r\\n
, read_until()
停在\\r\\n
之后,缓冲区中可能会有更新的数据。
读取缓冲区后,我尝试在缓冲区上consume()
,但这仍然是一项繁琐的工作,直到我知道我已从设备读取了最新数据。
有人对这个问题有意见吗?
由于串行端口是作为流而不是随机访问句柄读取的,因此必须按接收顺序读取数据。 鉴于此行为,这里有一些获取最新数据的选项:
\\r\\n
”字符序列用于数据边界,请考虑使用async_read_until()
尊重数据边界,而不必在应用程序代码内引入边界处理。 如果进入速率大于消耗速率,则超时可能不确定。 native_handle()
和系统特定的调用来确定可读取的字节数。 然后,采用一种读取策略,该策略使用可用的字节数来确定何时停止读取。 请注意,可用字节数可能不会直接落在数据边界上。 因此,应用程序将需要处理碎片。 例如,一个async_read_until()
可能超时。 但是,一旦消耗了先前已知的可用字节数,就可以显式停止异步调用链。 即使入口速率超过消耗速率,这也为异步调用链提供了确定性的终结。 请查阅系统文档以确定如何查询准备读取的可用字节,但是在Linux上通常是ioctl(..., FIONREAD, ...)
,在Windows上通常是ClearCommError()
。 async_read_until()
调用链连续从串行端口读取并保留最近读取的数据。 根据人们访问最新数据的方式,可能需要使用同步机制(例如互斥体)来避免争用情况。 一种消除从串行端口读取后锁定的需要的替代方法是使用async_read_until()
,并将满足诺言的操作发布到运行async_read_until()
循环的同一async_read_until()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.