4. DMA 传输模式详解:单次传输、循环传输、块传输、链式传输(Linked Transfer)及其应用场景
S32K3 的 eDMA(增强型直接存储器访问)控制器支持多种传输模式,以满足不同外设与内存之间的数据搬运需求。理解这些模式的区别与适用场景,是进行 DMA 驱动配置与 RTD 协同设计的基础。本章将逐一剖析四种核心传输模式:单次传输、循环传输、块传输以及链式传输(Linked Transfer)。
核心概念: 在 S32K3 RTD 驱动中,DMA 传输的基本单元是“传输请求”(Transfer Request, TDR)。一次传输请求可以包含一个或多个“传输块”(Block),每个传输块又由多个“传输节拍”(Beat)组成。不同的传输模式本质上是对这些层次结构的不同组织与调度方式。
4.1 单次传输(Single Transfer)
定义: 单次传输是最基本的 DMA 操作模式。当触发事件(如 ADC 转换完成、UART 接收标志置位)到来时,DMA 控制器执行一次预定义的传输操作,将指定数量的数据从源地址搬运到目的地址,然后停止,等待下一次触发。
特点:
- 一次性: 每次触发只完成一个传输块(Block)的搬运。
- 自动停止: 传输完成后,通道自动关闭或进入空闲状态,除非再次手动使能。
- 配置简单: 适用于数据量固定、触发频率可控的场景。
应用场景:
- 单次 ADC 采样结果读取: 用户按下按钮触发一次 ADC 转换,DMA 将单个结果搬运到内存变量。
- UART 单字节发送/接收: 在低数据率或命令响应模式下,每次中断触发搬运一个字节。
- 系统初始化时的数据拷贝: 将固件版本信息或校准参数从 Flash 拷贝到 RAM。
RTD 配置提示: 在 RTD 的 DMA 配置工具中,将
Transfer Mode 设置为 Single,并设置 Major Loop Count 为 1。注意检查 Channel Link Control 是否被禁用。
4.2 循环传输(Circular Transfer)
定义: 循环传输模式允许 DMA 在完成一个传输块后,自动将源地址或目的地址(通常是目的地址)重置回缓冲区的起始位置,形成一个环形缓冲区。传输可以无限循环进行,无需 CPU 干预。
特点:
- 自动回绕: 地址指针到达缓冲区末尾后自动跳转到开头。
- 持续运行: 一旦启动,只要触发源持续有效,传输就会一直进行。
- 缓冲区管理: 通常与“水印”或“半满”中断配合,通知 CPU 处理已填满的半区数据。
应用场景:
- 音频流播放/录制: 音频数据连续不断地从麦克风(通过 I2S)搬运到内存缓冲区,或从缓冲区搬运到扬声器。
- 高速 ADC 连续采样: 电机控制或电源管理中的电流/电压连续采样,数据循环存入 RAM。
- UART 环形 FIFO 实现: 接收中断频繁时,DMA 将数据循环写入一个软件环形缓冲区。
避坑指南: 循环传输模式下,务必确保缓冲区大小是传输块大小的整数倍,否则地址回绕时可能出现数据错位。同时,CPU 读取缓冲区数据时需注意“读写指针冲突”,建议使用原子操作或双缓冲机制。
4.3 块传输(Block Transfer)
定义: 块传输模式允许在一次触发事件中,连续传输多个“传输节拍”(Beat),构成一个完整的“传输块”(Block)。块的大小(即节拍数)可以在配置时设定。与单次传输相比,块传输在一次触发下搬运的数据量更大。
特点:
- 批量搬运: 一次触发完成一个数据块的传输,效率高于单次传输。
- 可配置块大小: 块大小可以是 1 到 1024 个节拍(取决于具体 eDMA 引擎配置)。
- 中断可选: 可以在块传输完成后产生中断,也可以在每次节拍完成后产生中断(较少用)。
应用场景:
- SPI 数据帧传输: 一次触发传输一个完整的 SPI 数据帧(例如 16 字节)。
- 显示缓冲区刷新: 将一行像素数据从内存搬运到显示控制器。
- CAN 报文收发: 将整个 CAN 报文(8 字节数据)从 RAM 搬运到 CAN 控制器发送缓冲区。
| 特性 | 单次传输 | 块传输 |
|---|---|---|
| 触发一次搬运量 | 1 个节拍(Beat) | N 个节拍(Block) |
| 总线占用 | 低,分散 | 高,集中 |
| CPU 中断频率 | 高(每次传输都中断) | 低(每块传输中断一次) |
| 适用数据量 | 小(1~4 字节) | 中等(4~1024 字节) |
| 典型外设 | UART 单字节、GPIO | SPI 帧、I2C 包、ADC 序列 |
RTD 配置提示: 在 RTD 中配置块传输时,需要设置
Minor Loop Count(每个块内的节拍数)和 Major Loop Count(块的数量)。对于单次块传输,Major Loop Count 通常设为 1。
4.4 链式传输(Linked Transfer)
定义: 链式传输(也称为“DMA 链接”或“通道链接”)是 S32K3 eDMA 的高级特性。它允许将一个 DMA 通道的传输完成事件作为另一个 DMA 通道的触发源,从而形成一条“传输链”。当第一个通道完成其传输任务后,自动启动第二个通道,第二个完成后启动第三个,以此类推。
特点:
- 自动级联: 无需 CPU 介入,DMA 通道之间自动顺序执行。
- 复杂传输序列: 可以实现“先搬运描述符,再搬运数据”、“先配置外设,再传输数据”等多步操作。
- 灵活配置: 每个通道可以有自己的源地址、目的地址、传输大小和传输模式。
应用场景:
- 多缓冲区分步传输: 先传输缓冲区 A,完成后自动切换到缓冲区 B 进行传输。
- 协议处理: 先通过 DMA 发送命令头(通道 0),完成后自动触发发送数据负载(通道 1)。
- 乒乓缓冲(Ping-Pong Buffer): 通道 0 负责填充 Ping 缓冲区,完成后链接到通道 1 处理 Ping 数据,同时通道 0 自动重载配置去填充 Pong 缓冲区。
避坑指南: 链式传输配置时需注意“链接中断”的处理。如果通道 0 完成中断被使能,中断服务程序可能会在通道 1 启动前执行,导致时序问题。建议仅在链的最后一个通道使能中断,或使用“中断链接”而非“启动链接”。
4.5 四种模式对比与选型建议
| 模式 | 触发一次搬运量 | 自动重复 | 通道链接 | CPU 负载 | 典型应用 |
|---|---|---|---|---|---|
| 单次传输 | 1 个节拍 | 否 | 否 | 高(中断频繁) | UART 单字节、GPIO 事件 |
| 循环传输 | 1 个块 | 是(地址回绕) | 否 | 低(半满中断) | 音频流、连续 ADC 采样 |
| 块传输 | N 个节拍 | 否 | 否 | 中(每块中断) | SPI 帧、显示刷新 |
| 链式传输 | 可变(多通道) | 是(通道级联) | 是 | 极低(链尾中断) | 乒乓缓冲、协议处理 |
选型建议:
- 如果数据量小且触发频率低,优先选择单次传输,配置简单。
- 如果需要连续、不间断的数据流,且数据需要循环覆盖,选择循环传输。
- 如果一次触发需要搬运一批数据,且数据量适中,选择块传输。
- 如果需要执行一系列不同的 DMA 操作,且希望完全自动化,选择链式传输。
在实际的 S32K3 项目中,这四种模式往往不是孤立使用的。例如,一个复杂的音频处理任务可能使用循环传输进行数据采集,同时使用链式传输在采集完成后自动启动数据处理通道。理解每种模式的本质,是灵活运用 RTD 驱动进行 DMA 协同设计的关键。