解析时限 UART 数据

Posted

技术标签:

【中文标题】解析时限 UART 数据【英文标题】:Parsing time-delimited UART data 【发布时间】:2015-01-25 00:05:30 【问题描述】:

在尝试对 UART 连接上的数据进行正确的逆向工程和解码时,我得出了以下关于所接收数据格式的结论。

    数据以“数据包”形式发送。每个数据包仅由传输之间的时间(空格)分隔。 数据包长度可变。长度由序列中的第三个字节指定。 数据使用任何特殊字符或带外信号构成帧,但有效数据包可以(假定)有效,基于作为校验和值的最后字节框架。

使用逻辑分析仪时,很容易识别数据包。但是,通过 UART 将数据馈送到程序使分隔数据包成为不可能。所有接收到的数据都由操作系统排队。虽然可以添加某些处理程序来触发数据接收事件,但这并不能确保操作系统的 uart 队列中可用的数据将是一个完整的数据包。

是否有分离此类数据的最佳实践?

附录:

我目前的解决方案(开销很大,错误率也很大):

从队列中的第一个字节开始,尝试解析一个帧。如果帧中指定的大小大于 0x20(没有大于 32 字节的数据包 - 包括标头和校验和),则当前“起始字节”被视为无效并丢弃,并且从下一个字节继续识别等)

我正在研究的另一个解决方案是使用微控制器来解析数据并正确地对其进行构图,无论是带内还是带外。这是一个更好的解决方案,因为这样一个时间敏感的协议应该需要一个 RTOS。但是,仍然必须有一种方法可以在普通操作系统上实现这一点。

逻辑分析仪: (第一个和第二个字节不是常数。我已经推断出第一个字节是一个地址(或者可能是一个时隙,第二个字节是一个数据包类型)。

【问题讨论】:

如果您编写驱动程序,您只能在“正常”操作系统上可靠地实现这一点。因此,从收到 UART 中断的那一刻起,您将有一个不错的保证,代码将以相当短的延迟运行。 【参考方案1】:

我正在研究的另一个解决方案是使用微控制器

(Modbus 是一种串行协议,似乎也依赖空闲时间来分隔消息帧。)

检测此类间隙的最佳方法是使用 USART/UART,它可以通过硬件在实际接收器输入端进行测量。由于延迟,任何用户空间软件解决方案都容易出现不准确和错误事件。

Atmel ARM(可能还有 AVR32)SoC 中的 USART 具有“接收器超时”功能。每个接收到的字符都会重新启动此计时器。可以在指定的时间间隔后产生中断(即一段时间内没有接收到更多字符时)。此超时可被视为消息结束事件。

来自 Atmel 数据表:

接收器超时支持处理可变长度帧。此功能检测 RXD 线路上的空闲状态。当检测到超时时,通道状态寄存器 (US_CSR) 中的 TIMEOUT 位会上升并产生中断,从而向驱动程序指示帧结束。


附录

一个可能的软件解决方案需要一个(高分辨率)周期性定时器,U(S)ART 驱动程序将使用它来计算接收字符之间的时间间隔。使用 PIO 而不是 DMA,驱动程序必须在收到每个字符时重置 count_of_intervals。当计数超过阈值时(即count * interval_time > inter_message_gap_time),则表示接收方已经静默太久,表示消息间存在间隙。

澄清:您需要 HR 计时器来模拟上述接收器超时。 您不想简单地测量接收字符之间的时间间隔。 每当“下一个”消息的开始以某种方式延迟时,这很容易出现“腐烂消息”的情况,因此在“下一个”消息到达之前不会检测到最后收到的消息的“结束”。

【讨论】:

这正是我希望避免的。我有备用的 AVR 和 2-3 个 FPGA 收集灰尘,这可能就是我要做的。如果我不能用 AVR 完成它。 此外,在阅读 Modbus 时,该协议似乎与 Modbus RTU 非常相似。谢谢!

以上是关于解析时限 UART 数据的主要内容,如果未能解决你的问题,请参考以下文章

printf的封装与实现

MCU 上有两个 UART:需要(或明智)FreeRTOS?

uart接收和发送数据

UART蓝牙通信问题 向UART发送数据的正确格式是啥(整数值)

UART基础知识转载

一起玩转玩转LiteOS组件:TinyFrame