2. DMA控制器硬件架构

DMA(Direct Memory Access)控制器是嵌入式系统中负责在内存与外设之间、或内存与内存之间直接传输数据的关键硬件模块。理解其内部组成与常见类型,是编写高效、稳定DMA驱动的前提。本章将深入剖析DMA控制器的核心组件,并对比两种广泛使用的商用DMA控制器:ARM PL330与Synopsys DW_axi_dmac。

2.1 DMA控制器内部组成

一个典型的DMA控制器由多个功能单元协同工作,主要包括:通道(Channel)、仲裁器(Arbiter)、地址发生器(Address Generator)以及控制逻辑与状态寄存器。下图展示了其内部架构关系。

DMA控制器内部组成架构 系统总线接口 控制逻辑 & 状态寄存器 通道组 (Channel Group) 通道 0 通道 1 通道 2 通道 3 仲裁器 地址发生器 数据 FIFO 说明: • 通道是独立的数据传输引擎,每个通道包含源/目的地址寄存器、传输计数器和控制配置。 • 仲裁器决定多个通道同时请求总线时的优先级顺序(固定优先级或轮询)。 • 地址发生器根据传输模式(线性、循环、1D/2D)自动更新源和目的地址。

2.1.1 通道(Channel)

通道是DMA控制器的基本执行单元。每个通道独立管理一次数据传输任务,包含以下关键寄存器与逻辑:

  • 源地址寄存器(SAR):存储数据读取的起始地址。
  • 目的地址寄存器(DAR):存储数据写入的起始地址。
  • 传输计数寄存器(CTL/BCR):记录待传输的数据量(字节数或块数)。
  • 控制配置寄存器(CCR):配置传输方向、数据宽度、突发大小、中断使能等。
  • 状态寄存器:指示通道是否忙碌、传输完成、错误等状态。
驱动开发要点: 在多通道场景下,驱动需要为每个通道维护独立的描述符链表和回调函数上下文。通道的分配与释放是驱动设计中的关键资源管理环节。

2.1.2 仲裁器(Arbiter)

当多个通道同时请求系统总线进行数据传输时,仲裁器负责决定总线使用权。常见的仲裁策略包括:

仲裁策略 描述 适用场景
固定优先级 通道编号越小(如通道0),优先级越高。高优先级通道可抢占低优先级通道。 实时性要求高的关键数据流(如音频、视频)。
轮询(Round-Robin) 所有通道按顺序轮流获得总线使用权,保证公平性。 多个外设带宽需求相近的场景(如多路UART、SPI)。
混合策略 将通道分组,组内固定优先级,组间轮询。 兼顾关键流与公平性的复杂系统。

2.1.3 地址发生器(Address Generator)

地址发生器在每次数据传输后,根据配置自动更新源地址和目的地址。其支持的模式直接影响驱动对描述符的构建方式:

  • 线性模式(Linear):地址连续递增或递减,适用于内存块拷贝或线性缓冲区。
  • 循环模式(Circular):地址到达边界后回绕到起始地址,适用于音频环形缓冲区。
  • 1D/2D 分块模式:支持行内连续、行间跨步的地址跳转,适用于图像帧缓冲区或矩阵转置。

2.2 常见DMA控制器类型

不同厂商的DMA控制器在架构、编程模型和功能特性上存在差异。以下重点介绍两种在嵌入式Linux中广泛使用的DMA控制器:ARM PL330 和 Synopsys DW_axi_dmac。

2.2.1 ARM PL330 DMA控制器

PL330是ARM公司推出的高性能DMA控制器,常见于基于AMBA总线的SoC(如Exynos、STM32MP系列)。其核心特点如下:

  • 微程序引擎:PL330内部包含一个微控制器,通过执行DMA微指令(DMA指令集)来完成复杂传输序列,而非简单的寄存器配置。
  • 描述符链(Descriptor Chain):支持链表式描述符,每个描述符指向下一个描述符,实现无需CPU干预的连续传输。
  • 事件与中断管理:每个通道可配置多个事件触发点(传输完成、半传输、错误),中断控制器可灵活屏蔽与路由。
  • 通道数量:通常支持8个通道,每个通道可独立配置。
ARM PL330 描述符链传输流程 描述符 0 src=0x1000, dst=0x2000 描述符 1 src=0x1100, dst=0x2100 描述符 2 src=0x1200, dst=0x2200 PL330 微程序引擎 描述符通过 next 指针链接,PL330 自动加载下一个描述符,无需 CPU 逐条配置。

2.2.2 Synopsys DW_axi_dmac DMA控制器

DW_axi_dmac是Synopsys DesignWare系列中的AXI总线DMA控制器,广泛应用于高性能SoC(如Zynq、Intel SoC FPGA)。其核心特点如下:

  • AXI总线接口:原生支持AXI4/AXI4-Stream协议,具备高带宽和低延迟特性。
  • 多块传输(Multi-Block):支持硬件链表(Hardware Linked List),描述符存储在内存中,由硬件自动遍历。
  • 可编程突发大小:支持1到256字节的突发传输,可针对不同外设优化总线效率。
  • 中断聚合:支持多个中断源合并为一个中断信号,减少CPU中断处理次数。
特性 ARM PL330 Synopsys DW_axi_dmac
总线协议 AMBA AHB/AXI AXI4 / AXI4-Stream
描述符管理 微指令 + 链表 硬件链表(内存描述符)
通道数量 最多8通道 最多16通道
传输粒度 字节/半字/字 字节/半字/字/双字
中断处理 每通道独立中断 支持中断聚合
典型应用 移动SoC、MCU FPGA、高端嵌入式

2.2.3 驱动开发视角的对比

从驱动开发角度看,两种控制器在描述符接口设计上存在显著差异:

  • PL330:驱动需要构建微指令序列(DMA指令),通过dmaengine_prep_slave_sg()等API提交。描述符的完成回调在微指令执行完毕后触发。
  • DW_axi_dmac:驱动直接填充内存中的描述符结构体(如dw_axi_dma_lli),设置llp(链表指针)字段链接下一个描述符。硬件自动遍历链表,无需微指令。
常见陷阱: 在DW_axi_dmac中,描述符链表必须位于非缓存(non-cacheable)内存区域,否则硬件可能读取到过时的描述符数据。驱动开发时需使用dma_alloc_coherent()分配描述符内存。

2.3 本章小结