【发布时间】:2019-07-05 22:35:43
【问题描述】:
我在解码通过微控制器的 UART 发送的数据包时遇到问题(固件需要是裸机,不支持 RTOS)。数据包长 32 个字节,每 10 毫秒发送一次(连续发送,没有任何停止)。
我需要在 ISR 中进行非常少的处理(以保持 ISR 足够短)并在 main() 循环中进行延迟处理。我想到了两种方法- 1. 使用中断安全的环形缓冲区,将 ISR 写入缓冲区并从中读取 main() 循环。头和尾指针被假定为我的体系结构的原子类型,以确保缓冲区是中断安全的。请参阅示例实现 here。
- 使用双缓冲方案(乒乓缓冲区),其中 main() 循环应在 ISR 写入另一个缓冲区时处理其中一个缓冲区。假设我可以原子地修改指向 ISR 缓冲区的指针,从而避免临界区问题。
UART 能够产生 RX FIFO 非空中断。还提供 DMA 支持。
- 这里使用哪种数据结构最合适?
- 这里涉及的权衡是什么?
【问题讨论】:
-
在双缓冲方法中切换缓冲的标准是什么?我猜你有一种“开始数据包”角色可以做到这一点?乍一看,这看起来比没有太多好处的简单环形缓冲区复杂一些。从错过的“数据包开始”中恢复对我来说似乎更困难。
-
双缓冲区需要 ISR 解码协议和切换缓冲区。相比之下,环形缓冲区不需要 ISR 来解码协议,但某些代码必须从环形的读取端足够快地读取以避免它被填满:该代码通常会将数据复制到另一个缓冲区,解析协议并保留已识别的数据包。 IMO 环形缓冲区对 ISR 的要求较低。
标签: embedded microcontroller circular-buffer double-buffering