3. UART 与 DMA 结合:为什么需要 DMA 及典型应用场景

在嵌入式系统中,UART(通用异步收发器)是最常用的串行通信接口之一。当波特率较低、数据量较小时,CPU 可以直接通过中断或轮询方式处理每个字节。然而,随着通信速率提升至数 Mbps 或数据包长度达到 KB 级别,传统的中断驱动模式会带来严重的 CPU 开销,甚至导致数据丢失。此时,DMA(直接存储器访问)成为解决性能瓶颈的关键技术。

3.1 为什么 UART 需要 DMA

UART 每传输一个字节都会触发一次中断。假设波特率为 3 Mbps,每个字节包含 10 位(1 起始位 + 8 数据位 + 1 停止位),则每秒传输约 300,000 字节。CPU 每 3.3 µs 就要响应一次中断,执行上下文保存、寄存器读写、缓冲区更新等操作。这种高频中断会严重挤占 CPU 处理其他任务的时间。

核心痛点: 高波特率下,中断服务程序(ISR)的频繁执行导致 CPU 利用率急剧上升,系统实时性下降,甚至出现 RX 溢出(Overrun)错误。

DMA 控制器接管 UART 数据搬运工作后,CPU 只需在传输开始前配置好源/目的地址和传输长度,在传输完成后通过完成中断获知结果。中间的数据搬运完全由 DMA 硬件完成,不占用 CPU 周期。

中断模式 vs DMA 模式关键对比
对比维度 中断驱动模式 DMA 模式
每字节 CPU 干预 是,每次传输触发 ISR 否,DMA 硬件自动搬运
CPU 利用率(3 Mbps) 约 60% ~ 80% 约 5% ~ 15%
数据吞吐量上限 受中断响应延迟限制 接近 UART 硬件极限
缓冲区管理 需在 ISR 中逐字节处理 DMA 直接填充/读取内存
错误处理复杂度 ISR 中即时检测 需结合完成中断与状态寄存器
设计建议: 当波特率 ≥ 115200 bps 且单次传输数据量 ≥ 64 字节时,强烈建议启用 DMA 模式。对于低波特率或小数据量场景,中断模式反而更简单高效。

3.2 UART + DMA 的典型应用场景

UART 与 DMA 的结合主要面向高波特率、大数据量、低延迟要求的通信场景。以下列出三种最典型的应用场景。

3.2.1 高波特率连续数据流

例如工业现场总线(RS-485/RS-422)以 1 Mbps ~ 10 Mbps 速率传输传感器数据或控制指令。DMA 可以连续接收数百字节的报文,CPU 仅在完整报文到达后执行解析。

3.2.2 大块数据批量传输

如固件升级、日志导出、文件传输。数据量可达数 KB 甚至数 MB。DMA 的块传输模式(Burst Transfer)能充分利用总线带宽,减少传输时间。

3.2.3 低功耗物联网设备

在电池供电设备中,CPU 大部分时间处于休眠状态。DMA 可以在 CPU 休眠时独立完成 UART 数据收发,仅在传输完成或出错时唤醒 CPU,显著降低系统功耗。

UART + DMA 典型应用场景架构图 UART + DMA 典型应用场景架构 CPU 配置 / 解析 / 休眠 DMA 控制器 数据搬运 / 链式传输 UART 外设 发送 / 接收 / 状态 外部设备 传感器 / 主机 配置 数据请求 TX / RX 完成中断 / 错误中断 典型应用场景说明 ① 高波特率连续数据流:工业总线 1~10 Mbps,DMA 连续接收报文,CPU 批量解析。 ② 大块数据批量传输:固件升级 / 日志导出,DMA 块传输模式,减少传输时间。 ③ 低功耗物联网设备:CPU 休眠,DMA 独立收发,仅在完成或出错时唤醒 CPU。 ④ 多通道并发:DMA 支持多通道,可同时管理多个 UART 实例的数据流。 ⑤ 链式传输:DMA 链表模式支持不连续内存块传输,适合协议帧处理。

3.3 UART + DMA 的软件架构层次

在 Linux 内核中,UART + DMA 的驱动通常分为三层:

  1. UART 控制器驱动层(tty/serial):负责寄存器配置、波特率设置、流控管理,提供 uart_ops 回调。
  2. DMA 引擎驱动层(dmaengine):提供统一的 DMA 传输 API,如 dmaengine_prep_slave_sg()、dmaengine_submit()。
  3. DMA 传输完成回调与错误处理层:在 DMA 完成中断或错误中断中,调用 UART 驱动的回调函数,更新环形缓冲区、唤醒等待队列。
注意事项: DMA 传输完成中断并不等同于 UART 数据帧结束。当使用 DMA 接收时,需要结合 UART 的空闲中断(IDLE)或超时定时器来检测帧边界。否则,DMA 可能一直等待填满预设长度才触发完成中断,导致短帧无法及时处理。

3.4 关键配置参数对比

UART + DMA 关键配置参数
参数 说明 典型值 影响
DMA 传输宽度 单次传输的数据位宽 8 位 / 16 位 / 32 位 匹配 UART 数据寄存器宽度
DMA 突发长度 连续传输的数据项数 4 / 8 / 16 影响总线占用与传输效率
环形缓冲区大小 DMA 接收缓冲区容量 512 / 1024 / 2048 字节 决定抗压能力与丢包风险
超时阈值 帧间隔超时时间 3 ~ 5 字符时间 影响短帧实时性
DMA 通道优先级 多通道时的仲裁优先级 高 / 中 / 低 影响多外设并发时的响应

3.5 小结

UART 与 DMA 的结合是解决高波特率、大数据量通信性能瓶颈的核心手段。DMA 将 CPU 从逐字节中断处理中解放出来,使 CPU 专注于协议解析与业务逻辑。典型应用场景包括工业总线、固件升级、低功耗物联网等。在驱动开发中,需要合理配置 DMA 传输参数,并处理好完成中断与帧边界检测的关系,才能充分发挥硬件性能。