2. S32K3 DMA控制器架构:DMA模块内部结构、通道、传输请求、源/目标地址、传输宽度与突发大小

S32K3系列MCU集成了增强型DMA控制器(eDMA),其设计旨在高效处理大量数据搬移任务,无需CPU持续干预。理解其内部架构是进行RTD驱动配置与项目移植的基础。本章将深入剖析DMA模块的核心组件、传输机制与关键参数。

2.1 DMA模块内部结构

S32K3的eDMA控制器由两个主要引擎构成:传输引擎(Transfer Engine, TE)和通道仲裁引擎(Channel Arbitration Engine, CAE)。它们协同工作,实现从请求到传输完成的完整流程。

核心组件:
  • DMA通道(DMA Channel):每个通道包含一组寄存器(源地址、目标地址、传输控制描述符TCD),用于定义一次完整的DMA传输任务。
  • 传输控制描述符(TCD):通道的核心数据结构,存储了传输的所有配置信息,包括地址、传输大小、偏移量、链接通道等。
  • 通道仲裁引擎(CAE):当多个通道同时请求服务时,CAE根据优先级(固定优先级或轮询)选择下一个执行的通道。
  • 传输引擎(TE):实际执行数据搬移的硬件单元,负责从源地址读取数据并写入目标地址。
  • DMA请求多路选择器(DMAMUX):将外设的DMA请求信号(如ADC转换完成、LPUART接收数据)路由到指定的DMA通道。
S32K3 eDMA控制器内部架构 S32K3 eDMA控制器内部架构 外设请求 软件触发 DMAMUX 请求路由 通道仲裁引擎 (CAE) 优先级裁决 传输引擎 (TE) 数据搬移执行 TCD寄存器组 (通道0-N) 系统总线 (SRAM/Flash/外设) 说明: 1. 外设请求经DMAMUX路由至指定DMA通道。 2. CAE根据优先级选择通道,TE读取对应TCD执行数据搬移。

2.2 DMA通道与传输请求

每个DMA通道都对应一个唯一的TCD,TCD定义了传输的全部细节。传输请求是启动DMA传输的触发信号。

2.2.1 通道特性

  • 通道数量:S32K3系列根据具体型号,通常提供16至64个DMA通道。
  • 通道优先级:支持固定优先级(Fixed Priority)和轮询优先级(Round-Robin Priority)两种仲裁模式。
  • 通道链接:一个通道传输完成后,可以自动触发另一个通道(Minor Loop或Major Loop链接),实现复杂的数据处理链。

2.2.2 传输请求类型

请求类型 触发源 典型应用场景
外设硬件请求 外设模块(ADC、LPUART、SPI、定时器等) ADC转换结果搬移、UART接收FIFO数据读取
软件触发请求 CPU通过写寄存器启动 内存到内存拷贝、初始化数据块
链式触发请求 其他DMA通道传输完成事件 多通道级联传输、乒乓缓冲切换
移植要点:在从S32K1移植到S32K3时,需注意DMAMUX的配置方式不同。S32K3的DMAMUX支持更灵活的触发源选择和同步功能,RTD驱动中通过 Dma_Ip_Init() 和 Dma_Ip_ConfigChannel() 进行配置。

2.3 源/目标地址与传输宽度

DMA传输的核心是定义数据从哪里来(源地址),到哪里去(目标地址),以及每次传输多少数据(传输宽度)。

2.3.1 地址配置

  • 源地址(Source Address):数据读取的起始地址。可以是外设数据寄存器地址或内存地址。
  • 目标地址(Destination Address):数据写入的起始地址。可以是内存地址或外设数据寄存器地址。
  • 地址偏移(Address Offset):每次传输后,源地址和目标地址的更新方式。支持固定地址(用于外设FIFO)、递增地址(用于内存缓冲区)或递减地址。

2.3.2 传输宽度(Transfer Width)

传输宽度定义了单次总线访问的数据大小。S32K3 eDMA支持以下宽度:

