RT-Thread 两代串口 DMA 驱动的缓冲边界取舍

项目仓库:github.com/RT-Thread/rt-thread(实时操作系统及设备驱动项目)

串口 DMA 接收只有一个核心取舍:接收缓冲是否直接承担 FIFO 职责。RT-Thread 的两代驱动给出了两种答案。

RT-Thread 两代串口 DMA 缓冲结构对比

经典驱动的 DMA 缓冲即 FIFO

经典驱动把 DMA 缓冲区直接当作串口环形队列使用。DMA 写入数据,应用从同一块缓冲区读取,中间没有额外拷贝。

缓冲区写满后,DMA 继续前进并覆盖旧数据。这套方案不追求保存全部历史数据,优先保证接收路径持续运行。

它的哲学很直接:用最少的内存和最短的数据路径换取性能,溢出时接受旧数据损失。

V2 驱动的 DMA 缓冲与 FIFO 分离

V2 驱动使用一块连续的循环 DMA 缓冲区。HT 表示前半区写完,TC 表示后半区写完,软件按两个半区交替处理,形成软件意义上的 ping-pong;DMA 控制器配置的仍是一块连续内存。

处理完成的数据再交给下方的应用 FIFO。DMA 接收和应用读取各自拥有缓冲边界,应用 FIFO 可以选择丢弃新数据或覆盖旧数据。

它的哲学是把接收动作和数据管理分开,用额外内存和一次搬运换取更清晰的边界与恢复方式。

取舍

两种方案都无法让有限缓冲区承受无限输入。差别是资源优先级:

RT-Thread 的实现说明,串口 DMA 的关键决策是明确溢出发生时由系统保留什么、放弃什么,再选择 DMA 直写 FIFO 或连续 DMA 缓冲加软件 FIFO。