2、DMA基础回顾:DMA的工作原理、传输模式(内存到内存、外设到内存)、与CPU中断的对比

在TinyML系统中,传感器数据采集、音频流处理、运动检测等场景对实时性和功耗有着严苛要求。若所有数据搬运都依赖CPU逐字节处理,不仅会大量占用CPU周期,还会因频繁进出中断服务程序而引入不可控的延迟抖动。DMA(Direct Memory Access,直接存储器访问)正是为解决这一瓶颈而设计的硬件机制。本章将系统梳理DMA的核心工作原理、两种关键传输模式,并通过与中断机制的深度对比,帮助你在TinyML工程中做出正确的数据通路设计决策。

DMA 数据通路与中断对比架构 CPU 核心 执行推理/控制流 响应中断/配置DMA DMA 控制器 搬运数据/管理描述符 触发完成中断 内存 (SRAM) 缓冲区A/B 模型输入/特征 外设 (ADC/I2S) 传感器数据流 定时触发采样 配置/状态 DMA写数据 外设→DMA请求 DMA传输完成 → 中断通知CPU 传统方式:外设中断CPU逐字节搬运 DMA数据流 中断通知 传统外设中断路径 外设请求

2.1 DMA核心工作原理:谁在搬运数据?

DMA的本质是一种硬件数据搬运引擎。当CPU配置好DMA控制器后,DMA便独立于CPU,直接在内存与外设之间、或内存的不同区域之间传输数据。整个传输过程由DMA控制器内部的有限状态机(FSM)管理,无需CPU逐条指令干预。

一个典型的DMA传输周期包含以下阶段:

  1. 请求阶段:外设(如ADC完成一次采样)或软件置位DMA请求标志,DMA控制器检测到请求后向总线仲裁器申请总线控制权。
  2. 应答阶段:总线仲裁器在CPU不访问总线的时间隙(或通过周期窃取方式)将总线控制权交给DMA控制器。
  3. 传输阶段:DMA控制器按照配置的源地址、目的地址、传输宽度(8/16/32位)和传输计数,执行一次或突发(Burst)多次数据传输。
  4. 地址更新与计数递减:每次传输后,DMA自动更新源/目的地址(递增、递减或固定),并将剩余传输计数减一。
  5. 完成判断:当计数减至零,DMA置位传输完成标志,并可触发中断通知CPU。

在TinyML场景中,DMA的典型应用是连续采集传感器数据到双缓冲区。例如,一个100Hz的IMU数据流,每个样本6字节(3轴×2字节),DMA可以配置为每采集10个样本触发一次中断,而CPU在中断中仅处理已填满的缓冲区,另一缓冲区继续由DMA填充,实现采集与计算的重叠。

关键参数速查表:配置DMA时必须明确的五个要素

参数说明TinyML典型值
源地址数据来源(外设数据寄存器或内存地址)ADC->DR 或 &buffer[0]
目的地址数据去向(内存地址或外设寄存器)&dma_buffer[0]
传输宽度每次搬运的数据位宽8位(麦克风PCM)/ 16位(加速度计)
传输计数总共搬运的数据单元数160(对应20ms音频帧)
循环模式是否自动回绕形成环形缓冲区通常开启,用于连续采集

2.2 两种核心传输模式:内存到内存与外设到内存

根据数据源和目的地的不同,DMA传输模式可分为两大类,它们在TinyML工作负载中扮演不同角色。

2.2.1 内存到内存(Memory-to-Memory)模式

该模式下,DMA在内存的两个区域之间搬运数据,无需外设参与。CPU只需设置源地址、目的地址和传输长度,DMA便完成剩余工作。在TinyML中,这种模式常用于:

  • 数据预处理:将传感器原始数据从采集缓冲区搬运到对齐的推理输入缓冲区。
  • 特征重排:将非连续存储的特征数据整理为连续内存块,便于向量处理器或SIMD指令高效访问。
  • 模型权重加载:从Flash读取权重到SRAM(部分MCU支持Flash到SRAM的DMA传输)。

需要注意的是,内存到内存模式会持续占用总线,因此传输期间CPU可能因总线竞争而变慢。在实时性要求高的推理阶段,应避免大块内存拷贝与推理计算同时进行。

2.2.2 外设到内存(Peripheral-to-Memory)模式

这是TinyML中最常用的DMA模式。外设(如ADC、I2S、UART)在接收到数据后,通过硬件请求线通知DMA控制器,DMA将外设数据寄存器中的内容搬运到指定的内存缓冲区。该模式的优势在于:

  • 零CPU干预采集:CPU可以进入低功耗模式或执行其他计算,直到缓冲区填满。
  • 精确的采样时序:由外设触发DMA传输,保证采样间隔的确定性,不受中断延迟影响。
  • 支持突发传输:当FIFO积累一定数据后,DMA可以一次突发搬运多个数据,提高总线利用率。

以音频采集为例:I2S接口以16kHz采样率持续产生16位PCM数据,DMA配置为循环模式,每采集320个样本(20ms帧)触发一次中断。CPU在中断中处理当前帧,而DMA继续采集下一帧,实现无缝音频流处理。

