RT-Thread 两代串口 DMA 驱动的缓冲边界取舍
项目仓库:github.com/RT-Thread/rt-thread(实时操作系统及设备驱动项目)
串口 DMA 接收只有一个核心取舍:接收缓冲是否直接承担 FIFO 职责。RT-Thread 的两代驱动给出了两种答案。
经典驱动的 DMA 缓冲即 FIFO
经典驱动把 DMA 缓冲区直接当作串口环形队列使用。DMA 写入数据,应用从同一块缓冲区读取,中间没有额外拷贝。
缓冲区写满后,DMA 继续前进并覆盖旧数据。这套方案不追求保存全部历史数据,优先保证接收路径持续运行。
它的哲学很直接:用最少的内存和最短的数据路径换取性能,溢出时接受旧数据损失。
V2 驱动的 DMA 缓冲与 FIFO 分离
V2 驱动使用一块连续的循环 DMA 缓冲区。HT 表示前半区写完,TC 表示后半区写完,软件按两个半区交替处理,形成软件意义上的 ping-pong;DMA 控制器配置的仍是一块连续内存。
处理完成的数据再交给下方的应用 FIFO。DMA 接收和应用读取各自拥有缓冲边界,应用 FIFO 可以选择丢弃新数据或覆盖旧数据。
它的哲学是把接收动作和数据管理分开,用额外内存和一次搬运换取更清晰的边界与恢复方式。
取舍
两种方案都无法让有限缓冲区承受无限输入。差别是资源优先级:
- 资源紧张、输入可控、允许覆盖旧数据:DMA 缓冲即 FIFO。
- 数据完整性优先、需要明确处理溢出:连续 DMA 缓冲与应用 FIFO 分离。
RT-Thread 的实现说明,串口 DMA 的关键决策是明确溢出发生时由系统保留什么、放弃什么,再选择 DMA 直写 FIFO 或连续 DMA 缓冲加软件 FIFO。