S32K3XX单片机DMA原理深度解析(下)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: S32K3XX单片机DMA原理深度解析(下)

4 相关操作

4.1 执行DMA转换

4.1.1 单次请求

比方说,我们需要传输16个字节的数据。eDMA可编程为一个大循环,每次传输16字节。在源内存有个1字节宽度的内存接口,地址为0x1000。数据终点地址为0x2000,有32位的接口。地址偏移量以增量方式编程以匹配传输大小,读取四次数据,才会写一次数据。相关配置程序如下:

TCDn_CITER = TCDn_BITER = 1
TCDn_NBYTES = 16
TCDn_SADDR = 0x1000
TCDn_SOFF = 1
TCDn_ATTR[SSIZE] = 0
TCDn_SLAST = -16
TCDn_DADDR = 0x2000
TCDn_DOFF = 4
TCDn_ATTR[DSIZE] = 2
TCDn_DLAST_SGA= –16
TCDn_CSR[INTMAJ] = 1
TCDn_CSR[START] = 1 (should be written last after all other fields have been initialized)
All other TCDn fields = 0

以上的配置,会按照如下顺序执行:

  1. 用户将TCDn_CSR[START]写入数据进行通道服务请求
  2. 通过通道仲裁后,该通道被选择
  3. eDMA引擎写入:
CHn_CSR[DONE] = 0 
 TCDn_CSR[START] = 0  
 CHn_CSR[ACTIVE] = 1
  1. eDMA引擎读取:从局部内存中读取通道的TCD数据到内部寄存器文件
  2. 从源头到终点的传输流程如下:
    0x10000x10010x10020x1003各读取一个字节的数据。
    写32位的数据到0x2000,进行小循环第一次迭代
    0x10040x10050x10060x1007各读取一个字节的数据。
    写32位的数据到0x2004,进行小循环第二次迭代
    0x10080x10090x100A0x100B各读取一个字节的数据。
    写32位的数据到0x2008,进行小循环第三次迭代
    0x100C0x100D0x100E0x100F各读取一个字节的数据。
    写32位的数据到0x200C,进行小循环第四次迭代,大循环迭代完成
  3. eDMA引擎写入:TCDn_SADDR = 0x1000, TCDn_DADDR = 0x2000, TCDn_CITER = 1 (TCDn_BITER)
  4. eDMA引擎写入:CHn_CSR[ACTIVE] = 0, CHn_CSR[DONE] = 1, CHn_INT[INT] = 1
  5. 通道退出,eDMA进入空闲状态,或者服务下一个通道。

具体流程大致如下图所示:

4.1.2 多次请求

如果说我们需要搬运32字节的数据,这个时候就需要两次硬件请求,其他都和上述的单次请求一致。这个时候我们只需要修改主循环的次数和最后的地址偏移。变成两次主循环,每次搬运16字节数据,最后我们通过CHn_CSR[ERQ]寄存器字段使能硬件请求,可初始化从机的通道服务请求。配置如下:

TCDn_CITER = TCDn_BITER = 2
TCDn_SLAST = –32
TCDn_DLAST_SGA = –32

执行的基本流程如下:

  1. 第一个硬件通道请求
  2. 通过通道仲裁后,该通道被选择
  3. eDMA引擎写入:
CHn_CSR[DONE] = 0 
 TCDn_CSR[START] = 0  
 CHn_CSR[ACTIVE] = 1
  1. eDMA引擎读取:从局部内存中读取通道的TCD数据到内部寄存器文件
  2. 从源头到终点的传输流程如下:
    0x10000x10010x10020x1003各读取一个字节的数据。
    写32位的数据到0x2000,进行小循环第一次迭代
    0x10040x10050x10060x1007各读取一个字节的数据。
    写32位的数据到0x2004,进行小循环第二次迭代
    0x10080x10090x100A0x100B各读取一个字节的数据。
    写32位的数据到0x2008,进行小循环第三次迭代
    0x100C0x100D0x100E0x100F各读取一个字节的数据。
    写32位的数据到0x200C,小循环迭代完成
  3. eDMA引擎写入:TCDn_SADDR = 0x1010, TCDn_DADDR = 0x2010, TCDn_CITER = 1
  4. eDMA引擎写入:CHn_CSR[ACTIVE] = 0
  5. 通道退出,主循环的一次迭代结束,eDMA进入空闲状态,或者服务下一个通道。
  6. 第二个硬件通道请求
  7. 通过通道仲裁后,该通道被选择
  8. eDMA引擎写入:
