缓冲不完整的高速读取

Buffering Incomplete High Speed Reads

本文关键字:高速 读取 缓冲      更新时间:2023-10-16

我正在以100hz的频率从串行端口读取数据~100字节。我的缓冲区是1024字节,所以我的缓冲区时经常无法完全使用。然而,有时我会从串行端口打嗝,缓冲区会被填满。

我的数据被组织为[标头]数据[校验和]。当我的缓冲区被填满时,有时一条消息/数据会从串行端口分为两次读取

这是一个简单的问题,我相信有很多不同的方法。我提前了计划,所以我想研究不同的方法。你们能说出一些涵盖高速数据缓冲的范例吗?这些数据可能需要从两次读取中组合在一起?注意,我在这个问题中看到的与我所做的其他缓冲(图像采集,tcp/ip)的主要区别在于,我们保证了完整的数据包/消息。在这里,一个"数据包"可能在读取之间被分割,只有当我们开始解析数据时,我们才会知道。

哦,是的,请注意,从读取缓冲的数据必须进行解析,所以为了简单起见,数据在到达解析时应该是连续的。(另外,我不认为这是解析器的责任)

我的一些想法:

  1. 将未使用的字节转移到我的原始缓冲区,然后在上次读取的剩余字节之后用读取填充它。(例如,我们读取1024个字节,最后还有24个字节,它们是一条部分消息,memcpy到read_buffer_的开头,将开头的+24传递给read并在1024-24中读取)
  2. 创建我自己的类,只获取数据块。它有两个指针,读/写和一大块内存(1024*4)。当您传入数据时,类会正确地更新写指针,当它到达缓冲区的末尾时,它会绕到缓冲区的开头。我想像个环形缓冲器
  3. 我在想也许用std::vector<unsigned char>。动态内存分配,保证连续

谢谢你们的信息!

定义一些"APU"应用程序协议单元类,该类将表示您的"[标头]数据[校验和]"。给它一些"add"函数,它接受一个char参数并返回一个"valid"bool。在串行读取线程中,创建一个APU并将一些数据读取到1024字节的缓冲区中。对缓冲区中的数据进行迭代,将其推入APU add(),直到APU add()函数返回true或迭代完成。如果add()返回true,则有一个完整的APU-将其排队等待处理,创建另一个APU并开始向其添加剩余的缓冲区字节()。如果迭代完成,则循环以读取更多的串行数据。

add()方法将使用状态机或其他机制来建立和检查传入的字节,只有在具有正确校验和的完整性检查数据集的情况下才会返回"true"。如果检查的某些部分失败,APU将"重置"并等待检测到有效的收割台。

APU可能会在add()数据输入期间逐字节地解析数据本身,就在add()返回"true"之前,也可能作为稍后调用的单独的"parse()"方法,可能由其他APU处理线程调用。

当从串行端口高速读取时,通常需要某种握手机制来控制数据流。这可以是硬件(例如RTS/CTS)、软件(Xon/Xoff),或者由更高级别的协议控制。如果你在没有握手的情况下以高速读取大量数据,你的UART或串行控制器需要能够以该速度读取和缓冲所有可用数据,以确保没有数据丢失。在Windows PC上看到的16550个兼容UART上,这个缓冲区只有14个字节,因此需要握手或实时操作系统。