
1. EDMA控制器嵌入式系统数据搬运的“隐形引擎”在嵌入式系统开发尤其是涉及高速数据流处理的场景里CPU常常被数据搬运这类“体力活”拖累。想象一下一个视频处理应用每一帧的YUV数据都需要从摄像头传感器缓冲区搬到DSP的L2缓存进行处理如果全靠CPU用memcpy来干那CPU就啥也别干了光忙着搬数据了。这时候直接内存访问DMA技术就成了救星。它就像一个专职的“搬运工”能在不打扰CPU的情况下高效地在内存与外设、内存与内存之间搬运数据。而德州仪器TI在其多核DSP和微控制器中广泛使用的增强型直接内存访问EDMA控制器则是这个领域的“高级技工”。它不仅仅是简单的数据搬运更提供了一套高度可编程、支持复杂传输模式、具备精细优先级管理的强大机制。理解EDMA尤其是其核心的事件优先级和参数集PaRAM配置是解锁TI平台高性能数据处理能力的关键。本文将带你深入EDMA的内部运作机制通过几个典型的传输示例手把手展示如何配置PaRAM并分享那些在官方手册里不会明说但在实际调试中能让你少掉几根头发的实战经验。2. EDMA核心架构与优先级机制深度解析要驾驭EDMA必须先理解它的“大脑”和“调度规则”。EDMA控制器主要由两大模块构成通道控制器TPCC和传输控制器TPTC。TPCC负责接收、排队和管理各种传输请求事件而TPTC则具体执行数据传输。我们今天讨论的重点是TPCC如何管理这些并发的、可能同时到达的传输请求这就是事件优先级机制。2.1 事件的生命周期从触发到执行当一个事件比如McASP的发送缓冲区空、或一个软件手动触发到来时它在EDMA内部会经历几个关键阶段我们可以把它想象成快递包裹的分拣配送流程事件捕获事件首先被锁存到事件寄存器EDMA_TPCC_ER/ERH。这就像快递到了分拣中心被扫描录入系统。每个通道DMA有64个QDMA有8个对应寄存器中的一个位。事件使能仅仅被捕获还不够该通道必须在事件使能寄存器EDMA_TPCC_EER/EERH中被使能。这相当于给这个快递包裹开通了处理权限。如果没使能事件会被忽略。优先级仲裁这是最关键的一步。如果有多个事件同时处于待处理状态即ER和EER对应位都为1TPCC需要决定先处理谁。这里涉及多级优先级判断。进入队列仲裁胜出的事件被提交到事件队列。EDMA通常有多个队列如Queue 0, Queue 1。队列可以理解为不同优先级的“传送带”。出队与参数加载传输控制器TPTC从队列中取出事件根据该事件映射到的参数集PaRAM加载具体的传输参数源地址、目的地址、传输量等。执行传输TPTC根据PaRAM的配置执行实际的DMA传输。完成与链式触发传输完成后可能会产生完成中断也可能触发一个“链式事件”Chain Event自动启动下一次相关的传输写入链式事件寄存器EDMA_TPCC_CER/CERH。2.2 三级优先级详解谁先谁后的规则当多个“包裹”同时到达分拣中心谁先上传送带EDMA定义了清晰的三级优先级规则。2.2.1 通道优先级Channel Priority这是针对同时到达的不同通道事件的排序规则。规则很简单通道编号越小优先级越高。对于64个DMA通道通道0优先级最高通道63最低。对于8个QDMA通道通道0优先级最高通道7最低。为什么这么设计这是一种静态、固定的优先级策略。在系统设计阶段开发者可以将最紧急、最频繁的数据流分配到低编号通道如0 1 2确保它们总能优先获得服务。例如你可以将音频的实时RX/TX分配到通道0和1将非实时的内存初始化分配到通道63。注意这个优先级仅在事件同时被锁存到ER寄存器时起作用。如果事件是先后到达的则先到先服务在各自队列内。另外当一个DMA事件和一个QDMA事件同时发生时DMA事件总是优先于QDMA事件被提交到事件队列。2.2.2 触发源优先级Trigger Source Priority这是针对同一个通道的多种触发方式的排序规则。一个通道可以被三种方式触发事件触发Event Trigger由外设硬件信号触发最高优先级。链式触发Chain Trigger由前一个DMA传输完成时自动触发中等优先级。手动触发Manual Trigger由软件写事件置位寄存器EDMA_TPCC_ESR/ESRH触发最低优先级。规则事件触发 链式触发 手动触发。应用场景假设你为通道0配置了从ADC搬数据到内存事件触发同时又在代码里手动写ESR想启动一次测试传输。如果ADC数据正好在手动触发的同时或之后极短时间内到来那么EDMA会优先处理ADC的硬件事件而手动触发的事件需要等待。这保证了硬件实时性需求不会被软件操作意外抢占。2.2.3 出队优先级Dequeue Priority这是事件队列之间的优先级。事件被仲裁后会进入指定的队列。TPTC从这些队列中取事件来执行时遵循队列编号越小优先级越高的原则。通常Queue 0优先级最高。如何设置通过EDMA_TPCC_DMAQNUMNDMA通道和EDMA_TPCC_QDMAQNUMQDMA通道寄存器可以将每个通道映射到特定的队列。实战技巧你可以创建“高优先级队列”和“低优先级队列”。将音频、视频等对延迟敏感的数据流映射到Queue 0将后台的内存拷贝、缓存维护等任务映射到Queue 1。这样即使低优先级通道有大量任务堆积也不会饿死高优先级通道的实时请求。这比单纯的通道优先级更灵活因为它允许高编号通道如通道50通过映射到Queue 0来获得比低编号通道如通道10但映射到Queue 1更优先的服务。2.3 PaRAMEDMA的“传输任务清单”如果说优先级机制是调度规则那么参数集Parameter RAM, PaRAM就是每个传输任务的详细工单。每个通道或QDMA触发字关联一个PaRAM集合里面定义了传输的所有细节。一个完整的PaRAM集合包含多个关键字段理解它们才能配置出复杂的传输模式SRC/DST源和目的起始地址。ACNT第一维Array的字节数。通常是你想连续搬运的“元素”大小比如一个数据包的字节数。BCNT第二维Block的数量。即有多少个这样的“ACNT”数组。CCNT第三维Frame的数量。即有多少个这样的“BCNT”块。SRCBIDX / DSTBIDX在完成一个BCNT即一个Array传输后源/目的地址的跳跃字节数。用于处理不连续的数据块。SRCCIDX / DSTCIDX在完成一个CCNT即一个Block传输后源/目的地址的跳跃字节数。用于处理三维数据结构的重组。LINK链接地址。当本次传输完成后可以自动加载另一个PaRAM集合的地址实现传输链无需CPU干预。OPT选项寄存器包含大量控制位如TCINTEN传输完成中断使能。ITCINTEN中间传输完成中断使能在AB同步模式下每完成一个BCNT触发一。STATIC静态参数集。如果置1传输完成后PaRAM内容不会被更新链接功能失效适用于一次性或固定传输。SYNCDIM同步维度。决定是ACNT传输完成A同步还是ACNT*BCNT传输完成AB同步算作一次“传输请求”提交。3. 典型传输场景与PaRAM配置实战理解了原理我们来看几个“教科书级”的案例。这些案例不仅仅是示例更是你解决实际工程问题的模板。3.1 案例一基础数据块搬运Block Move场景将一块连续数据比如一幅图像的原始数据从外部DDR内存搬运到片内L2 SRAM以加速后续处理。配置思路这是最简单的1维线性传输。我们只需要设置源地址、目的地址和总字节数。如果总字节数小于64KBACNT的最大值可以使用A同步模式。否则需要使用AB同步模式将总数据拆分成多个BCNT。PaRAM配置示例假设搬运128KB数据 由于ACNT最大为6553564KB-1我们需要使用AB同步模式。将128KB数据视为ACNT1024字节1KBBCNT128个这样的块。SRC: 源数据起始地址如0x8000_0000DST: 目标起始地址如0x0080_0000ACNT: 1024BCNT: 128CCNT: 1 三维中不用SRCBIDX: 1024 每搬完1KB源地址1KB指向下一块DSTBIDX: 1024 同理SRCCIDX,DSTCIDX: 0 因为只有一“帧”OPT:SYNCDIM1(AB同步)TCINTEN1完成后中断STATIC1一次性搬运不链接。代码片段示意基于TI Driver或寄存器直接操作// 假设使用EDMA3的LLD (Low Level Driver) 或类似库 EDMA3_PaRAM_Config myParam {0}; myParam.srcAddr (uint32_t)src_buffer; myParam.destAddr (uint32_t)dest_buffer; myParam.aCnt 1024; // 1KB per array myParam.bCnt 128; // 128 arrays myParam.cCnt 1; myParam.srcBIdx 1024; myParam.destBIdx 1024; myParam.srcCIdx 0; myParam.destCIdx 0; myParam.linkAddr 0xFFFF; // 无链接 myParam.bCntReload 0; myParam.opt EDMA3_OPT_TCINTEN_ENABLE | EDMA3_OPT_SYNCDIM_AB | EDMA3_OPT_STATIC_TRUE; // 关键静态参数 // 将配置写入PaRAM集合并关联到某个DMA通道 EDMA3_configParam(handle, paramSetId, myParam); EDMA3_enableChannel(handle, channelId); // 使能通道和事件避坑指南地址对齐虽然EDMA支持非对齐访问但为了获得最佳性能尽量保证源地址和目的地址按照数据总线宽度如32位/64位对齐。ACNT也建议设置为总线宽度的整数倍。缓存一致性如果源或目的地址位于CPU的缓存空间如L1D L2在启动DMA传输前务必确保缓存数据已写回内存CacheWB或CacheWBInv传输完成后如果需要CPU读取数据要无效化对应的缓存行CacheInv。忘记这一步是导致“数据看起来没搬过去”或“数据是旧的”最常见的原因。STATIC位对于一次性搬运务必设置STATIC1。如果设为0EDMA会在传输完成后尝试根据LINK地址加载新参数如果LINK指向一个无效地址或未初始化的PaRAM会导致不可预知的行为甚至系统错误。3.2 案例二二维数据子帧提取Subframe Extraction场景从一帧640x480的YUV图像存储在外部DDR中提取一个16x12像素的小窗口ROI到L2 SRAM进行处理。每个像素16位2字节。配置思路这是一个经典的2D到1D的“采样”传输。源数据是二维矩阵我们需要跳过不需要的行和列只提取感兴趣的区域。这需要巧妙运用SRCBIDX。计算步骤确定窗口位置假设窗口起始于图像的第start_row100行第start_col200列。计算源起始地址src_addr image_base (start_row * 640 start_col) * 2。配置PaRAMACNT 16 * 2 32字节窗口的宽度即一行需要提取的字节数。BCNT 12窗口的高度即行数。SRCBIDX (640 - 16) * 2 1248字节。这是关键每提取完一行16个像素后源地址需要跳过本行剩余像素640-16和下一行开头到窗口起始列之间的像素start_col不对这里计算有误。正确思路SRCBIDX是完成一个ACNT传输后源地址的增量。我们提取了窗口的一行16像素但源图像的一行有640像素。所以为了移动到源图像中下一行对应窗口的起始位置我们需要跳过(640 - 16) * 2 1248字节。这里不需要考虑start_col因为起始地址已经定位到了窗口第一行的开头。DSTBIDX 32字节。目的地址是连续存放的所以每写完一行目的地址只需递增到下一行开头32字节。SYNCDIM1(AB同步)即每完成一行一个ACNT*BCNT不对这里概念要厘清。在AB同步下ACNT*BCNT即一行的传输完成后才会更新地址索引应用BIDX。所以BCNT在这里是“行”数。我们需要的是每传输完一行ACNT个字节就跳转源地址所以应该用A同步(SYNCDIM0)。在A同步下每完成一个ACNT传输即一行就应用SRCBIDX和DSTBIDX。BCNT在这里是重复次数行数。修正后的PaRAM配置ACNT: 32 (一行窗口的字节数)BCNT: 12 (行数)CCNT: 1SRCBIDX: 1248 (640*2 - 32) // 从本行窗口结尾跳到下一行窗口开头DSTBIDX: 32 // 目的地址连续存放SYNCDIM: 0 (A同步)STATIC: 1为什么用A同步因为我们的“传输单元”是“一行窗口数据”。我们希望每搬完一行就立刻更新地址跳过源图像中该行剩余部分然后开始搬下一行。这正是A同步的行为。3.3 案例三数据重排序Data Sorting/Transpose场景你有4个数组A, B, C, D每个数组有1024个32位整数。它们依次存储在内存中A[0], A[1], ... A[1023], B[0], B[1], ... D[1023]。但你的算法需要“交织”访问A[0], B[0], C[0], D[0], A[1], B[1], ...。你需要用EDMA将数据重新排列。配置思路这是一个3维传输的完美应用。我们可以把源数据看作一个4CCNT x 1024BCNT x 4字节ACNT的三维结构。目标是将其转换为1024CCNT x 4BCNT x 4字节ACNT的结构。PaRAM配置计算ACNT 4(一个元素的字节数int32_t)BCNT 1024(每个数组的元素个数)CCNT 4(数组的个数)SRCBIDX ACNT 4。每读完一个元素如A[0]源地址移动到下一个元素A[1]。DSTBIDX CCNT * ACNT 16。每写完一个目标位置如交织后数组的第一个位置放A[0]目的地址需要跳过4个元素的位置为B[0], C[0], D[0]预留空间指向下一个“A[?]”该放的位置即A[1]的位置。SRCCIDX ACNT * BCNT 4096。每读完一个完整的源数组如读完A的所有1024个元素源地址需要跳到下一个数组B的起始处。DSTCIDX ACNT 4。每写完一个完整的“交织块”即A[i], B[i], C[i], D[i]都写完目的地址只需移动到下一个交织块的起始连续存放。SYNCDIM 1(AB同步)。我们希望每成一个完整的“源数组元素读取”即读完A[0], B[0], C[0], D[0]后才更新到下一个元素索引。实际上这里需要链式触发Chaining或多次手动触发因为一次触发只能完成BCNT*CCNT个元素的传输让我们重新思考。更可行的方案配置为AB同步BCNT1024,CCNT4。但这样一次传输就会把整个A数组搬完不是我们想要的交织。正确做法是利用链式触发或多次触发将BCNT设为4数组个数CCNT设为1024元素个数然后通过合理的索引实现交织。修正后的配置使用链式触发单次传输任务搬运4个数组的第i个元素共4个元素16字节。ACNT 4(一个int32)BCNT 4(4个数组)CCNT 1024(总共1024组这样的操作但一次触发只完成一组)SRCBIDX 4(源在数组内移动A[i] - A[i1])DSTBIDX 16(目的在交织块内移动为4个元素预留空间)SRCCIDX 4096 - 4*3 4084?不对。我们需要在完成一个BCNT即搬完A[i],B[i],C[i],D[i]后源地址从D[i]跳回A[i1]这很复杂。实际上更简单的办法是将源视为一维连续数组通过精心计算的SRCBIDX来实现“跳跃式”读取。最终简化方案推荐 我们放弃使用CCNT仅用A同步和BCNT并利用链式触发或多次手动触发每次搬运一个“交织单元”4个元素。但设置BCNT4ACNT4SRCBIDX4096从A[i]跳到B[i]DSTBIDX4目的连续存放。这样一次触发只能搬4个元素A[i],B[i],C[i],D[i]。然后通过链式触发将完成事件链向自身或CPU循环触发1024次来完成全部工作。虽然触发次数多但EDMA硬件链式触发开销很小。PaRAM配置ACNT: 4BCNT: 4CCNT: 1SRCBIDX: 4096 // 从A[i]到B[i]的偏移DSTBIDX: 4 // 目的连续存放SRCCIDX: 0 (不用)DSTCIDX: 0 (不用)LINK: 指向自身PaRAM集合的地址用于链式触发OPT:SYNCDIM0(A同步),TCINTEN0(如果链式最后再中断),ITCCHEN1(启用中间完成链式触发即每完成一个BCNT就触发一次自身)这样只需手动触发第一次EDMA就会自动链式触发1024次完成全部数据的重排序。这是EDMA最强大的能力之一通过链式触发和参数更新非STATIC模式实现复杂的循环和间接寻址操作完全解放CPU。4. 从零开始EDMA传输配置步骤详解纸上得来终觉浅我们一步步拆解配置一个EDMA传输的完整流程。以最常见的DMA通道、外设事件触发为例。4.1 第一步初始化与通道映射确定通道类型选择使用DMA通道还是QDMA通道。DMA通道由外部事件或软件手动触发QDMA通道由对特定触发字的写操作触发延迟极低。通道映射DMA通道通过EDMA_TPCC_DCHMAPN_m寄存器将物理DMA通道号m映射到一个PaRAM集合号。例如将DMA通道0映射到PaRAM集合5DCHMAP0 5 5具体位域参考手册。QDMA通道通过EDMA_TPCC_QCHMAPN_j寄存器将QDMA通道号j映射到一个PaRAM集合号并指定触发字PaRAM集合内的某个偏移量通常是最后一个参数。例如将QDMA通道0映射到PaRAM集合6触发字为LINK地址字段QCHMAP0 (6 5) | (0x14)0x14是LINK字段在PaRAM集合内的偏移。影子区域考虑如果你的应用涉及多核或安全域可能会用到影子区域寄存器。确保通过EDMA_TPCC_DRAEM_k等寄存器正确配置了影子区域的访问权限。4.2 第二步配置PaRAM参数集这是核心步骤根据你的传输需求如上述三个案例计算并填充PaRAM集合的所有字段。OPT: 配置同步维度、中断使能、静态/动态链接等。SRC,DST: 源和目的地址。ACNT,BCNT,CCNT: 三个维度的计数。SRCBIDX,DSTBIDX,SRCCIDX,DSTCIDX: 地址索引增量。BCNTRLD: BCNT重载值用于链接或循环。LINK: 链接地址指向下一个PaRAM集合0xFFFF表示空不链接。关键提示对于QDMA通道包含触发字的那个PaRAM字段通常是最后一个写入的必须最后配置。或者在写完触发字之后再使能QDMA通道。这是为了防止在参数未完全配置好时误触发传输。4.3 第三步中断配置如果你需要传输完成通知必须配置中断。使能EDMA控制器内部中断在EDMA_TPCC_IER/IERH寄存器中置位对应传输完成码TCC的位。TCC在OPT寄存器中配置。配置设备级中断控制器将EDMA控制器的完成中断输出线如EDMA3_CC0_INT[0]连接到CPU的中断控制器如INTC并设置好优先级和使能。影子区域中断如果使用影子区域还需在EDMA_TPCC_DRAEM_k寄存器中使能对应通道/TCC的中断这是一个二级使能。4.4 第四步触发传输根据触发源类型操作外设事件触发使能外设的DMA请求功能。例如使能McASP的XEVT DMA请求。事件会自动被EDMA捕获。QDMA触发向映射好的触发字如PaRAM的LINK字段执行一次写操作即使写入的值不变传输立即启动。手动触发软件向EDMA_TPCC_ESR/ESRH寄存器的对应位写1。链式触发在前一个传输的PaRAM中设置好TCC码并在当前通道的链式事件使能寄存器中关联该TCC。前一个传输完成时会自动置位当前通道的链式事件寄存器CER。4.5 第五步等待完成与清理中断方式在中断服务程序ISR中读取EDMA_TPCC_IPR/IPRH寄存器确定是哪个TCC触发的中断处理数据然后必须向EDMA_TPCC_ICR/ICRH的对应位写1来清除中断挂起位。不清除会导致无法接收下一次中断。轮询方式主循环中不断检查EDMA_TPCC_IPR/IPRH的对应位。同样处理完成后需手动清除。5. 调试血泪史常见问题与排查指南即使按照手册配置EDMA也常常“罢工”。下面是我在项目中踩过的坑和总结的排查清单。5.1 传输根本不动No Transfer这是最让人抓狂的情况。按以下顺序检查事件使能了吗这是新手最常犯的错误。EDMA_TPCC_ER里看到了事件标志但传输就是不启动。立刻去检查EDMA_TPCC_EERDMA或EDMA_TPCC_QEERQDMA事件必须被使能对应位为1才会被处理。通过写EESR寄存器来置位EER。参数集是有效的吗检查关联的PaRAM集合确保CCNT不为0。一个全零或未初始化的PaRAM集合是无效的。通道被屏蔽了吗检查Secondary Event Register (EDMA_TPCC_SER/QSER)。如果一个通道的SER位被置1该通道将被禁止新的事件不会被处理。这通常发生在对一个NULL参数集全0或LINK0xFFFF且STATIC0进行触发时EDMA会将其视为错误并设置SER。你需要通过写SECR寄存器来清除SER位并重新配置正确的PaRAM。队列映射正确吗确认EDMA_TPCC_DMAQNUMN或EDMA_TPCC_QDMAQNUM寄存器是否正确地将你的通道映射到了一个有效的事件队列如Queue 0。映射到不存在的队列会导致事件无法被提交。5.2 中断不产生或只产生一次OPT寄存器中断使能了吗检查PaRAM中OPT寄存器的TCINTEN传输完成中断或ITCINTEN中间传输完成中断位是否置1。EDMA控制器中断使能了吗检查EDMA_TPCC_IER/IERH寄存器中对应你设置的TCC码的位是否置1。设备中断控制器配置了吗EDMA控制器的中断输出信号是否连接到了CPU中断控制器并且在该中断控制器中使能了该中断这是软件层面另一个常见的遗漏点。中断标志清除了吗在ISR中你是否正确地清除了EDMA_TPCC_IPR/IPRH中的中断挂起位忘记清除是导致中断只发生一次的最主要原因。清除方法是向EDMA_TPCC_ICR/ICRH的对应位写1。影子区域中断双重使能如果使用影子区域除了IER还必须检查EDMA_TPCC_DRAEM_k寄存器中对应的位是否使能。这是一个额外的“开关”。5.3 数据错误或地址不对缓存一致性再次强调如果源/目的地地址位于CPU缓存管理的内存区域必须在DMA传输前后进行缓存维护操作Write-Back, Invalidate。使用Cache_wb,Cache_inv等函数。建议为DMA缓冲区使用非缓存Non-cacheable或回写式缓存Write-Back with allocation的内存区域可以简化问题。索引计算错误仔细复核SRCBIDX,DSTBIDX,SRCCIDX,DSTCIDX的计算公式。特别是在处理二维、三维数据时一个符号错误或偏移量计算错误会导致数据错位。画个内存布局图辅助计算。同步维度SYNCDIM理解错误A同步和AB同步的选择直接影响传输的粒度和索引更新的时机。回顾案例二和案例三理解两者区别。5.4 性能不佳或丢事件队列饥饿如果一个低优先级队列如Queue 1有长时间的大数据量传输BCNT/CCNT很大可能会阻塞高优先级队列Queue 0的事件处理。考虑使用链式触发将大传输拆分成多个小传输。例如将一个大的1D传输拆分成多个BCNT较小的AB同步传输并在每次BCNT完成后链式触发下一次。这样事件队列有机会在链式触发间隙处理其他高优先级事件。过早完成报告如果使能了提前完成Early Completion选项EDMA可能在向TPTC提交完传输请求TR后就报告完成触发中断或链式事件而此时数据可能尚未完全到达目的地。对于需要严格同步的场景如数据发送后才能关闭外设谨慎使用此功能或通过其他方式如目的端缓冲区状态标志确认数据实际到位。事件丢失如果外设产生事件的速度超过EDMA处理出队和执行的速度事件可能会被后续事件覆盖而丢失。检查EDMA_TPCC_EMREvent Missed Register寄存器。如果发生丢失需要考虑优化传输减小单次传输量、提高优先级、使用更快的存储介质或增加事件缓冲机制。6. 高级技巧与最佳实践寄存器操作“三件套”很多EDMA控制寄存器如EER, IER的位不能直接读写必须通过对应的“Set”和“Clear”寄存器来操作。例如使能事件要写EESR禁用事件要写EECR。直接写EER寄存器是无效的。务必查阅手册区分REG,REG_SET,REG_CLR寄存器。利用链接LINK实现传输链对于复杂的多步传输如数据搬移-格式转换-输出可以预先配置多个PaRAM集合并通过LINK字段将它们串联起来。第一个传输完成后自动加载并启动第二个如此往复形成一个完整的处理流水线CPU只需启动第一次触发。QDMA用于低延迟触发QDMA的触发方式是写一个内存地址触发字这比配置DMA通道寄存器再手动触发ESR要快得多。非常适合在紧密循环中或对延迟极其敏感的场景中启动传输。调试时观察事件队列在复杂系统调试中如果怀疑事件调度有问题可以读取EDMA_TPCC_QSTATN等队列状态寄存器观察事件是否正常入队和出队。这有助于定位是事件生成问题、优先级仲裁问题还是TPTC执行问题。参数集复用与动态更新对于周期性或模式相似的传输可以配置一个非静态STATIC0的PaRAM集合。每次传输完成后通过链接或CPU更新其部分参数如源/目的地址即可用于下一次传输节省配置开销。错误中断服务程序ISR务必使能EDMA的错误中断EDMA_TPCC_ERRINT并编写ISR。当发生事件丢失、地址错误等问题时EDMA会触发错误中断。在ISR中读取错误状态寄存器可以及时发现问题避免系统静默失败。EDMA是一个功能极其强大的模块其复杂度对应着其灵活性。初学时会觉得寄存器繁多、概念抽象但一旦掌握了其优先级调度思想和PaRAM配置的精髓它将成为你开发高性能嵌入式系统最得力的助手。记住多动手实验从简单的块搬运开始逐步尝试复杂的二维、三维和链式传输结合调试器观察寄存器状态是掌握EDMA的最佳途径。当你能让EDMA流畅地处理视频流、重组音频数据包而CPU占用率几乎为零时那种成就感会让你觉得所有的调试都是值得的。