1 简介
1.1 DMA系统框图
首先一起来看看S32K3XX
单片机DMA
系统的庐山真面目
从上图中可以看出,eDMA
主要由两部分构成,一部分是 eDMA引擎,负责仲裁,控制,数据传输等工作;另一部分是传输控制描述符,存储了各个通道操作所需的属性数据,比方说,传输数据的源地址,目的地址等。整个系统设计得精巧而优雅。
eDMA引擎主要有两个功能:
地址计算
数据传输
传输控制描述符主要负责32个通道中每个通道传输控制描述符的存储。
1.2 各模块简介
Address path
- 第一通道和第二通道(抢占通道)的
TCD
保存 - 管理所有主机总线的地址计算
允许一个通道在数据完成读写任务时被抢占。
当一个通道被激活的时候,它会一直运行直到小循环完成,除非被一个更高优先级的通道抢占。
当选择执行任何通道时,将从本地内存中读取其TCD的内容,并将其加载到地址路径通道x寄存器中进行正常启动,并将其加载到通道y寄存器中进行抢占启动。在小循环完成执行后,地址路径硬件将TCDn_{SADDR, DADDR, CITER}的新值写回本地内存。如果主迭代(大循环)计数耗尽,则执行额外的处理,包括最终地址指针更新,重新加载TCDn_CITER字段,以及作为分散/收集操作的一部分可能从内存中获取新的TCDn。有关详细信息,请参考动态分散/收集(Dynamic scatter/gather)部分。
Data path
这个模块实现了总线主读/写数据路径。它包含一个数据缓存和必要的复杂逻辑来支持任何需要进行的数据对齐。内部的读数据总线是主输入,内部的写数据总线是主输出。
地址和数据路径模块可直接支持两级流水式内部总线。地址路径模块代表了第一级流水式总线,数据路径模块代表了第二级流水式总线。
Program model/channel arbitration
该模块实现了eDMA
编程模型的第一部分以及通道仲裁逻辑。可编程的模块寄存器与内部的外设总线相连。eDMA
的外设请求输入和中断请求输出也可以通过这个模块相连。
传输控制描述符(TCD
)可分成两部分:Memory controller和Memory array
Memory controller
该逻辑实现了所需的双端口控制器,并管理来自eDMA
引擎的访问以及来自内部外围总线的引用。如前所述,在同步访问中,eDMA
引擎被赋予优先级,外围事务被停止。
Memory array
TCD
存储的用于每个通道的传输配置文件。也就是所要执行的通道数据的各种相关信息。
1.3 特点
eDMA是一种高度可编程的数据传输引擎,可以最大限度地减少主机处理器所需的任何干预,eDMA模块具有以下特点:
- 所有的数据移动都通过双地址传输:从数据的源头读出到目标写入
— 可编程的源地址和目标地址以及传输大小
— 支持复杂地址计算 - 在最少干预主机处理器的前提下,实现了32通道的复杂数据传输。
— 内部数据buffer,被用作所有数据传输的临时存储器
— 连接到 crossbar switch,以控制总线的数据移动 - TCD支持两层深的嵌套传输操作
— 每个通道的32字节TCD保存
— 由小字节传输计数定义的内部数据传输循环
— 由主迭代计数定义的外部数据传输循环 - 可通过三种方法让通道处于活动状态
— 直接软件初始化
— 通过连续转换中的通道连接机制进行初始化
— 每个通道一个Peripheral-paced
的硬件请求 - 固定优先级和轮询通道仲裁
- 通过可编程中断请求报告通道完成情况
— 每个通道都可以独立产生中断,可以在主循环计数完成时产生断言
— 每个通道的可编程错误结果,被逻辑地加在一起形成一个中断控制器的错误中断 - 可编程支持分散/收集DMA处理
- 支持复杂数据结构
2 工作流程概述
2.1 基本工作流程
2.1.1 通道激活
本例使用eDMA外设请求信号的断言来请求通道n的服务。通过软件和TCDn_CSR[START]
字段激活通道遵循与外设请求相同的基本流程(也就是说,软件和硬件的通道激活方式基本一致)。
eDMA
请求输入信号在内部注册,然后通过eDMA
引擎:首先通过控制模块,然后进入程序模块和通道仲裁。
在下个周期中,通道仲裁采用固定优先级和可选的循环算法进行仲裁。在仲裁执行完毕后,激活的通道号通过地址路径发送,并转换为访问TCDn本地存储器所需的地址,接下来,访问TCD
内存,并从本地内存读取所需的描述符,然后将其加载到eDMA
引擎地址路径的主通道或辅助通道执行寄存器中。TCD
内存为64
位宽,以尽量减少获取激活通道描述符并将其加载到地址路径寄存器所需的时间。
2.1.2 数据传输(数据流动)
与数据传输相关的模块(地址路径、数据路径和控制)通过所需的源读取和目标写入序列来执行实际的数据移动。源读取被启动,获取的数据被临时存储在数据路径块中,直到在目标写入期间将其传输到内部总线上。这个从源头读取/从目标写入操作一直持续到字节数(NBYTES
)传输结束。
2.1.3 更新内存,申请中断
搬运NBYTES
的数据后,执行基本数据流的最后阶段。在此段中,地址路径逻辑对一些TCD
中的某些字段(例如,SADDR
、DADDR
、CITER
)执行所需的更新。
如果主要迭代(大循环)计数耗尽,则执行额外的操作。这包括最后的地址调整和将BITER
字段重新加载到CITER字段中。此时还会发生可选中断请求的断言,以及使用描述符中包含的scatter
/gather
地址指针(如果启用了scatter
/gather
)从内存中取出一个新的TCD
。TCD
内存的更新和中断请求的断言显示在上面的图中。
注:相关寄存器/字段解释
NBYTES:TCD Transfer Size
定义了每次DMA请求需要搬运的字节数
BITER:TCD Beginning Major Loop Count
通道最开始设定的主循环次数
CITER :Current Major Iteration Count
通道的当前主循环计数。每次通道完成一个服务请求并将其写回TCD内存时,它都会减少
2.2 故障报告和处理
通道错误在错误状态寄存器(CHn_CSR
和TCDn_CSR
)中报告,可能由以下任何一种原因引起:
- 配置错误,传输控制描述符中的某些/个设置是非法的
- 通过“ 错误取消传输”的硬件或软件请求 取消已经被激活的通道
- TCD内存错误
- 总线主机读或写周期的错误终止
而当报告配置错误时,可能由下面这些因素的状态不一致引起的:
- 起始地址或者目的地址
- 起始或目的地址偏移
- 小循环字节计数
- 传输大小
造成这些错误的原因可能源于以下几个方面:
- 地址和偏移必须与零模传输大小的边界对齐
- 小循环的计数大小必须起始和目的传输大小的整数倍
- 所有源读取和目标写入都必须配置为程序传输大小的自然边界
- 如果一个分散/收集操作在通道完成时使能,但分散/收集地址(
DLAST_SGA
)没有对齐到32字节的边界,这时候就会报告配置错误。 - 如果在通道完成时使能小环路通道连接,如果
TCDn_CITER[ELINK]
字段不等于TCDn_BITER[ELINK]
字段,则在尝试连接时报告配置错误。
2.3 通道抢占
- 通道抢占允许在更高优先级的通道请求数据传输的时候,当前通道被挂起;
- 不支持嵌套抢占,也就是说,已经抢占的通道,不能被抢占;
- 通道的抢占被禁用时,失去了抢占功能,即使是优先级更低的通道,依然不能被抢占;
- 为了避免相互占用,可以都设置为低优先级(也就是
0
)。
3 核心原理
3.1 大循环和小循环
下图显示了每个DMA请求如何启动一个小循环传输,或者迭代。DMA仲裁可在每个小循环后发生,并且允许一个级别的小循环DMA
抢占。大循环中的小循环的数量由开始迭代计数(BITER
)指定。
其实大循环和小循环的很多属性都可以很灵活地进行配置,详情请移步4.1小节。
3.2 eDMA仲裁机制简介
eDMA
由多个优先级组成分层仲裁方案。采用固定优先级仲裁,在特定条件下也可以选择轮询仲裁。优先级顺序如下图所示:
仲裁组优先:每个通道都可以通过配置 CHn_GRPRI
寄存器来设置通道优先级,总共有32
个优先级(0-31
),数值越大,优先级越高。
通道优先:每个通道都可以通过配置 CHn_PRI
寄存器来设置通道优先级,总共有8
个优先级(0-7
),数值越大,优先级越高。
通道数(通道编号):当两个及其以上的通道有相同的仲裁组优先级和通道优先级的时候,就需要通过通道编号来区分优先级,通道编号越高,优先级越高,不可自定义。
轮询:启用轮询时,任何配置了轮询的通道操作在仲裁组中优先级最低。通过将CSR[ERCA]
字段设置为1
来启用轮询。启用后,通道优先级为0 (CHn_PRI=0)
的通道将被使用轮询仲裁。轮循仲裁将在仲裁组中请求服务的通道(CHn_PRI=0)
之间轮换通道选择。如果请求服务将在任何循环通道中被选择,仲裁组内的任何非零通道将继续使用固定优先级仲裁。
任何通道优先级大于0
的通道都会在循环之前得到服务。
3.2.1 固定组仲裁,固定通道仲裁
在该模式下,eDMA
从最高优先级组中最高优先级的通道中选择执行通道业务请求。如果对eDMA
进行编程,使高优先级组内的通道具有大量请求或大量数据传输,则该组可能会消耗eDMA
控制器的所有带宽。也就是说,如果在控制器仲裁下一个DMA
请求时,在最高优先级组中的通道上总是有至少一个DMA
请求待处理,则不会为低优先级组提供服务DMA
请求。这种方案的优点是:通道的延迟可能很小。
3.2.2 固定组仲裁,轮询通道仲裁
请求的优先级最高的组先得到服务。如果高优先级组中不存在挂起请求,则为低优先级组提供服务。
在组内,非零通道优先级的通道优先得到服务。对于所有优先级为0
的通道,优先选择通道编号较高的请求进行服务,然后一次到请求服务的最低通道。通道仲裁可以为低优先级通道提供一种公平机制。
这种方案可能引起与固定组仲裁,固定通道仲裁相同的带宽消耗问题,最高优先级组中的所有通道都将得到服务。最高优先级组上的服务延迟很短,但随着组优先级的降低,服务延迟可能会长得多。