工程经验:在配置外设到内存DMA时,务必确认外设的DMA请求映射关系。例如,STM32系列中ADC1的DMA请求可能映射到DMA1的Channel1,而I2S2则映射到DMA1的Channel4。错误的映射会导致数据错乱或DMA无法启动。

2.3 DMA与CPU中断的深度对比:何时用谁?

中断和DMA都是解决CPU与外设速度不匹配的机制,但它们的定位截然不同。中断是事件通知机制,DMA是数据搬运机制。下表从多个维度进行对比:

对比维度DMACPU中断
数据搬运主体专用硬件控制器CPU执行中断服务程序(ISR)
CPU占用配置完成后几乎为零每次中断都需保存/恢复现场
实时性硬件级响应,纳秒级启动受中断优先级和嵌套影响,微秒级
批量传输效率极高,支持突发传输低,逐字节搬运浪费总线带宽
功耗影响CPU可进入睡眠模式CPU必须频繁唤醒
适用场景高频、大批量、周期性数据低频事件、控制命令、异常处理
配置复杂度较高(需初始化DMA通道)较低(仅设置中断向量和优先级)

在实际TinyML系统中,两者通常协同工作而非互斥。典型模式是:DMA负责数据搬运,传输完成时触发一个中断,CPU在中断中仅做轻量级处理(如切换缓冲区指针、触发推理任务),而非逐字节读取数据。这种设计将CPU从繁重的数据搬运中解放出来,使其专注于推理计算和系统控制。

2.4 案例拆解:基于DMA的麦克风音频采集与推理触发

下面通过一个具体的TinyML语音唤醒词检测场景,展示DMA如何与外设采集、缓冲更新和推理触发协同工作。

系统背景与约束:

  • MCU:Cortex-M4F @ 80MHz,内置64KB SRAM
  • 音频输入:数字麦克风通过I2S接口,16kHz采样率,16位单声道
  • 推理模型:关键字识别模型,输入为20ms音频帧(320个样本),推理耗时约15ms
  • 功耗目标:平均电流<1mA(含传感器和MCU)

初始方案与问题:最初采用中断方式采集音频,每次I2S接收FIFO半满(16个样本)触发一次中断,CPU在ISR中读取数据并存入缓冲区。实测发现:

  • CPU在ISR中耗时约8μs,中断频率为1000Hz(16kHz/16),CPU占用率达10%
  • 频繁的中断导致推理任务被抢占,推理延迟抖动达到±3ms
  • CPU无法进入睡眠模式,平均功耗高达2.3mA

DMA方案设计与实施:

  1. 配置DMA1 Channel4:源地址为I2S2_DATA_DR,目的地址为audio_buf[0],传输宽度16位,传输计数320,循环模式开启。
  2. 配置双缓冲区:audio_buf[0]和audio_buf[1]各320样本(640字节),DMA交替填充。
  3. 使能DMA传输完成中断:当DMA填满一个缓冲区并切换到另一个时,触发中断。
  4. 中断服务程序精简:ISR中仅做两件事——切换当前活动缓冲区指针,并设置一个标志位通知主循环执行推理。
  5. 主循环处理:检测到标志位后,从已填满的缓冲区拷贝数据到推理输入(或直接使用DMA缓冲区地址),执行推理。

结果对比与复盘:

指标中断方案DMA方案改善幅度
CPU占用率10%1.5%↓85%
推理延迟抖动±3ms±0.2ms↓93%
平均功耗2.3mA0.8mA↓65%
代码复杂度简单中等(需配置DMA)可接受

风险与代价:DMA配置错误可能导致数据错位或总线冲突;双缓冲区需要额外640字节SRAM(占总SRAM的1%);调试DMA时序问题比中断更复杂,需要逻辑分析仪辅助。

常见误区提醒:

  • 误区1:认为DMA传输完成后数据立即可用。实际上,需要等待DMA完全停止(或使用内存屏障指令)后再访问缓冲区,否则可能读到不一致数据。
  • 误区2:忽略DMA传输宽度与外设寄存器位宽匹配。例如,16位外设配置为8位DMA传输会导致数据错位。
  • 误区3:在DMA传输过程中修改缓冲区地址或计数。这会导致未定义行为,应在DMA禁用状态下重新配置。
  • 误区4:认为DMA可以完全替代中断。DMA完成仍需中断通知CPU,且错误处理(如FIFO溢出)仍需中断介入。

2.5 总结与设计决策建议

DMA是TinyML系统中实现高效数据通路的核心硬件资源。选择DMA还是中断,应基于以下判断路径:

  • 数据速率 > 1kHz且每次传输数据量 > 4字节:优先考虑DMA。
  • 需要精确的采样间隔或低功耗运行:必须使用DMA,使CPU尽可能睡眠。
  • 事件频率低(<100Hz)且处理逻辑简单:中断即可满足需求,避免DMA配置开销。
  • 混合场景:使用DMA搬运数据,中断仅做事件通知,两者协同。