宽度枚举 数据大小 典型用途
DMA_TRANSFER_WIDTH_8BIT 1字节(8位) UART字符传输、8位外设寄存器访问
DMA_TRANSFER_WIDTH_16BIT 半字(16位) 定时器捕获值、16位ADC数据
DMA_TRANSFER_WIDTH_32BIT 字(32位) 内存拷贝、32位外设寄存器(如SPI FIFO)
对齐要求:源地址和目标地址必须与传输宽度对齐。例如,32位传输要求地址按4字节对齐。未对齐的访问可能导致总线错误或数据损坏。在RTD配置中,需确保 SrcAddr 和 DestAddr 满足对齐约束。

2.4 突发大小(Burst Size)

突发大小定义了DMA在一次总线仲裁周期内连续传输的数据单元数量。合理配置突发大小可以显著提高总线利用率和传输效率。

2.4.1 突发大小与传输循环

DMA传输分为两个循环层次:

  • Minor Loop(小循环):一次突发传输完成的数据量。由 NBYTES 寄存器中的 SMOD 和 SSIZE/DSIZE 共同决定。
  • Major Loop(大循环):整个DMA传输任务完成的数据量。由 CITER(当前迭代次数)和 BITER(起始迭代次数)控制。

突发大小与传输宽度的关系如下:

突发大小(Burst Size) 含义 示例(传输宽度=32位)
1 单次传输 每次传输4字节
4 4次突发 一次仲裁传输16字节
8 8次突发 一次仲裁传输32字节
16 16次突发 一次仲裁传输64字节
DMA突发传输与循环结构 DMA突发传输与循环结构 Major Loop (大循环: 总传输量 = CITER × NBYTES) Minor Loop 1 突发大小 × 传输宽度 (如: 4 × 32bit = 16字节) Minor Loop 2 突发大小 × 传输宽度 (如: 4 × 32bit = 16字节) Minor Loop N 突发大小 × 传输宽度 (如: 4 × 32bit = 16字节) 关键参数关系: 总传输量 = CITER × NBYTES = CITER × (Burst Size × Transfer Width) 例如:CITER=10, Burst Size=4, Transfer Width=32bit → 总传输量 = 10 × 16字节 = 160字节

2.5 关键参数配置示例(RTD驱动)

以下代码片段展示了在RTD驱动中如何配置DMA通道的源地址、目标地址、传输宽度和突发大小:

// 使用RTD API配置DMA通道
Dma_Ip_ConfigChannel(DMA_INSTANCE, DMA_CHANNEL_0, &dmaChannelConfig);

// 假设dmaChannelConfig结构体定义如下:
dmaChannelConfig.transferSize = DMA_TRANSFER_SIZE_32BIT;   // 传输宽度:32位
dmaChannelConfig.srcAddr = (uint32_t)&ADC0->R[0];          // 源地址:ADC结果寄存器
dmaChannelConfig.destAddr = (uint32_t)&adcBuffer[0];       // 目标地址:内存缓冲区
dmaChannelConfig.srcOffset = 0;                            // 源地址不递增(外设固定地址)
dmaChannelConfig.destOffset = 4;                           // 目标地址每次递增4字节
dmaChannelConfig.minorLoopBytes = 16;                      // 小循环字节数:16字节
dmaChannelConfig.majorLoopCount = 100;                     // 大循环次数:100次
// 注意:minorLoopBytes / transferSize = 16 / 4 = 4,即突发大小为4
移植经验:
  • 在配置 minorLoopBytes 时,必须确保其值是传输宽度的整数倍,且不超过TCD中 NBYTES 字段的最大值(通常为1024字节)。
  • 对于外设到内存的传输,源地址通常设置为不递增(srcOffset = 0),目标地址递增;内存到外设则相反。
  • 突发大小不宜过大,否则会长时间占用总线,影响其他高优先级任务(如中断响应)。建议根据系统实时性要求进行权衡。