CHn_CSR[DONE] = 0 
 TCDn_CSR[START] = 0  
 CHn_CSR[ACTIVE] = 1
  1. eDMA引擎读取:从局部内存中读取通道的TCD数据到内部寄存器文件
  2. 从源头到终点的传输流程如下:
    0x10100x10110x10120x1013各读取一个字节的数据。
    写32位的数据到0x2010,进行小循环第一次迭代
    0x10140x10150x10160x1017各读取一个字节的数据。
    写32位的数据到0x2014,进行小循环第二次迭代
    0x10180x10190x101A0x101B各读取一个字节的数据。
    写32位的数据到0x2018,进行小循环第三次迭代
    0x101C0x101D0x101E0x101F各读取一个字节的数据。
    写32位的数据到0x201C,进行小循环第四次迭代,大循环完成
  3. eDMA引擎写入:TCDn_SADDR = 0x1000, TCDn_DADDR = 0x2000, TCDn_CITER = 2 (TCDn_BITER)
  4. eDMA引擎写入:CHn_CSR[ACTIVE] = 0, CHn_CSR[DONE] = 1, CHn_INT[INT] = 1
  5. 通道退出,主循环结束,eDMA进入空闲状态,或者服务下一个通道。

具体流程大致如下图所示:

4.2 监视描述符状态

4.2.1 测试小循环是否完成

两种方法可以测试小循环(次循环)的状态

  1. 读取TCDn_CITER字段,并测试其是否有更改
  2. 读取下表相应字段,根据数值判断状态

    当使用硬件发起的(即外设发起的)服务请求时,测试小循环完成的最佳方法是读取TCDn_CITER字段并测试更改。硬件请求和确认握手信号在程序员的模型中是不可见的。
    TCD状态字段为硬件激活的通道执行以下序列:

4.2.2 读取激活通道的传输描述符状态

如果在通道执行时读取TCDn_SADDRTCDn_DADDRTCDn_NBYTES的值,eDMA将回读它们的真实值。SADDRDADDRNBYTES的真实值是eDMA引擎当前在其内部寄存器文件中使用的值,而不是该通道的TCD本地内存中的值。

4.2.3 检查通道抢占状态

抢占的情况是启用了抢占的通道正在执行,而高优先级的请求变为活动的情况。

启用轮循仲裁模式时,通道优先级为0的优先级被视为相等,即不断轮换。

被抢占通道的CHn_CSR[ACTIVE]字段在整个抢占过程中保持断言。当抢占通道执行一次主循环迭代时,被抢占的通道被暂时挂起。如果在全局TCD映射中同时设置了两个CHn_CSR[ACTIVE]字段,则高优先级通道正在主动抢占低优先级通道。

4.3 通道连接(通道链接)

通道连接(或链接)是一种机制,其中一个通道设置另一个通道(或其自身)的TCDn_CSR[START]字段,从而为该通道发起服务请求。在配置得当时,eDMA引擎会在大循环或小循环完成时自动执行此操作。

注:相关寄存器/字段解释

START:如果此标志为1,则通道正在请求服务。eDMA硬件在通道开始执行后自动将此标志清除为0

小循环通道连接发生在小循环(或大循环的一次迭代)完成时。TCDn_CITER[ELINK]字段决定是否请求小环路连接。启用后,除了最后一次迭代之外,每次大循环迭代之后都会建立通道链接。当主环路耗尽时,仅使用大环路通道link字段来确定是否应该建立通道链路。例如,若采用如下配置:

TCDn_CITER[ELINK] = 1
TCDn_CITER[LINKCH] = 0xC
TCDn_CITER[CITER] value = 0x4
TCDn_CSR[MAJORELINK] = 1
TCDn_CSR[MAJORLINKCH] = 0x7

则执行过程如下:

小循环完成——>设置TCD12_CSR[START]字段

小循环完成——>设置TCD12_CSR[START]字段

小循环完成——>设置TCD12_CSR[START]字段

小循环完成,大循环完成——>设置TCD7_CSR[START]字段

注:相关寄存器/字段解释

TCDn_CITER[CITER]:Current Major Iteration Count

表示通道的当前主循环计数。每次通道完成一个服务请求并将其写回TCD内存时,它都会减少。

从以上配置来看,一个大循环包含了四个小循环。

下面的表格总结了一个DMA通道如何连接到其他DMA通道,也就是在一次循环结束后,使用其他通道的TCD

4.4 动态程序设计

在通道的执行过程中,也可以改变eDMA的一些配置。

4.4.1 动态改变通道优先级

若想改变或者通道的优先级可以这样做:

  • 通过将CSR[HALT]字段写1来终止DMA写入
  • 改变想改变的组或者通道的优先级
  • 通过将CSR[HALT]字段写0来重新启动DMA操作

4.4.2 动态通道连接(动态通道链接)

