AM261x EDMA编程实战:时间同步事件路由与性能优化

发布时间:2026/7/26 15:31:04

AM261x EDMA编程实战:时间同步事件路由与性能优化 1. 项目概述在AM261x这类高性能工业级SoC上做嵌入式开发尤其是涉及到高速数据采集、实时控制或者网络通信时直接内存访问DMA绝对是绕不开的核心技术。它就像是你项目里的“隐形搬运工”能在CPU喝茶休息的时候默默地把数据从A点搬到B点从而把宝贵的CPU算力解放出来去处理更复杂的逻辑和算法。但说实话DMA用好了是神器用不好就是“坑神”。寄存器配置、事件触发、中断处理每一步都藏着细节稍有不慎就会导致数据错乱、传输卡死或者性能不达预期。最近在调一个基于AM261x的实时运动控制项目需要将编码器信号通过PRU-ICSS的时间戳单元IEP捕获并经由EDMA增强型直接内存访问控制器实时搬运到内存中进行位置解算。整个过程对时序的确定性要求极高延迟必须控制在微秒级。这就不得不深入AM261x的时间同步Time Sync架构和EDMA事件路由机制。官方几千页的技术参考手册TRM信息量巨大但实操性的“坑点”和技巧却散落各处。今天我就结合自己踩过的坑和最终调通的实战经验把AM261x上EDMA编程的核心技巧以及如何利用SOC_TIMESYNC_XBAR路由器来配置高精度时间同步事件触发DMA的完整流程给大家掰开揉碎了讲清楚。无论你是刚开始接触AM261x的DMA还是正在为某个外设事件无法触发DMA而头疼这篇文章应该都能给你带来直接的帮助。2. EDMA控制器核心架构与编程思想在深入具体寄存器之前我们必须先建立对AM261x上EDMA控制器的正确认知。它不是一个简单的、只能做内存到内存拷贝的DMA而是一个高度复杂、可编程的数据搬运引擎其设计哲学围绕着“参数集Parameter Set”和“传输控制器Transfer Controller”展开。2.1 参数集Parameter Set与影子区域Shadow Region这是EDMA最核心的概念。你可以把每一个DMA传输任务比如从ADC结果寄存器搬256个字节到内存抽象成一个“参数集”。这个参数集里定义了一切源地址、目标地址、传输数据量aCnt, bCnt, cCnt、传输模式单次、链式、完成后的回调事件TCC代码等等。AM261x的EDMA控制器TPCC内部有大量的参数集RAM可以存放很多个这样的任务模板。“影子区域”是AM261x EDMA的一个高级特性主要用于多核或者复杂中断管理场景。简单理解控制器内核比如R5F可以直接访问的参数集区域叫“全局区域”。而“影子区域”是映射到不同中断线或不同主机如另一个R5F核心或DSP的私有参数集视图。通过配置EDMA_TPCC_DRAEMDMA区域访问使能寄存器和EDMA_TPCC_QRAEN队列区域访问使能寄存器你可以精细地控制哪个核心能访问、触发哪些通道的参数集。这个机制的核心目的是隔离和优先级管理。例如你可以让高优先级的实时任务独占一个影子区域确保其触发和完成中断不会被低优先级任务干扰。实操心得一影子区域配置的“坑”手册里提到配置影子区域完成中断时必须确保EDMA_TPCC_DRAEM_k寄存器对各区域的通道分配是互斥的除非应用特殊需要。这句话千万要重视。我曾在项目初期图省事将同一个通道例如通道0同时使能在了影子区域0和区域1。结果当该通道传输完成TCC0时竟然同时触发了两个区域的中断这直接导致中断服务程序ISR被重复调用系统状态紊乱。排查了很久才发现是这个配置问题。所以除非你明确需要“广播”式的中断通知否则务必保证每个通道在DRAEM寄存器中只被一个区域使能。2.2 传输控制器TPTC与提交队列参数集定义好了“搬什么”和“怎么搬”而真正执行搬运工作的“苦力”是传输控制器TPTC。AM261x通常有多个TPTC实例可以并行工作。EDMA控制器TPCC的作用是“调度员”它接收外部事件如定时器溢出、ADC转换完成找到对应的参数集然后将一个传输请求TR提交给空闲的TPTC去执行。这里就引出了“事件队列”的概念。TPCC内部有多个事件队列Queue每个队列有优先级。当多个DMA请求同时到来时它们会在各自的队列中排队由TPCC按优先级调度给TPTC。这种设计避免了单个硬件资源TPTC被某个高频率事件独占导致其他事件“饿死”。在编程时我们可以根据事件的实时性要求将其分配到不同优先级的队列中。2.3 关键寄存器操作范式AM261x EDMA的寄存器操作有一些特殊的“规矩”不按规矩来配置就会失效。这是第一个需要牢记的编程技巧。1. 专用置位/清零寄存器很多标志位寄存器其位的设置和清除必须通过独立的专用寄存器完成直接读写该寄存器本身是无效的。这是硬件设计上的常见做法旨在实现原子操作避免读-修改-写Read-Modify-Write过程在多核或中断环境下产生竞态条件。事件寄存器EDMA_TPCC_ER当某个DMA通道的事件被触发比如外设来了一个信号对应位会被硬件置1。你不能直接向ER写0来清除它。必须向**事件清除寄存器EDMA_TPCC_ECR**的对应位写1才能将其清零。事件使能寄存器EDMA_TPCC_EER用于使能或禁用某个通道的事件触发。同样你不能直接修改EER。需要使能时向**事件使能置位寄存器EDMA_TPCC_EESR对应位写1需要禁用时向事件使能清除寄存器EDMA_TPCC_EECR**对应位写1。2. 影子区域内存映射的访问使能对影子区域参数集RAM的读写访问受EDMA_TPCC_DRAEDMA区域访问使能和EDMA_TPCC_DRAEHM_k高半区域访问使能等寄存器控制。如果你在代码中配置了某个影子区域的参数集但传输就是不启动很可能是忘记在对应的DRAE寄存器中使能该区域的通道访问权限。在初始化任何影子区域的参数集前务必先配置好相应的DRAE寄存器。3. 参数集中的CCNT不能为零这是一个非常容易忽略但会导致严重问题的点。在编程一个“非哑元”non-dummy参数集时必须确保参数EDMA_TPCC_CCNT_n[15:0]即C计数不为零。CCNT定义了三维传输中“C”维度的迭代次数。如果它被意外设置为0EDMA控制器可能无法正确启动传输或者行为不可预测。在初始化参数集结构体时一定要给CCNT一个明确的有效值通常至少为1。3. 时间同步Time Sync架构与事件路由网络理解了EDMA本身我们再来看看如何让外部世界的事件精准地触发它。在AM261x上各种定时、同步事件是通过一个叫做时间同步交叉开关Time Sync XBAR的网络进行路由的。这个网络非常灵活是构建高精度同步系统的关键。3.1 时间同步架构概览AM261x支持多种时间同步协议和功能例如通过PRU-ICSS实现的IEEE 1588PTP精确时间协议以及通过CPSW0集成的CPTS模块实现的时钟同步。这些功能都可以作为整个系统的时间源Time Sync Controller。SOC_TIMESYNC_XBAR0和SOC_TIMESYNC_XBAR1这两个路由器模块提供了极大的灵活性。它们允许每个独立的时间域Time Domain独立选择自己的同步控制器。更重要的是它们负责将各种“同步Sync”和“比较Compare”事件路由到CPU中断或DMA事件触发源。简单说它们是把“时间到了”这个信号送到需要它的地方比如触发一次DMA搬运的“交通枢纽”。3.2 两大时间同步路由器详解SOC_TIMESYNC_XBAR0输入事件46个。来源极其丰富包括CPSW0_CPTS模块的对比事件COMP、生成函数事件GENF0/GENF1、同步事件SYNC。PRU-ICSS0/1内部IEP工业以太网外设的多个同步事件EDC_SYNC和比较事件IEP_CMP_EVT0~15。GPIO中断交叉开关GPIO_INTER_XBAR输出的多个中断信号。输出事件12个。主要路由至EPWMx_SYNCIN[8:1]作为增强型PWM模块的同步输入用于同步多个PWM模块的时基。RTIx/WDTx_CAPEVT[1:0]作为实时中断模块和看门狗定时器的捕获事件。EDMA_TRIGGERXBAR_IN[76:75]这是关键这两个输出直接连接到DMA触发交叉开关EDMA_TRIGGER_XBAR的输入从而可以作为EDMA的触发源。配置方法每个输出SYNCEVENT_OUTy都对应一个多路复用器控制寄存器SOC_TIMESYNC_XBAR0_MUXCNTL_y。向该寄存器写入输入事件的编号0~45即可完成路由配置。SOC_TIMESYNC_XBAR1输入事件18个。来源相对集中包括CPTS事件、PRU-ICSS同步事件、PWM同步输出事件以及GPIO中断。输出事件26个。功能更侧重于中断和事件分发EDMA_TRIGGERXBAR_IN[74:73]另外两个通往EDMA触发器的路由。R5SS0_CORE[0/1]_INTR[163:160]直接连接到R5F核心的VIM向量中断管理器作为CPU中断。ICSS0_EDC_LATCH[1:0]_IN路由到PRU-ICSS的锁存事件输入。ICSS0_IEP_CAP_INTR[5:0]路由到PRU-ICSS的捕获中断。CPTS_HW[8:1]_TS_PUSH路由到CPSW0 CPTS模块的硬件时间戳推送事件。配置方法同样通过SOC_TIMESYNC_XBAR1_MUXCNTL_y寄存器进行配置。3.3 事件路由配置实战以PRU-ICSS IEP事件触发EDMA为例假设我们的应用场景是使用PRU-ICSS0的IEP定时器在每次比较匹配事件例如ICSSM0_IEP_CMP_EVT2发生时触发EDMA搬运一次ADC数据。步骤1规划路由路径我们需要将ICSSM0_IEP_CMP_EVT2输入事件路由到一个能通往EDMA触发器的输出。查表可知ICSSM0_IEP_CMP_EVT2是SOC_TIMESYNC_XBAR0的输入事件编号为8。而SOC_TIMESYNC_XBAR0的输出SYNCEVENT_OUT10和SYNCEVENT_OUT11连接到了EDMA_TRIGGERXBAR_IN75和IN76。我们可以选择SYNCEVENT_OUT10。步骤2配置SOC_TIMESYNC_XBAR0找到SOC_TIMESYNC_XBAR0_MUXCNTL_10寄存器对应SYNCEVENT_OUT10。其物理地址为基址0x52E0_0000 偏移量0x04 (10 * 0x4) 0x52E0_0028。向该寄存器写入输入事件编号8。// 假设已映射寄存器地址到指针 pMuxCtrl10 *pMuxCtrl10 8; // 将 ICSSM0_IEP_CMP_EVT2 路由到 SYNCEVENT_OUT10步骤3配置EDMA_TRIGGER_XBARSYNCEVENT_OUT10现在变成了EDMA_TRIGGERXBAR_IN75。我们需要在EDMA触发交叉开关中将这个输入映射到某个EDMA通道的触发事件。假设我们使用EDMA通道20。 找到EDMA_TRIGGERXBAR模块中对应输入75的映射寄存器具体寄存器名需查TRM通常为EDMA_TRIGGERXBAR_IN75或类似将其值设置为目标EDMA通道号例如20。步骤4配置EDMA通道参数最后在EDMA控制器中配置通道20的参数集并将其触发源设置为由EDMA_TRIGGERXBAR映射过来的事件通常是某个特定的事件编号需要结合芯片手册确定具体的事件ID。使能该通道的事件并设置好源地址如ADC结果寄存器、目标地址内存缓冲区、传输计数等。至此一个由IEP定时器比较事件精准触发的DMA传输链路就配置完成了。当IEP定时器计数达到比较值时会产生一个脉冲事件这个脉冲依次通过SOC_TIMESYNC_XBAR0-EDMA_TRIGGERXBAR最终触发EDMA通道20启动传输。实操心得二路由链路的“端到端”验证时间同步事件路由链路可能很长源外设 - XBAR0/1 - EDMA_TRIGGER_XBAR - EDMA通道。调试时如果DMA不触发不要只盯着EDMA配置。一个有效的调试方法是“分段验证”。例如可以先将SOC_TIMESYNC_XBAR的输出路由到一个GPIO中断通过XBAR1连接到R5F中断用示波器或点灯的方式确认源事件如IEP比较事件是否真的产生了并且能否正确到达XBAR的输出端。确认前半段链路畅通后再连接EDMA部分。这样可以快速定位问题是在事件生成端、路由端还是DMA配置端。4. EDMA高级编程技巧与性能优化掌握了基本配置和事件路由后我们再来探讨一些提升EDMA稳定性、效率和可靠性的高级技巧。4.1 错误中断处理与系统健壮性EDMA控制器内部有完善的状态和错误检测机制。但默认情况下错误中断可能是关闭的。强烈建议在初始化EDMA后立即使能EDMA控制器的错误中断并为其挂接一个中断服务程序ISR。// 使能EDMA TPCC的错误中断 EDMA_TPCC-EEVAL 0xFFFFFFFF; // 使能所有错误类型的中断根据实际需要选择 // 在系统中断控制器中为EDMA错误中断号配置ISR在错误ISR中你需要读取EDMA_TPCC_EMR错误监控寄存器和EDMA_TPCC_EMRH高半部分来确定具体的错误类型例如地址对齐错误、配置错误、传输错误等。根据错误类型进行相应的处理如记录日志、重置通道、或触发系统安全恢复流程。忽略错误中断可能导致DMA静默失败数据不一致且极难调试。4.2 大块数据传输与链式Chaining操作当需要传输的数据量非常大例如数MB的图像数据时直接配置一个巨大的单次传输并不是好主意。这会导致该DMA通道长时间占用总线资源阻塞其他低延迟的DMA请求如音频采样造成“饿死”现象。解决方案是使用链式Chaining传输。将一个大传输拆分成多个较小的、参数化的传输即多个参数集并通过链式功能将它们链接起来。当前一个传输完成时会自动加载并启动链中的下一个参数集。这样在每个小传输结束后事件队列有机会处理其他等待的DMA请求提高了系统的整体响应性和公平性。链式传输有两种模式普通链式在当前传输完全完成包括所有数据写入目标后再加载下一个参数集。早期链式Early Chaining在当前传输的最后一个传输请求TR被提交给传输控制器TPTC后立即开始加载下一个参数集而不等待当前传输的所有数据实际搬运完成。这可以显著减少连续传输块之间的间隙提高吞吐量。实操心得三早期链式的“数据未就绪”风险使用早期链式需要特别注意因为“完成”信号是在最后一个TR提交给TPTC时发出的此时最后一个TR对应的数据可能还没有被TPTC实际搬运到目的地。如果你的应用逻辑在DMA完成中断后立即读取目标缓冲区可能会读到旧数据或部分数据。因此早期链式适用于“生产者-消费者”模型其中消费者如CPU或另一个外设会在稍后的时间点通过其他同步机制如另一个完成中断或标志位来确认最终数据的可用性。对于需要严格保证数据在中断时已完全就绪的场景应使用普通链式。4.3 利用事件队列进行调试在复杂的系统中如果出现DMA相关的问题如某个事件似乎没触发EDMA_TPCC的事件队列状态寄存器如EDMA_TPCC_QSTAT是一个宝贵的调试工具。你可以读取这些寄存器来观察各个事件队列中排队的条目。即使在系统发生故障后只要内存未被破坏这些队列中的条目也可能保留着最后几个未能处理的DMA事件信息前提是队列未被旁路。这为分析死机前的DMA活动状态提供了线索。5. 完整配置流程示例与代码片段下面以一个相对完整的示例展示如何配置一个由PRU-ICSS IEP定时器触发、使用EDMA进行周期性数据搬运的流程。这里假设使用SOC_TIMESYNC_XBAR0和EDMA通道20。5.1 系统初始化与外设使能// 1. 使能相关模块的时钟通过PRCM模块 PRCM-MOD_CLK_EN[CLK_DOMAIN] | (1 CLK_EDMA_BIT) | (1 CLK_ICSS_BIT) | (1 CLK_XBAR_BIT); // 2. 释放相关模块的复位通过PRCM模块 PRCM-MOD_RST_CTRL[RST_DOMAIN] ~((1 RST_EDMA_BIT) | (1 RST_ICSS_BIT) | (1 RST_XBAR_BIT)); // 3. 配置PRU-ICSS0的IEP定时器使其在特定比较值CMP2处产生比较事件 // 假设IEP时钟已配置设置比较寄存器2的值 PRU_ICSS0_IEP-CMP_CFG_REG | (1 2); // 使能CMP2 PRU_ICSS0_IEP-CMP2_REG 0x0000FFFF; // 设置比较值产生固定频率事件 PRU_ICSS0_IEP-CMP_STATUS_REG (1 2); // 清除可能存在的旧状态位5.2 配置时间同步事件路由// 4. 配置 SOC_TIMESYNC_XBAR0将 IEP 比较事件路由到 EDMA 触发器 volatile uint32_t *pTimesyncXbar0Base (volatile uint32_t *)0x52E00000; // 配置 MUXCNTL_10 寄存器 (偏移 0x04 10*4 0x2C)选择输入事件 8 (ICSSM0_IEP_CMP_EVT2) *(pTimesyncXbar0Base 0x2C/4) 8; // SYNCEVENT_OUT10 连接 IN75 // 5. 配置 EDMA_TRIGGER_XBAR将输入75映射到EDMA通道20的事件 volatile uint32_t *pEdmaTrigXbarBase (volatile uint32_t *)0x...; // 请查阅TRM获取确切基址 // 假设寄存器 EDMA_TRIGGERXBAR_IN75_MUX 控制输入75的映射 *(pEdmaTrigXbarBase IN75_MUX_OFFSET/4) 20; // 映射到EDMA通道205.3 配置EDMA通道参数集// 6. 初始化EDMA控制器驱动以TI SDK的EDMA3驱动为例 EDMA3_DRV_Handle hEdma EDMA3_DRV_open(0 /* instance */, 0 /* edma region */); // 7. 准备参数集 (Param Set) EDMA3_DRV_PaRAMConfig paramConfig; memset(¶mConfig, 0, sizeof(paramConfig)); paramConfig.srcAddr (uint32_t)(ADC_RESULT_REG); // 源地址ADC结果寄存器 paramConfig.destAddr (uint32_t)dataBuffer; // 目标地址内存缓冲区 paramConfig.aCnt 2; // 例如每次传输2字节ADC结果 paramConfig.bCnt 100; // B维度计数传输100次A计数 paramConfig.cCnt 1; // **关键C维度计数必须非零设为1** paramConfig.bCntReload 0; // B重载值用于链式传输 paramConfig.srcBIdx 0; // 源B索引地址偏移 paramConfig.destBIdx 2; // 目标B索引每次搬运后目标地址2字节 paramConfig.srcCIdx 0; paramConfig.destCIdx 0; paramConfig.linkAddr EDMA3_DRV_LINK_NULL; // 无链式或指向下一个参数集ID paramConfig.opt EDMA3_DRV_OPT_MAKE( EDMA3_DRV_SYNC_AB, // 同步类型A同步 EDMA3_DRV_ADDR_MODE_LINEAR, // 源地址模式线性 EDMA3_DRV_ADDR_MODE_LINEAR, // 目标地址模式线性 false, // 不累加源地址 false, // 不累加目标地址 EDMA3_DRV_TCC_NORMAL, // 传输完成码模式 20, // **TCC代码必须与触发事件关联这里设为通道号20** EDMA3_DRV_TCC_MODE_NORMAL, EDMA3_DRV_FIFO_WIDTH_8BIT, // 根据总线宽度设置 false, // 非早期完成 EDMA3_DRV_INTERRUPT_ENABLE // 使能传输完成中断 ); // 8. 配置通道20的参数集 EDMA3_DRV_configParamSet(hEdma, 20, ¶mConfig); // 9. 配置并使能影子区域访问如果需要 // 假设我们使用区域0并使能通道20 uint32_t draem_val 1 20; // 使能通道20在区域0 EDMA3_DRV_setDRAEM(hEdma, 0 /* region */, draem_val); // 10. 使能EDMA通道20的事件捕获 EDMA3_DRV_enableChannel(hEdma, 20, EDMA3_DRV_CHANNEL_TYPE_DMA); // 11. 使能EDMA控制器的错误中断全局配置 EDMA3_DRV_enableErrorInterrupt(hEdma, EDMA3_DRV_ERROR_INTERRUPT_ALL); // 并在系统级中断控制器中注册错误ISR5.4 配置中断服务程序// 12. 为EDMA通道20的传输完成中断注册ISR // 具体函数取决于你的RTOS或裸机中断管理库 register_isr(EDMA_CH20_COMPLETE_IRQn, edma_ch20_complete_isr); // 13. 传输完成中断服务程序 void edma_ch20_complete_isr(void) { // 清除EDMA通道中断状态通过事件清除寄存器ECR // 使用驱动API或直接写寄存器 EDMA3_DRV_clearInterrupt(hEdma, 20); // 处理数据例如通知任务缓冲区已满进行下一步处理 data_ready_flag 1; // 如果需要连续传输可以在这里重新配置参数集或使用链式自动加载 // 例如切换双缓冲区指针 // paramConfig.destAddr (uint32_t)nextBuffer; // EDMA3_DRV_configParamSet(hEdma, 20, ¶mConfig); } // 14. EDMA错误中断服务程序 void edma_error_isr(void) { uint32_t errorStatus EDMA3_DRV_getErrorStatus(hEdma); // 检查并处理具体错误位 if (errorStatus EDMA3_DRV_ERR_MISSED_EVENT) { // 处理事件丢失错误 log_error(EDMA missed event!); } if (errorStatus EDMA3_DRV_ERR_ADDRESS_ERROR) { // 处理地址错误 log_error(EDMA address error!); } // ... 清除错误中断标志 EDMA3_DRV_clearErrorInterrupt(hEdma, errorStatus); }6. 常见问题排查与调试技巧实录在实际开发中EDMA和时间同步路由的配置问题层出不穷。下面是我总结的一些典型问题及其排查思路希望能帮你快速定位问题。6.1 DMA传输完全不启动这是最常见的问题。请按照以下清单逐项检查时钟与复位确认EDMA控制器、源外设如ADC、IEP、以及SOC_TIMESYNC_XBAR模块的时钟是否使能复位是否已释放这是最基础的硬件使能步骤。事件通路这是排查的重点。使用“分段法”源头用示波器或逻辑分析仪测量源外设如IEP比较输出引脚或内部信号是否有脉冲产生频率和宽度是否符合预期路由第一段尝试将SOC_TIMESYNC_XBAR的输出路由到一个GPIO中断通过XBAR1连接到CPU中断在中断服务程序里翻转一个测试引脚的电平。如果能观察到翻转说明事件已成功到达XBAR输出端。路由第二段确认EDMA_TRIGGERXBAR的映射配置是否正确。输入编号如IN75和输出的EDMA通道号是否对应EDMA端检查EDMA通道的事件是否已使能EDMA_TPCC_EER寄存器对应位可以通过软件手动触发一次DMA写EDMA_TPCC_ESR寄存器来测试通道参数集本身是否正确。如果软件触发能工作但外部事件不能问题肯定出在事件路由链路上。参数集配置检查参数集中的CCNT是否不为零源地址和目标地址是否可访问非空、已映射OPT字段中的TCC代码是否与通道号或期望的中断号匹配6.2 DMA传输能启动但数据错误或传输不完整地址与对齐检查源/目标地址是否符合EDMA的总线访问对齐要求通常是字节对齐但某些模式下可能需要更严格的对齐。检查SRC/DEST_BIDX等地址索引计算是否正确是否会导致地址越界。数据宽度与FIFO设置检查OPT中的FIFO_WIDTH设置是否与总线的实际数据宽度匹配是否与源/外设的数据宽度匹配不匹配会导致数据被拆分或合并错误。缓冲区大小与传输计数复核ACNT、BCNT、CCNT的乘积是否等于你期望传输的总字节数BCNT重载值BCNTRLD在链式传输中是否正确设置竞争条件如果源数据是外设如ADC确保DMA读取数据的速度不超过外设产生数据的速度。必要时在外设和DMA之间加入FIFO或使用流控。同时确保CPU或其他主机不会在DMA传输过程中修改源/目标缓冲区。6.3 中断无法产生或异常产生多次中断使能与映射EDMA传输完成中断TCINT需要在参数集OPT中使能。同时需要在系统中断控制器如VIM中使能对应的EDMA中断线并正确设置中断向量。中断清除在中断服务程序ISR中必须通过写EDMA_TPCC_ECR事件清除寄存器来清除对应的中断标志位。忘记清除会导致中断持续触发陷入死循环。影子区域冲突如前所述如果同一个通道在多个影子区域的DRAEM寄存器中被使能且TCC代码相同一次传输完成会产生多个区域的中断。检查并确保通道在DRAEM中的分配是互斥的。早期完成中断的时机如果使用了早期链式Early Chaining中断是在最后一个TR提交时产生的而非数据完全搬运完成时。如果你的ISR立即使用数据可能会出错。考虑使用普通链式或在ISR中通过其他机制如查询目标缓冲区状态标志确认数据就绪。6.4 性能不达预期队列优先级高实时性要求的DMA通道应分配到高优先级的事件队列通过EDMA_TPCC_DMAQNUM寄存器配置。避免低优先级的长传输阻塞高优先级的紧急事件。总线带宽与仲裁检查EDMA访问的内存或外设是否位于繁忙的总线上是否存在与其他主设备如另一个CPU核心、DSP的带宽竞争可能需要调整系统互连Interconnect的仲裁优先级。使用链式与早期链式对于大数据量传输务必使用链式将其拆分。对吞吐量要求极高的场景评估使用早期链式但要注意其数据就绪的延迟。参数集链接地址在链式传输中确保当前参数集的LINK字段正确指向下一个参数集的地址。错误的链接地址会导致链式传输停止。调试时善用芯片的调试功能如通过CCSCode Composer Studio查看EDMA寄存器的实时状态或者使用性能计数器如果支持来监控DMA活动率和总线占用率。对于最棘手的时序问题有时在关键信号线上添加测试点用逻辑分析仪捕捉实际的事件触发和DMA响应时序是唯一有效的定位手段。

相关新闻