1. DMA基础概念

1.1 DMA工作原理

直接存储器访问(Direct Memory Access,DMA)是一种允许外设或存储器之间直接传输数据的硬件机制,无需CPU逐字节参与。DMA控制器作为独立的总线主机,在系统总线上与CPU并行工作,显著提升数据吞吐量并降低CPU负载。

核心工作流程: DMA传输由硬件状态机构成,通常包含以下四个阶段:
  1. 请求阶段: 外设(如ADC、SPI、UART)产生DMA请求信号,通知DMA控制器准备传输。
  2. 仲裁阶段: DMA控制器向总线仲裁器申请总线控制权,优先级高于CPU(在多数车载MCU架构中)。
  3. 传输阶段: DMA控制器直接驱动地址总线和数据总线,完成源地址到目的地址的数据搬运,每次传输一个字节/半字/字。
  4. 完成阶段: 传输计数器递减至零时,DMA控制器产生中断信号通知CPU,或自动重载配置进入循环模式。
传输阶段 总线操作 时钟周期数(典型) CPU干预
请求与仲裁 DMA控制器获取总线控制权 1~2 无
源地址读取 从外设数据寄存器或存储器读取数据 1~4(取决于总线等待状态) 无
目的地址写入 将数据写入目标存储器或外设 1~4 无
地址更新与计数 源/目的地址递增或递减,传输计数器减1 0(并行于读写周期) 无
关键理解: DMA传输的最小单位是beat(一次总线传输)。对于支持突发传输(burst transfer)的DMA控制器,一次请求可连续传输多个beat,大幅降低总线仲裁开销。
DMA传输状态机与数据流 空闲 请求与仲裁 数据传输 传输完成 自动重载(循环模式) 外设 存储器 DMA搬运数据 注:DMA传输期间CPU可执行其他任务,仅在总线冲突时插入等待周期。

1.2 DMA在车载MCU中的角色

在车载嵌入式系统中,MCU需要同时处理多个实时外设的数据流——CAN收发、LIN通信、ADC采样、SPI传感器读取、PWM捕获等。DMA在这些场景中扮演着数据管道和CPU卸载引擎的双重角色。

车载应用场景 外设类型 数据速率 DMA作用
电机控制电流采样 ADC + SPI 1~10 Msps 将ADC结果直接搬运到PWM比较寄存器或RAM缓冲区
CAN FD报文收发 CAN控制器 最高8 Mbps 自动将报文从RAM搬运到CAN Tx FIFO,或从Rx FIFO搬运到RAM
传感器数据采集 SPI / I²C 1~50 Mbps 多通道传感器数据连续采集,无需CPU逐字节读取
音频/语音处理 I²S / SAI 48~192 kHz 双缓冲乒乓传输,保证音频流连续无断裂
Bootloader固件升级 UART / CAN 115200 bps~1 Mbps 大块固件数据从通信接口直接搬运到Flash编程缓冲区
车载安全关键性: 在ISO 26262 ASIL-B/D系统中,DMA传输必须配合ECC(纠错码)保护,防止单比特翻转导致数据损坏。部分车载MCU(如Infineon TC3xx、NXP S32K3)提供DMA传输的硬件CRC校验和地址保护机制。
车载MCU中DMA与外设的连接架构 CPU核心 任务调度/异常处理 DMA控制器 多通道/优先级/链式 系统总线 AHB/AXI/Crossbar 存储器 SRAM / Flash / DDR CAN / LIN ADC / DAC SPI / I²C PWM / Timer 车载MCU典型DMA通道分配: • 通道0:CAN0 Rx(高优先级,固定映射) • 通道1:ADC1 扫描完成(循环模式,双缓冲) • 通道2:SPI2 Tx/Rx(链式传输,触发PWM同步)

1.3 DMA与CPU的数据搬运对比

理解DMA与CPU在数据搬运上的本质差异,是正确使用DMA的前提。下表从多个维度进行对比:

对比维度 CPU搬运(轮询/中断) DMA搬运 车载场景影响
执行主体 CPU核心(取指、译码、执行) DMA控制器(硬件状态机) CPU可同时运行控制算法
每字节开销 10~50个CPU时钟周期(含循环、地址计算、中断压栈) 1~4个总线时钟周期(纯硬件搬运) 高数据速率场景下差异显著
CPU负载 100%占用(轮询)或每次中断约50~200周期(上下文切换) 仅初始化配置+完成中断(约0.1%~1% CPU负载) 释放CPU用于安全监控和诊断
实时性 受中断优先级和任务调度影响,抖动大 硬件触发,确定性延迟(通常2~5个总线周期) 满足车载硬实时要求
数据吞吐量 受限于CPU主频和指令效率 接近总线带宽上限 支持多通道并发采集
灵活性 可进行数据校验、格式转换、条件判断 仅搬运,部分DMA支持简单运算(加减、CRC) 复杂处理仍需CPU介入
功耗 高(CPU全速运行+缓存活动) 低(专用硬件,无取指开销) 符合车载低功耗待机要求
性能量化示例: 以100 kHz采样率、16位精度的ADC为例,每秒需搬运200 KB数据。
  • CPU轮询方式: 每次采样约消耗50周期 → 5 MHz CPU时间 → 在200 MHz MCU上占用2.5% CPU。
  • DMA方式: 每次采样仅消耗2个总线周期 → 0.2 MHz总线时间 → 几乎零CPU占用,且支持双缓冲无丢失。
何时不应使用DMA? 对于单次、小数据量(如1~4字节)或需要逐字节判断/转换的场景,DMA的初始化开销可能超过直接CPU读取。典型例子:UART接收单字节命令、GPIO电平读取。此时使用中断或轮询更高效。