动态通道连接是通设置TCDn_CSR[MAJORELINK]字段来实现的,这个字段从TCD的局部内存中读取的,因此可以在DMA通道运行的时使用该特性。为了保险起见,建议采用下面的步骤。

  1. TCDn_CSR[MAJORELINK]字段写1
  2. 读取TCDn_CSR[MAJORELINK]字段的值
  3. 测试TCDn_CSR[MAJORELINK]请求状态
    如果为1,则动态连接尝试成功
    如果为0,则动态连接尝试失败

4.4.3 动态分散/聚集

自动加载一个新的TCD到一个通道,允许同时使用多个TCD,然后进行多个DMA数据的搬运。

有两种方法可以实现动态分散/聚集

Method 1 (不使用大循环连接

如果通道没有使用大循环连接,则可以使用动态分散/收集请求。

Method 2 (使用大循环连接

如果通道使用了大循环连接,则仍然可以使用动态分散/收集请求。此方法使用TCDn_DLAST_SGA字段作为TCD的标识。

注:字段/寄存器解释

TCDn_DLAST_SGA :TCD Last Destination Address Adjustment / Scatter Gather Address

调整要加载到此通道的下一个传输控制描述符的最后一个目标地址或内存地址。

4.5 挂起/重启一个已经激活的通道

挂起一个被激活的通道:

  1. 停止其DMA请求服务;
  2. 通过读取DMAHardware Request Status (HRS)确保没有服务请求的通道被挂起。

如果需要挂起一个DMA/DSPI传输环路。需要执行以下步骤:

  1. 通过将DSPI_RSER[TFFF_RE]字段置0来禁用中断服务请求。
  2. 验证DSPI_RSER[TFFF_RE]0,确保没有来自DSPIDMA服务请求被执行。如果没有被执行,则通过将ERQ字段置零来禁用硬件服务请求。

注:相关术语解释

DSPI :Dual Serial Peripheral Interface(不能100%确实是这个意思)

双线串行外设接口

我们发现标准SPI通信时发送和接收时主机和从机都只能使用自己的那根数据线进行数据传输,Dual SPI无论是接收还是发送都是使用两根数据线进行的,所以单向数据传输速度上是标准SPI的双倍。

关于什么是标准的SPI通信,可以看这篇帖子:SPI通信协议详解

5 后记

通道仲裁的基本逻辑与《操作系统》中的调度算法非常类似,相关内容可以看这篇帖子:《操作系统》第二章 2.2处理机调度

没有比人更高的山,没有比脚更长的路。在学习eDMA的过程中,遇到了比较多的困难,关于这种特殊的DMA网上的资料并不多,只能硬着头皮去看官网的文档,一点一点地分析,比较,推理。但这也是一条充满乐趣的道路!

------------------------------------------------------------------------END------------------------------------------------------------------------

相关文章
|
17天前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
35 3
|
5天前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
15 1
|
10天前
|
数据采集 存储 编解码
一份简明的 Base64 原理解析
Base64 编码器的原理,其实很简单,花一点点时间学会它,你就又消除了一个知识盲点。
37 3
|
21天前
|
网络协议 数据格式
【通信协议讲解】单片机基础重点通信协议解析与总结之ModBus(五)
【通信协议讲解】单片机基础重点通信协议解析与总结之ModBus(五)
|
21天前
|
IDE 开发工具
【通信协议讲解】单片机基础重点通信协议解析与总结之CAN(四)
【通信协议讲解】单片机基础重点通信协议解析与总结之CAN(四)
|
21天前
【通信协议讲解】单片机基础重点通信协议解析与总结之串口通信(三)
【通信协议讲解】单片机基础重点通信协议解析与总结之串口通信(三)
|
21天前
【通信协议讲解】单片机基础重点通信协议解析与总结之SPI(二)
【通信协议讲解】单片机基础重点通信协议解析与总结之SPI(二)
|
7天前
|
供应链 安全 分布式数据库
探索区块链技术:从原理到应用的全面解析
【10月更文挑战第22天】 本文旨在深入浅出地探讨区块链技术,一种近年来引起广泛关注的分布式账本技术。我们将从区块链的基本概念入手,逐步深入到其工作原理、关键技术特点以及在金融、供应链管理等多个领域的实际应用案例。通过这篇文章,读者不仅能够理解区块链技术的核心价值和潜力,还能获得关于如何评估和选择适合自己需求的区块链解决方案的实用建议。
25 0
|
18天前
|
前端开发 JavaScript UED
axios取消请求CancelToken的原理解析及用法示例
axios取消请求CancelToken的原理解析及用法示例
62 0
|
6月前
|
编译器 C语言 开发者
单片机原理与应用:探索微型计算机世界
单片机原理与应用:探索微型计算机世界
53 1

热门文章

最新文章

推荐镜像

更多