DM647/648 DSP开发实战:PLL时钟与EDMA3数据搬运核心配置详解
1. 项目概述:从芯片手册到实战,拆解DM647/648的时钟与数据搬运核心
如果你正在或即将基于德州仪器(TI)的TMS320DM647或DM648 DSP进行开发,那么你肯定绕不开两个最核心、也最容易让人困惑的底层模块:锁相环(PLL)时钟系统和增强型直接内存访问(EDMA3)控制器。手册里密密麻麻的寄存器表格和时序参数,是不是让你感觉无从下手?别担心,这篇文章就是为你准备的。我将结合自己多年在视频编解码和通信设备上折腾DM64x系列DSP的经验,把这两个模块从原理到配置,再到实际开发中踩过的坑,给你掰开揉碎了讲清楚。
简单来说,PLL决定了芯片能跑多快、跑多稳,而EDMA3则决定了数据能在芯片内部和外部如何高效、不卡顿地流动。一个处理“时间”,一个处理“空间”(数据流),两者共同构成了DSP高效运行的基石。DM647/648作为面向视频和影像处理的高性能DSP,其双PLL设计和强大的EDMA3控制器正是其性能优势的关键。理解它们,你才能从“芯片能用”进阶到“芯片用好”,真正榨干硬件的每一分性能。无论你是正在编写底层启动代码、优化算法数据流,还是在进行系统级功耗与稳定性调试,接下来的内容都将是你不可或缺的实战指南。
2. 核心思路解析:为什么DM647/648需要如此复杂的时钟与DMA设计?
在深入寄存器之前,我们得先想明白TI的设计师为什么要这么干。DM647/648定位在高清视频处理、多通道语音处理等场景,这类应用有几个共同特点:数据吞吐量巨大、实时性要求苛刻、多种时钟域并存。
想象一下处理一路1080p@60fps的视频流:每秒钟要处理超过124兆像素的数据(1920108060),这还没算上色度采样。如果所有数据搬运和计算都靠CPU(即C64x+内核)来亲自搬运,那它基本就别干别的了,全耗在搬数据上了,性能瓶颈立现。所以,必须有一个强大的、能独立于CPU工作的“搬运工”,这就是EDMA3存在的根本原因。它像一个高度智能化的物流中心,CPU只需要下达指令(比如:从视频端口缓冲区把一帧YUV数据搬到L2缓存),剩下的地址计算、数据搬运、搬运完成通知等繁琐工作全部由EDMA3自动完成,CPU得以解放出来专心进行算法运算。
另一方面,视频处理涉及多个时钟域:CPU核心需要很高的主频进行运算(可达1.1GHz),DDR2内存接口需要满足特定的频率规范(如533MHz的时钟速率),而像音频接口McASP、视频输入输出端口等外设又有各自独立的、通常较低的时钟需求。如果只用一个PLL生成所有时钟,很难同时满足高性能和低抖动的需求,且任何时钟调整都会牵一发而动全身。因此,TI采用了双PLL独立架构:
- PLL1:系统主时钟引擎。它为CPU核心、大部分外设和内部总线(如SYSCLK1/2/4)提供时钟。其频率可调范围宽(400-1100MHz),是系统性能的“总开关”。
- PLL2:专用内存时钟引擎。它专门为DDR2内存控制器生成时钟,采用固定20倍频。将内存时钟独立出来,可以确保内存接口获得最纯净、抖动最小的时钟信号,这对于高速并行的DDR2接口稳定性至关重要,避免了系统主时钟调整对内存访问的干扰。
这种设计思路的核心是“解耦”与“专精”。把对抖动敏感的内存时钟独立出去,把可灵活配置的系统时钟留给CPU和外设,让两者都能工作在最佳状态。理解了这一点,再看那些具体的配置参数和操作步骤,就不会觉得是一堆冰冷的数字了。
3. PLL1控制器:系统核心时钟的生成与精细化管理
PLL1是整个DSP的“心脏起搏器”。手册里Table 6-6那堆频率范围数字是死的,但怎么用活它们,里面门道不少。
3.1 工作模式与配置流程
PLL1有两种工作模式,由PLLCTL寄存器中的PLLEN位决定:
- 旁路模式(Bypass Mode, PLLEN=0):输入时钟
CLKIN1直接作为系统参考时钟SYSREFCLK输出。这通常用于芯片初始化和低功耗调试阶段,或者当外部可以提供足够高的时钟时。此时PLL不工作,自然没有倍频。 - PLL模式(PLL Mode, PLLEN=1):这才是正常工作的模式。
CLKIN1经过一个可编程的前置分频器PREDIV,再经过PLL倍频器PLLM进行倍频,产生高频的PLLOUT,最后再经过后置分频器(如PLLDIV4)产生最终的SYSCLK4等系统时钟。
一个完整的、安全的PLL1配置流程应该是这样的:
- 确定输入时钟
CLKIN1:根据你的硬件晶振或时钟发生器,选择一个在25MHz到66.6MHz之间的稳定频率。例如,一个常见的选择是50MHz。 - 计算倍频系数:假设你用的是-900版本芯片,目标CPU频率(
PLLOUT)设为900MHz。那么倍频系数PLLM = PLLOUT / (CLKIN1 / (PREDIV + 1))。通常PREDIV可以设为0(即除1)。以50MHz输入、900MHz输出为例,PLLM = 900 / 50 = 18。你需要确保这个值在16到32之间(见手册说明)。 - 配置后置分频:
SYSCLK4是许多外设的时钟源。例如,通过PLLDIV4.RATIO配置。手册中例子RATIO=3,则SYSCLK4 = PLLOUT / (2*(3+1)) = PLLOUT / 8。如果PLLOUT为900MHz,则SYSCLK4为112.5MHz。 - 关键操作:遵循状态机,耐心等待。这是最容易出错的地方!你不能直接写入倍频值然后立刻让CPU跑在900MHz上。必须遵循:上电 -> 等待至少150μs的PLL稳定时间 -> 置位PLLRST进行复位 -> 等待至少128个输入时钟周期的复位时间 -> 清除PLLRST并配置PLLM/PREDIV -> 等待PLL锁定(锁定时间最长为2000个输入时钟周期)-> 最后才将PLLEN置1切换到PLL模式。这个等待过程必须通过读取
PLLSTAT寄存器中的锁定状态位来确认,或者用软件延时最坏情况时间。绝对禁止在时钟切换期间让主机(如HPI)访问DSP,手册明确警告了这一点。
实操心得:我强烈建议在Bootloader或系统初始化代码中,将PLL配置函数用汇编或内联汇编编写,并放置在片内RAM(L2或L1D)中执行。因为当时钟频率改变时,从慢速Flash执行代码可能会出错。代码结构大致如下:
// 伪代码,示意流程 void configure_pll1(void) { // 1. 确保PLL处于旁路模式(如果需要) REG_PLLCTL = BYPASS_MODE; // 2. 等待PLL电源稳定(上电后) delay_us(200); // 留有余量,大于150us // 3. 复位PLL REG_PLLCTL |= PLL_RST_BIT; delay_cycles(128 * (CYCLE_PER_US)); // 计算等待128个CLKIN1周期的时间 // 4. 清除复位,配置倍频和分频 REG_PLLCTL &= ~PLL_RST_BIT; REG_PLLM = DESIRED_MULTIPLIER; REG_PREDIV = DESIRED_PREDIV; REG_PLLDIV4 = DESIRED_RATIO; // 5. 等待PLL锁定 while (!(REG_PLLSTAT & LOCK_STATUS_BIT)) { // 可加入超时判断 } // 6. 切换到PLL模式 REG_PLLCTL |= PLL_ENABLE_BIT; // 7. 可选:等待几个周期让新时钟稳定 delay_cycles(10); }
3.2 电气特性与PCB布局的坑
手册Table 6-8的电气参数不是摆设。CLKIN1的时钟质量直接决定了PLL输出时钟的抖动(Jitter),进而影响系统稳定性。
- 周期抖动(Period Jitter):要求峰值小于100ps。这意味着你的晶振或时钟源本身质量要够好,PCB布线也要讲究。
- 上升/下降时间(Transition Time):要求小于1.2ns。过缓的边沿会导致时钟采样不确定,增加功耗和噪声。
- 占空比(Duty Cycle):高电平脉宽和低电平脉宽都要大于周期的40%(0.4C)。一个严重偏离50%的时钟会影响内部电路的时序余量。
PCB设计注意事项:
- 时钟线:必须作为关键信号线处理。走线尽量短、粗,避免打过孔,全程参考完整的地平面。
- 远离干扰源:绝对不要让时钟线靠近或平行于高速数据线(如DDR数据线)、开关电源的功率电感、以及复位等开关信号线。
- 终端匹配:根据时钟驱动器的要求和走线长度,考虑是否需要串联匹配电阻(通常22-33欧姆),以消除反射,保证信号完整性。
4. PLL2控制器:为DDR2内存提供“纯净”时钟
PLL2的设计哲学是“简单、稳定、专用”。它只工作在PLL模式,固定20倍频,输入CLKIN2范围20-26.6MHz,输出PLLOUT为400-533MHz(对应DDR2-800/1066)。
4.1 固定倍频与外部滤波电路
为什么是固定20倍频?这是为了优化PLL的环路带宽和相位噪声,为DDR2接口提供一个抖动极低的时钟。DDR2接口对时钟抖动非常敏感,因为数据是在时钟的上升沿和下降沿都进行采样(双倍数据速率),时钟的微小抖动会直接缩小数据有效窗口,导致读写错误。
图6-7中那个外部电路(C161, C162和EMI滤波器)至关重要,且必须严格按照手册要求布局。
- 电容C161, C162:通常是560pF和0.1μF,它们为PLL的电荷泵提供低噪声的电源滤波。必须使用高质量的NPO/COG陶瓷电容,并且务必靠近芯片的PLLV2电源引脚放置,引线尽可能短。
- EMI滤波器(Murata NFM18CC222R1C3):TI明确指定了型号。它的作用是进一步滤除电源线上的高频噪声,防止其耦合到敏感的PLL模拟电路中。这个滤波器的1.8V电源必须和芯片的I/O电源
DVDD18来自同一个电源平面,以避免地噪声。
布局铁律:这三个器件必须放在PCB的同一层,并且尽可能靠近DSP芯片,中间不能有任何开关、跳线或其他器件。同时,要最大化它们与任何高速开关信号线(特别是DDR2本身的数据、地址线)的间距。我曾在一个早期版本板卡上,因为EMI滤波器布局稍远且靠近DDR2数据线,导致系统在高温下偶发内存校验错误,排查了整整一周才发现是PLL2时钟抖动超标。
4.2 配置与注意事项
PLL2的配置比PLL1简单得多,因为它没有旁路模式,倍频固定。通常只需要在系统初始化时,确保其供电和输入时钟正常,它会在上电复位完成后自动锁定。你需要关注的是CLKIN2的电气特性(Table 6-11),其要求与CLKIN1类似。
一个重要提示:DDR2内存控制器内部的数据总线接口,实际上是由PLL1产生的SYSCLK1驱动的。PLL2产生的时钟(DDR2CLKOUT)主要用于内存芯片的时钟输入和控制器内部的时序对齐。这意味着DDR2的访问时序计算,需要同时考虑PLL1和PLL2两个时钟域之间的关系,在配置DDR2控制器寄存器(如SDCFG中的CLK位)时需要特别注意。
5. EDMA3控制器:数据搬运的“瑞士军刀”
如果说CPU是DSP的大脑,那EDMA3就是它不知疲倦的四肢和高效的物流网络。它支持64个通道,可以处理片内L1/L2、外部DDR2/EMIF以及所有外设之间的数据搬运。
5.1 核心概念与工作流程
理解EDMA3,首先要分清几个关键概念:
- 通道(Channel):共64个,每个通道与一个特定的事件(Event)绑定(见Table 6-13)。例如,通道0对应HPI中断事件,通道10对应McASP的发送事件等。通道是数据传输的“申请入口”。
- 参数RAM(PaRAM):这是EDMA3的灵魂。每个传输任务(Transfer)的所有信息(源地址、目的地址、传输维度、计数、链接地址等)都存储在一个参数集中。DM647/648提供了512个参数集(PaRAM Sets),每个集包含8个32位字(见表6-16)。通道通过
DCHMAPx或QCHMAPx寄存器与某个参数集关联。 - 传输控制器(TC, Transfer Controller):实际执行数据传输的硬件单元。DM647/648有多个TC(如TC0, TC1…),它们从EDMA3通道控制器(CC)分配的任务队列中读取参数集并执行搬运。TC的数量和性能决定了EDMA3的并行搬运能力。
- 事件(Event):触发一次传输的源头。可以是外设产生的(如McASP收到一个数据字),也可以是软件手动写入(通过
ESR寄存器)或链式传输(一次传输完成自动触发下一次)产生的。
一次典型的EDMA3传输流程(以McASP收数据到L2缓存为例):
- 初始化参数集:在PaRAM中找一个空闲集(例如Set 10),填写
OPT(传输选项,如地址模式、中断使能)、SRC(McASP数据接收寄存器地址)、DST(L2缓存目标地址)、A_B_CNT(A计数=单次传输元素个数,B计数=数组个数)、SRC_DST_BIDX(B索引,即每个数组间的地址偏移)等。 - 配置通道映射:找到McASP接收事件对应的通道(假设是通道11),在
DCHMAP11寄存器中写入参数集编号10。 - 使能通道事件:在事件使能寄存器
EER中,将通道11的对应位置1,允许该通道响应事件。 - 等待事件触发:当McASP收到一个数据块(例如一个音频帧)后,会产生一个接收事件。
- EDMA3响应:事件被捕获,EDMA3 CC根据通道映射找到参数集10,将其提交给一个空闲的TC。
- TC执行传输:TC根据参数集内容,自动完成从McASP到L2缓存的数据搬运。
- 传输完成:TC完成传输后,可根据
OPT中的设置,产生完成中断通知CPU,或者通过链接(LINK字段)自动加载下一个参数集(例如Set 11,用于将数据从L2搬到DDR2),开始链式传输。
5.2 参数集(PaRAM)配置详解与三维传输
EDMA3的强大之处在于它支持复杂的三维传输,这通过A_B_CNT、SRC_DST_BIDX和SRC_DST_CIDX、CCNT这几个寄存器精妙配合实现。
我们以一个图像处理中的典型场景为例:将DDR2中存储的一幅RGB图像(假设为640x480,每个像素3字节)搬运到L2缓存中进行处理。
- 第一维(A维):最基本的传输单元。
A_CNT= 3字节(一个像素的RGB值)。这是单次读/写操作的最小数据块。 - 第二维(B维):由多个A维传输组成的一维数组。
B_CNT= 640(图像一行的像素数)。SRC_BIDX和DST_BIDX= 3字节(每传输完一个像素,源和目标地址自动增加3字节,指向下一个像素)。 - 第三维(C维):由多个B维传输组成的二维数组。
C_CNT= 480(图像的行数)。SRC_CIDX和DST_CIDX= (640 - 1) * 3 字节?不对!这里是个关键点。CIDX是在完成一个完整的B维传输(即一行)后,地址的偏移量。假设图像在DDR中是连续存储的,那么一行结束后,下一行的起始地址就是上一行起始地址加上一行的大小。所以SRC_CIDX=DST_CIDX= 640 * 3 字节。
这样配置后,你只需要触发一次EDMA传输事件(或手动启动),EDMA3就会自动完成整个640x480图像的数据搬运,CPU完全不用干预。LINK_BCNTRLD字段还可以在C维传输完成后,自动加载一个新的参数集地址,实现“乒乓缓冲”等复杂数据流,这对于视频的连续采集-处理-显示流水线至关重要。
5.3 队列(Queue)与优先级(Priority)
64个通道的事件并不是同时处理的。它们被分配到几个事件队列中(Queue 0, 1, 2, 3…)。DMAQNUMx寄存器用来配置每个通道属于哪个队列。每个队列有一个优先级,由QUEPRI寄存器设置。
为什么要用队列?
- 避免冲突:当多个事件同时到达时,队列提供了缓冲和调度机制。
- 优先级管理:你可以将实时性要求最高的外设(如视频端口)分配到高优先级队列,将后台数据搬运分配到低优先级队列。确保关键数据流不被阻塞。
- 性能优化:不同的TC可以服务不同的队列,实现并行处理。
配置建议:通常将高带宽、实时性强的外设(如VPORT、McASP)分配到高优先级队列(如Queue 0),并与性能较强的TC绑定。将低速或软件触发的事件分配到低优先级队列。
6. 实战配置:从零搭建一个视频数据采集链路
让我们结合PLL和EDMA3,设计一个简单的视频采集子系统。假设我们从视频端口(VPORT)采集YCbCr 4:2:2数据到DDR2,然后通过EDMA3搬运到L2供编码器使用。
6.1 系统时钟规划
PLL1配置:
- 目标:CPU运行在900MHz,为视频编码提供算力。
- 输入:
CLKIN1= 50MHz晶振。 - 计算:
PLLM= 900 / 50 = 18(在16-32范围内,有效)。 - 后分频:设置
PLLDIV4.RATIO=3,得到SYSCLK4= 900MHz / 8 = 112.5MHz,作为VPORT等外设的时钟源。 - 操作:严格按照3.1节的流程编写初始化代码。
PLL2配置:
- 目标:为DDR2-800提供时钟。
- 输入:
CLKIN2= 25MHz晶振。 - 输出:固定20倍频,
PLLOUT= 25 * 20 = 500MHz。DDR2 PHY内部会将其除以2,产生250MHz的时钟给DDR2芯片,即DDR2-500(等效于DDR2-800的数据速率?这里需要注意,DDR2-800的时钟是400MHz,数据速率800MT/s。500MHz输出对应250MHz内存时钟,是DDR2-500。若要支持DDR2-800,需选择CLKIN2=26.6MHz,得到533MHz输出,内存时钟266.6MHz)。这里我们按手册支持的400-533MHz范围选择。 - 硬件:确保C161, C162和指定的EMI滤波器已正确焊接在靠近芯片的位置。
6.2 EDMA3数据流设计
假设使用VPORT2的Y/Cb/Cr事件(对应通道32, 33, 34)。
参数集规划:
- Set 0: 用于VPORT Y分量采集。
SRC=VPORT2数据寄存器,DST=DDR2中Y分量缓冲区(乒乓缓冲A区),A_CNT=一行Y分量的字节数,B_CNT=1,BIDX=0,CCNT=帧行数,CIDX=一行字节数。OPT中使能传输完成中断(TCC编码)和链接。 - Set 1: 链接到Set 0。
DST=乒乓缓冲B区,其他同Set 0。实现自动乒乓。 - Set 2, Set 3: 类似地,为Cb和Cr分量配置参数集,目标地址指向DDR2中Cb/Cr缓冲区。
- Set 10: 用于从DDR2搬运Y分量一帧数据到L2。配置为三维传输,
SRC=DDR2 Y缓冲区,DST=L2 SRAM,A_CNT=一行字节,B_CNT=一行像素数,BIDX=1个像素字节数,C_CNT=帧行数,CIDX=一行字节数。由软件触发。
- Set 0: 用于VPORT Y分量采集。
通道与队列配置:
- 通道32, 33, 34默认映射到VPORT2的Y/Cb/Cr事件。通过
DCHMAP32/33/34将它们分别映射到参数集0, 2, 3。 - 将通道32, 33, 34分配到高优先级队列(如Queue 0),确保视频采集数据不被丢失。
- 在
EER寄存器中使能这三个通道的事件。
- 通道32, 33, 34默认映射到VPORT2的Y/Cb/Cr事件。通过
初始化代码框架:
// 伪代码,展示关键步骤 void init_vport_edma(void) { // 1. 初始化PaRAM Set 0 for VPORT2 Y volatile uint32_t *param_set = (uint32_t*) (EDMA_PARAM_BASE + 0 * 32); // Set 0 起始地址 param_set[0] = OPT_VALUE; // 配置选项,如2D传输、递增模式、使能中断、链接到Set1 param_set[1] = (uint32_t)VPORT2_DATA_REG_Y; // 源地址 param_set[2] = (A_CNT << 16) | B_CNT; // A计数和B计数 param_set[3] = (uint32_t)DDR2_BUFF_Y_A; // 目的地址A param_set[4] = (DST_BIDX << 16) | SRC_BIDX; param_set[5] = (LINK_BCNTRLD_RELOAD << 16) | (uint32_t)(EDMA_PARAM_BASE + 1 * 32); // BCNTRLD和链接地址(Set1) param_set[6] = (DST_CIDX << 16) | SRC_CIDX; param_set[7] = C_CNT; // 2. 类似初始化Set 1, Set 2, Set 3... // 3. 配置通道映射 REG_DCHMAP32 = 0; // 通道32使用PaRAM Set 0 REG_DCHMAP33 = 2; // 通道33使用PaRAM Set 2 REG_DCHMAP34 = 3; // 通道34使用PaRAM Set 3 // 4. 配置队列 REG_DMAQNUM4 = (0 << 0) | (0 << 4) | (0 << 8); // 假设通道32-39在DMAQNUM4中,将通道32,33,34分配到队列0 // 5. 使能通道事件 REG_EESR = (1 << 32) | (1 << 33) | (1 << 34); // 设置事件使能 // 6. 启动VPORT,开始产生事件... }7. 调试技巧与常见问题排查
即使配置看起来正确,在实际硬件上跑起来还是可能遇到各种问题。以下是一些血泪教训总结出的排查思路。
7.1 PLL相关问题
- 症状:系统无法启动,或启动后运行不稳定,随机死机。
- 排查步骤:
- 测量时钟:用示波器测量
CLKIN1和CLKIN2引脚。检查频率、幅值、上升/下降时间、抖动是否满足手册要求。一个常见的坑是晶振负载电容不匹配,导致频率轻微偏移或启动不良。 - 检查电源:测量PLL的模拟电源引脚(如
PLLV、PLLV2)电压是否稳定、纹波是否在范围内(通常要求<50mV)。电源噪声是导致PLL抖动增大甚至失锁的主要原因。 - 验证锁定状态:在初始化代码中,在切换PLL模式后,循环读取
PLLSTAT寄存器的锁定状态位。如果始终无法锁定,检查PLLM/PREDIV配置值是否超出范围,或输入时钟质量太差。 - 旁路测试:先将PLL1配置为旁路模式,如果系统能以低频正常启动运行,则问题很可能出在PLL配置或时钟质量上。如果旁路模式也不行,则可能是电源、复位或最小系统其他问题。
- 测量时钟:用示波器测量
7.2 EDMA3相关问题
- 症状:数据搬运错误,目的地址数据全零或错乱,或者传输根本未发生。
- 排查步骤:
- 确认事件是否产生:在使能EDMA通道前,先读取
ER(事件寄存器)和EER(事件使能寄存器)。确保你关心的通道事件位在事件发生时会被置位。可以通过软件写ESR寄存器手动触发一次事件来测试。 - 检查PaRAM配置:这是最易出错的地方。务必在配置后,从内存中读回你写入的PaRAM Set值,确保与预期一致。特别是地址值,确保是物理地址,并且是字节地址(EDMA3使用字节地址)。检查
OPT中的SRC/DST地址模式(是递增、固定还是索引)、数据宽度等。 - 检查链接(Linking):如果使用了链接传输,确保链接地址指向一个有效的、已初始化的PaRAM Set。错误的链接地址会导致EDMA3读取到随机数据,行为不可预测。
- 检查队列状态:如果传输没启动,可能是事件队列满了。读取
QSTATx寄存器查看队列深度。高优先级队列如果被持续占满,低优先级队列的事件可能一直得不到服务。 - 利用中断和错误寄存器:在
OPT中使能传输完成中断(TCC),在中断服务程序里检查。同时,读取CCERR(通道控制器错误寄存器)和TC的ERRSTAT寄存器,看是否有地址对齐错误、权限错误等。 - 内存一致性:如果源或目标是缓存(Cache)内存区域(如L2被配置为Cache),必须在启动EDMA传输前,确保数据已经写回到内存(使用
CACHE_wbInv或CACHE_wb函数)。传输完成后,如果CPU要读取目的数据,可能需要无效化对应的Cache行(使用CACHE_inv)。忘记Cache一致性操作是导致数据“看起来”没更新或错乱的元凶之一。
- 确认事件是否产生:在使能EDMA通道前,先读取
7.3 性能优化建议
- 合理使用QDMA:除了64个事件触发的DMA通道,EDMA3还提供了QDMA(Quick DMA)。QDMA由软件直接写触发字(
QCHMAPx关联的PaRAM Set地址)来启动,没有事件绑定的开销,适用于一次性、软件发起的传输任务,速度更快。 - 参数集链接与乒乓缓冲:对于连续的数据流(如视频),充分利用PaRAM的链接功能。设置两套参数集(Set A和Set B),当Set A传输完成时,自动链接加载Set B,并在Set B的传输完成中断中,重新填充Set A的数据地址(例如指向下一帧)。这样可以实现零开销的连续搬运,CPU只需要处理中断和准备新数据地址即可。
- TC分配:如果有多个TC,可以通过
DMAQNUM寄存器将高带宽的通道分配到不同的TC上,实现真正的并行数据传输。例如,让VPORT采集用一个TC,DDR2到L2的搬运用另一个TC。 - 带宽考量:计算你的理论带宽需求。例如,1080p30 YUV422视频流,数据率约为 ~124MB/s。确保EDMA3的源/目标总线(如到DDR2的带宽)能够满足所有并发传输的总和,避免成为瓶颈。
