2. DMA控制器架构:DMA通道与请求映射、源/目标地址配置、传输宽度与突发模式

DMA(Direct Memory Access)控制器是嵌入式系统中实现高速数据搬移的核心硬件模块。理解其内部架构是进行驱动隔离调试与设备移植故障排查的基础。本节将深入剖析DMA控制器的三大关键子模块:通道与请求映射、源/目标地址配置以及传输宽度与突发模式。

2.1 DMA通道与请求映射

DMA控制器通常包含多个独立的通道(Channel),每个通道可以独立配置并处理一条数据传输链路。通道是DMA引擎的基本执行单元,而请求映射(Request Mapping)则决定了哪个外设或软件事件可以触发该通道开始工作。

核心概念: 每个DMA通道都有一个专用的请求线(Request Line)。硬件设计上将外设(如UART、SPI、ADC)的DMA请求信号通过多路选择器(MUX)连接到不同的通道上。驱动开发者的任务就是正确配置这个映射关系。

下图展示了一个典型的DMA控制器内部通道与外设请求的映射架构:

DMA通道与外设请求映射架构 外设请求源 UART1_TX SPI2_RX ADC1_DONE TIM2_UP 软件触发 请求映射 (MUX) CH0 ← UART1 CH1 ← SPI2 CH2 ← ADC1 CH3 ← TIM2 CH4 ← 软件 DMA通道 通道 0 通道 1 通道 2 通道 3 通道 4 通道仲裁 (优先级) → 系统总线 (AHB/APB)
调试要点: 在设备移植时,最常见的问题之一是外设请求号与DMA通道号不匹配。务必查阅芯片参考手册中的“DMA Request Mapping”表格,确认外设的DMA请求线编号。

2.2 源/目标地址配置

DMA传输的核心是数据从一个地址空间搬移到另一个地址空间。每个DMA通道都包含一组地址寄存器,用于配置源地址(Source Address)和目标地址(Destination Address)。根据传输场景,地址可以设置为固定模式或递增模式。

地址模式 描述 典型应用场景
固定地址 每次传输后地址不变,始终指向同一个寄存器或内存位置 外设数据寄存器(如UART_DR、SPI_DR)
递增地址 每次传输后地址自动增加(增加量为传输宽度) 内存缓冲区(如数组、FIFO)
回环地址 地址递增到边界后自动回到起始地址 循环缓冲区(音频流、数据采集)

地址配置的典型寄存器结构如下:

/* DMA通道地址寄存器结构(以STM32为例) */
typedef struct {
    volatile uint32_t SAR;   /* 源地址寄存器 (Source Address Register) */
    volatile uint32_t DAR;   /* 目标地址寄存器 (Destination Address Register) */
    volatile uint32_t NDTR;  /* 传输数据数量寄存器 (Number of Data) */
    volatile uint32_t CR;    /* 控制寄存器 (Control Register) */
    volatile uint32_t PAR;   /* 外设地址寄存器 (Peripheral Address Register) - 部分控制器 */
} DMA_Channel_TypeDef;

/* 配置示例:从外设数据寄存器读取数据到内存缓冲区 */
void dma_config_mem2mem(DMA_Channel_TypeDef *ch, uint32_t src, uint32_t dst, uint16_t size) {
    ch->SAR = src;          /* 源地址:外设寄存器地址 */
    ch->DAR = dst;          /* 目标地址:内存缓冲区地址 */
    ch->NDTR = size;        /* 传输数据量:字节数 */
    ch->CR |= (1 << 7);     /* 内存递增模式 (MINC) */
    ch->CR &= ~(1 << 6);    /* 外设非递增模式 (PINC = 0) */
    ch->CR |= (1 << 0);     /* 使能通道 (EN) */
}
常见故障: 地址对齐问题。如果源或目标地址没有按照传输宽度对齐(例如32位传输时地址不是4字节对齐),会导致总线错误(Bus Fault)或数据错位。在调试时,务必检查地址的低位对齐情况。

2.3 传输宽度与突发模式

传输宽度(Transfer Width)定义了DMA每次数据传输的位宽,通常支持字节(8位)、半字(16位)和字(32位)。突发模式(Burst Mode)则决定了DMA在获得总线控制权后,连续传输多少个数据单元。

下表对比了不同传输宽度和突发长度的组合对总线性能的影响:

传输宽度 突发长度 单次总线占用 适用场景 注意事项
8-bit (字节) 1 (单次) 1个总线周期 低速外设、UART 总线利用率低
16-bit (半字) 4 (突发) 4个总线周期 音频Codec、SPI 需外设支持突发
32-bit (字) 8 (突发) 8个总线周期 高速ADC、内存拷贝 可能阻塞CPU访问
32-bit (字) 16 (增量突发) 16个总线周期 显示控制器、DDR 需FIFO深度匹配

突发模式的工作流程可以通过下图理解:

突发模式传输时序对比 非突发模式 (单次传输) DMA请求 传输1 释放总线 DMA请求 传输2 释放总线 → 每次传输后释放总线, 重新仲裁,延迟大 突发模式 (Burst=4) DMA请求 传输1 传输2 传输3 传输4 释放总线 → 一次请求连续传输4个数据, 总线占用时间长但吞吐量高 ⚠ 突发模式配置需匹配外设FIFO深度:若外设FIFO小于突发长度,可能导致数据溢出或丢失。
性能权衡:
  • 单次模式: 总线延迟高,但CPU响应快,适合低数据率外设。
  • 突发模式: 总线吞吐量高,但会长时间占用总线,增加CPU等待时间。在实时系统中需谨慎配置突发长度。

2.4 关键寄存器配置总结

以下表格汇总了DMA通道配置中与本节内容相关的核心寄存器位域:

寄存器 位域 功能描述 配置值示例
CR (控制寄存器) DIR[1:0] 传输方向:外设到内存 / 内存到外设 / 内存到内存 00: 外设→内存; 01: 内存→外设; 10: 内存→内存
CR PSIZE[1:0] 外设数据宽度:8/16/32位 00: 8-bit; 01: 16-bit; 10: 32-bit
CR MSIZE[1:0] 内存数据宽度:8/16/32位 00: 8-bit; 01: 16-bit; 10: 32-bit
CR MBURST[1:0] 内存侧突发模式:单次/4/8/16节拍 00: 单次; 01: 4节拍; 10: 8节拍; 11: 16节拍
CR PBURST[1:0] 外设侧突发模式:单次/4/8/16节拍 00: 单次; 01: 4节拍; 10: 8节拍; 11: 16节拍
SAR / DAR [31:0] 源/目标基地址 必须按PSIZE/MSIZE对齐
NDTR [15:0] 待传输数据项数量(非字节数) 0x0001 ~ 0xFFFF
移植检查清单:
  1. 确认目标芯片的DMA通道数量与外设请求映射表。
  2. 检查源/目标地址是否按传输宽度对齐。
  3. 验证突发长度是否超出外设FIFO深度。
  4. 确认传输宽度设置与外设寄存器位宽一致(例如UART数据寄存器通常为8位)。