OMAP-L138是TI的一款ARM9与C6000结合的双核心异构处理器,ARM与DSP的最高主频都是456MHz,非常适合算法与控制上的应用。在使用EDMA时,有一个新的概念,就是PARAM(parameter RAM),这个是其他DMA使用中所没有的,这个参考可以方便DMA的数据传输,使DMA的传输更加的灵活。方便矩阵运算。
首先是芯片的EDMA,有两路EDMA:EDMA3_0_CC0与EDMA3_1_CC0;每一个EDMA模块,都有32个DMA 通讯,8个QDMA通道,128个PARAM,2个发送控制器,5个中断等等。其中可以看到有128个PARAM,虽然PARAM的功能很灵活,但是还没有实践方面的教程,本文就开始通过实践代码学习PARAM的使用。
一个EDMA3 传输总是被定义为三维数组,分别为ACNT、BCNT 、CCNT, 其分布结构如下:
PARAM的功能,通俗讲,就是某一路DMA的配置参数,可以在一组数据传输完成后,自动设置成PARAM中的参数,开启另一次DMA传输,PARAM中的参数可以是相同的传输,也可以是其他类型的传输,通过一路DMA与多个PARAM的组合,可以完成部分数据的截取,数组的排列(不是排序)等功能。 如下,是EDMA支持的两种模式:A 类同步传输与AB类同步 传输。其分别对应操作一维数据与二维数据。
那么下面,就要使用PARAM进行EDMA的配置了 在使用时,要通过EDMA3CCPaRAMEntry 类型的结构体宝一个param变量
EDMA3CCPaRAMEntry param0;
这个结构体的成员函数如下,可以看到,有一些源地址,目标地址,偏移之类的参数,这与DMA的配置中的参数是很像的,其实就是通过PARAM参数来对EDMA时行初始化的。 当参数中的aCnt、bCnt、cCnt在DMA传输过程中通过--到0后,本次的PARAM的资源也就消耗完了。
Param的地址与param成员的偏移地址如下,这里的param参数每个DMA都有128个,这里的n 的取值为1127,每个param中的参数分别也如下,每个param参数占用32字节数据,所有的param点用8K数据RAM。这里要在内存分配有做好容量的分配。
来看一下更详细的配置程序。 这里的pt是param0变量的一个形参,param0是传递到这个函数中的一个变量,而在这个函数中使用pr这个参数。 SrcAddr 设置为了sucBuff,而srcBuff的地址就是0x60000000,这个地址是挂在总线上的一个采样芯片,所以,这里的这个地址是不可以变的,总线上的这个芯片并没有地址线,只是通过并行数据线读取数据用的,所以, 这里的源地址在整个DMA的传输过程中是不更改的,srcBIdx的值就要设置为0. 而目标地址是要根据读取的数据进行修改偏移的,否则所有的数据都写入一个地址,那么也就只能得到新的一个数据,也是没有意义的。所以,这里的destBIdx要设置成acnt的值。
最后通过EDMA3SetPaRAM函数,将设置好的PARAM与EDMA通道进行绑定,以开启EDMA时消耗PARAM资源。
还有一个变量的配置是要注意的,那么就是linkAddr,这个linkAddr可以设置为另一个Param的地址,这样,当前Param资源消耗完了,会自动配置连接地址的Param中的初始化配置进行下一次的DMA传输。 这样,如果指定的这个地址是当前param本身,就是相同配置的连续DMA传输了。所以,DMA的触发连接与单次,并不在DMA控制寄存器中配置了,而是使用灵活使用param实现的。 在单核使用时就像上面的例程程序这样,但是在双核时,两个核心共享外设的情况下,DMA通道与Param都是进行了分配的,这些分配参数是在Linux启动时进行分配好的,对于双核的这个芯片,是要先启动ARM内核再通过ARM去加载DSP程序到DSP核心进行运行的。 在PAram中,前32位个param是与特定的DMA事件进行绑定的,其他的param可以配置为这些param的连接参数集;当然,也只有这些DMA通道使用的情况下才会进行绑定,否则,在不使用的情况下,也是可以作为普通的param集进行使用的。
这些param集要与Linux系统下的外设的使用分配不可共用,也就是说,一个param集只能由某一个内核使用,双核系统芯片,所有的外设都是共用的,而并没有两套这样的外设。那么分析情况就要是用户自己根据项目的需要进行合理的分配,只要是不冲突就是可以使用的。
|