4. DMA 控制器原理
在 Bootloader 升级场景中,大量数据需要从通信接口(如 CAN、UART、SPI)搬运到 Flash 或 RAM。传统 CPU 轮询或中断方式会占用大量内核时间,导致升级速度下降。DMA(Direct Memory Access,直接存储器访问)控制器允许外设与存储器之间直接传输数据,无需 CPU 干预,是提升 Bootloader 升级性能的核心硬件基础。
4.1 DMA 基本概念
DMA 控制器是一个独立的总线主机,拥有自己的地址总线和控制逻辑。一次典型的 DMA 传输涉及以下要素:
| 要素 | 说明 | Bootloader 场景示例 |
|---|---|---|
| 源地址 | 数据读取的起始位置 | CAN 模块的接收 FIFO 地址 |
| 目的地址 | 数据写入的目标位置 | SRAM 中的临时缓冲区 |
| 传输长度 | 本次传输的字节/半字/字数 | 256 字节(一个 CAN 报文数据段) |
| 触发源 | 启动 DMA 传输的硬件事件 | CAN 接收完成中断请求 |
| 通道 | DMA 控制器内部的独立传输路径 | S32K3 支持 64 个 DMA 通道 |
S32K3 系列基于 Arm Cortex-M7 内核,集成了恩智浦增强型 eDMA(Enhanced Direct Memory Access)控制器,支持最多 64 个独立通道、16 个可编程优先级等级,以及灵活的通道链接能力。
4.2 传输模式
eDMA 支持三种核心传输模式,分别适用于不同的 Bootloader 升级子阶段:
4.2.1 单次传输模式
每次触发完成一个固定长度的数据传输后,通道自动关闭或等待重新使能。适用于一次性数据块搬运,如将单个 CAN 报文数据从接收寄存器搬入 RAM。
- 特点: 配置简单,一次触发一次完成。
- 适用场景: 小数据包、非连续传输。
- Bootloader 示例: 读取单个升级命令帧(8 字节)。
4.2.2 循环传输模式
传输完成后,源地址、目的地址和计数自动重置为初始值,通道保持使能状态,等待下一次触发。适用于周期性数据搬运,如持续从 ADC 或通信 FIFO 读取数据流。
- 特点: 无需 CPU 重新配置,自动循环。
- 适用场景: 连续数据流、环形缓冲区。
- Bootloader 示例: 持续从 CAN FIFO 搬运升级数据到 RAM 缓冲区。
4.2.3 链式传输模式
一个通道传输完成后,自动加载下一个 TCD(即下一个传输描述符),实现多个传输任务的串联执行。链式模式是 Bootloader 升级中最强大的 DMA 特性。
- 特点: 多段传输自动衔接,CPU 零干预。
- 适用场景: 复杂传输序列、多缓冲区切换。
- Bootloader 示例: 先搬运数据到 RAM,再触发 CRC 计算,最后搬运到 Flash 写入缓冲区。
4.3 传输粒度
传输粒度决定了每次 DMA 总线访问操作的数据宽度。S32K3 eDMA 支持三种粒度配置,需根据源和目的设备的位宽匹配选择:
| 粒度 | 数据宽度 | 典型外设 | Bootloader 应用建议 |
|---|---|---|---|
| 字节(8-bit) | 1 字节 | UART、SPI、I2C | 串口升级时逐字节搬运 |
| 半字(16-bit) | 2 字节 | 定时器、部分 ADC | 较少用于 Bootloader 主数据流 |
| 字(32-bit) | 4 字节 | CAN、FlexRay、内部 SRAM | CAN 升级时推荐使用,提升总线利用率 |
4.4 eDMA 传输流程与 TCD 结构
理解 TCD(Transfer Control Descriptor)是掌握 eDMA 编程的关键。每个 DMA 通道对应一个 TCD,TCD 中保存了完整的传输上下文:
/* S32K3 eDMA TCD 主要字段(简化结构) */
typedef struct {
uint32_t SADDR; /* 源地址 */
uint16_t SOFF; /* 源地址每次传输后偏移量 */
uint16_t NBYTES; /* 每次传输的字节数(minor loop) */
uint32_t DADDR; /* 目的地址 */
uint16_t DOFF; /* 目的地址每次传输后偏移量 */
uint16_t CITER; /* 当前主循环计数(major loop) */
uint32_t DLAST_SGA; /* 主循环完成后目的地址调整量 */
uint16_t BITER; /* 起始主循环计数 */
uint8_t CHANNEL_CTRL; /* 通道控制:模式、中断使能等 */
} eDMA_TCD_t;
一次完整的 eDMA 传输由两层循环构成:
- Minor Loop(小循环): 每次触发完成 NBYTES 字节的传输,源地址和目的地址按 SOFF/DOFF 递增。
- Major Loop(主循环): 完成 CITER 次小循环后,触发主循环完成事件,可产生中断或启动链式传输。
4.5 Bootloader 中的 DMA 配置要点
在 Bootloader 升级场景中配置 DMA 时,需重点关注以下参数:
- 通道优先级: 升级数据通道应设置为高优先级,避免被其他外设 DMA 请求阻塞。
- 中断使能: 仅在 Major Loop 完成时产生中断,避免 Minor Loop 频繁中断 CPU。
- 地址递增模式: 源地址(外设 FIFO)通常固定不变,目的地址(RAM 缓冲区)递增。
- 传输完成回调: 在中断服务函数中启动下一段传输或通知 Bootloader 主状态机。