1. UART DMA 基础概念
在全志 T113 平台的嵌入式开发中,UART 驱动采用 DMA 模式是提升数据吞吐量、降低 CPU 负载的关键技术。本节将系统讲解 DMA 的工作原理、UART 与 DMA 的协同机制,以及全志 T113 DMA 控制器的核心架构,为后续参数配置与性能调试奠定理论基础。
1.1 DMA 工作原理
DMA(Direct Memory Access,直接存储器访问)是一种允许外设与存储器之间直接传输数据而无需 CPU 干预的硬件机制。在传统的 PIO(Programmed I/O)模式下,CPU 需要逐字节搬运数据,导致 CPU 被大量占用;而 DMA 控制器接管了数据搬运任务,CPU 仅在传输开始和结束时参与。
核心优势: DMA 模式可将 UART 数据传输的 CPU 占用率从 80% 以上降低至 5% 以下,同时将有效数据吞吐量提升 3-5 倍。
DMA 传输的基本流程包含以下步骤:
- 初始化阶段: CPU 配置 DMA 控制器的源地址、目的地址、传输长度、传输宽度等参数,并启动 DMA 通道。
- 传输阶段: DMA 控制器独立于 CPU,通过系统总线直接读取源数据并写入目的地址,每次传输后自动更新地址和计数。
- 完成阶段: 当传输计数归零时,DMA 控制器向 CPU 发送中断信号,通知传输完成。
技术要点: DMA 传输模式分为单次传输(Single Transfer)和突发传输(Burst Transfer)。突发传输可一次搬运多个数据单元,总线利用率更高,但需要外设支持突发能力。全志 T113 的 DMA 控制器支持 1/4/8/16 字节的突发长度配置。
1.2 UART 与 DMA 协同机制
UART 与 DMA 的协同工作,本质上是将 UART 的接收/发送 FIFO 与系统内存之间的数据搬运任务交给 DMA 控制器。当 UART 的 FIFO 达到预设阈值或接收超时时,DMA 自动启动传输,将数据搬入内存缓冲区;发送时,DMA 从内存缓冲区取出数据写入 UART 发送 FIFO。
UART 与 DMA 协同工作时,需要关注以下关键参数:
| 参数名称 | 作用描述 | 典型配置值 |
|---|---|---|
| FIFO 阈值 | 触发 DMA 传输的 FIFO 数据量 | RX: 8 字节 / TX: 4 字节 |
| 突发长度 | 单次 DMA 传输的数据单元数 | 4 / 8 / 16 字节 |
| 传输宽度 | 每次传输的数据位宽 | 8 位(与 UART 数据位一致) |
| 描述符链 | 支持连续多段传输的描述符链表 | 2-8 个描述符 |
| 超时时间 | 接收超时触发 DMA 传输的时间 | 3-5 字符时间 |
常见陷阱: UART 的 FIFO 深度与 DMA 突发长度不匹配会导致数据丢失或传输效率低下。例如,T113 UART FIFO 深度为 64 字节,若 DMA 突发长度设置为 32 字节,而 FIFO 阈值设置为 1 字节,则可能频繁触发小数据量传输,降低 DMA 效率。建议 FIFO 阈值 ≥ 突发长度。
1.3 全志 T113 DMA 控制器概述
全志 T113 芯片内部集成了一个高性能 DMA 控制器,支持 8 个独立通道,可同时处理多个外设的 DMA 请求。该 DMA 控制器采用描述符链(Descriptor Chain)架构,支持内存到内存、内存到外设、外设到内存三种传输模式。
全志 T113 DMA 控制器的关键特性如下:
| 特性 | 规格 | 说明 |
|---|---|---|
| 通道数量 | 8 个独立通道 | 每个通道可独立配置源/目的地址、传输长度、传输模式 |
| 传输模式 | 3 种 | 内存到内存、内存到外设、外设到内存 |
| 数据宽度 | 8 / 16 / 32 / 64 位 | 支持字节、半字、字、双字传输 |
| 突发长度 | 1 / 4 / 8 / 16 | 单次突发传输的数据单元数 |
| 描述符链 | 支持 | 链表结构,支持连续多段传输,无需 CPU 反复配置 |
| 中断支持 | 每个通道独立中断 | 支持传输完成、传输错误、半传输中断 |
| 总线接口 | AHB / AXI 64 位 | 高带宽总线接口,支持高速数据传输 |
| 优先级 | 可配置 | 固定优先级或轮询调度算法 |
UART DMA 通道分配建议: 在全志 T113 平台上,通常为每个 UART 实例分配两个 DMA 通道:一个用于接收(RX),一个用于发送(TX)。例如,UART0 使用 CH0(RX)和 CH1(TX),UART1 使用 CH2(RX)和 CH3(TX),以此类推。这种分配方式可以避免通道冲突,并充分利用 DMA 控制器的并行处理能力。
DMA 描述符是 DMA 传输的核心数据结构,每个描述符定义了单次传输的所有参数:
// 全志 T113 DMA 描述符结构(简化版)
struct dma_descriptor {
uint32_t src_addr; // 源地址(物理地址)
uint32_t dst_addr; // 目的地址(物理地址)
uint32_t byte_count; // 传输字节数
uint32_t config; // 配置信息(突发长度、数据宽度、传输类型等)
uint32_t next_desc; // 下一个描述符地址(链表指针)
uint32_t status; // 传输状态(由硬件更新)
uint32_t reserved[2]; // 保留字段
};
描述符链优势: 使用描述符链可以实现“乒乓缓冲”(Ping-Pong Buffer)机制。例如,配置两个描述符分别指向两个不同的内存缓冲区,当第一个缓冲区填满后,DMA 自动切换到第二个缓冲区,同时 CPU 处理第一个缓冲区的数据,从而实现数据采集与处理的全流水线操作,极大提升系统吞吐量。