在双缓冲区和环形缓冲区之间进行选择?
Choosing between double buffer and ring buffer?
我在解码通过微控制器的 UART 发送的数据包时遇到问题(固件需要是裸机,不支持 RTOS)。数据包长 32 字节,每 10 毫秒发送一次(连续,没有任何停顿)。
我需要在 ISR 中进行非常少的处理(以保持 ISR 足够短)并在 main() 循环中进行延迟处理。我想到了两种方法-
1. 使用中断安全的环形缓冲区,ISR 写入缓冲区并从中读取 main() 循环。头指针和尾指针被假定为我的体系结构的原子类型,以确保缓冲区是中断安全的。请参阅示例实现 here。
- 使用双缓冲方案(乒乓缓冲区),其中 main() 循环应处理其中一个缓冲区,而 ISR 正在写入另一个缓冲区。假设我可以原子地修改指向 ISR 缓冲区的指针,从而避免临界区问题。
串口可以产生RX FIFO非空中断。还提供 DMA 支持。
- 这里使用的最佳数据结构是什么?
- 这里涉及的权衡是什么?
双缓冲区只是一种特殊的环形缓冲区,只有两个槽,在生产者和消费者之间交换。如果您的处理时间变化不大,应该足够了。如果输入速率或处理时间发生变化,环形缓冲区可能会有所帮助,但当处理跟不上时,您很可能需要一些流量控制来减慢输入速率。
我在解码通过微控制器的 UART 发送的数据包时遇到问题(固件需要是裸机,不支持 RTOS)。数据包长 32 字节,每 10 毫秒发送一次(连续,没有任何停顿)。
我需要在 ISR 中进行非常少的处理(以保持 ISR 足够短)并在 main() 循环中进行延迟处理。我想到了两种方法- 1. 使用中断安全的环形缓冲区,ISR 写入缓冲区并从中读取 main() 循环。头指针和尾指针被假定为我的体系结构的原子类型,以确保缓冲区是中断安全的。请参阅示例实现 here。
- 使用双缓冲方案(乒乓缓冲区),其中 main() 循环应处理其中一个缓冲区,而 ISR 正在写入另一个缓冲区。假设我可以原子地修改指向 ISR 缓冲区的指针,从而避免临界区问题。
串口可以产生RX FIFO非空中断。还提供 DMA 支持。
- 这里使用的最佳数据结构是什么?
- 这里涉及的权衡是什么?
双缓冲区只是一种特殊的环形缓冲区,只有两个槽,在生产者和消费者之间交换。如果您的处理时间变化不大,应该足够了。如果输入速率或处理时间发生变化,环形缓冲区可能会有所帮助,但当处理跟不上时,您很可能需要一些流量控制来减慢输入速率。