OMAPL138学习----Codec Engine之xDAIS
认识xDAIS(部分转载)
现代软件开发,已从上世纪的面向过程编程发展到当前的面向框架编程。软件开发经验已证明:框架话、模块化的开发方式可以极大的提高软件开发效率,提高代码质量及代码重用率。然而,在嵌入式编程中,由于长期缺乏完善的开发框架和可用的API,开发人员依旧利用C或汇编语言和底层硬件打交道,凡是亲力亲为,这必然会增加嵌入式开发的入门门槛,降低代码的重用性,甚至增加代码易集时的复制度(不过这些缺点,对于程序员来说确是好事,入门门槛高、开发复制意味着高付出高回报,不像现在桌面电脑端的开发,已经被人研究烂了,如果你不是超超超超级大牛,根本找不到一份满意的薪水)。基于这点,TI公司发布了一套DSP算法标准——TMS320 DSP Algorithm Standard,规范了DSP算法软件的开发,并提供了类似C++语言类的封装方式的算法接口,使得算法集成变得简单统一。
XDAIS标准
如果你对TMS320 DSP Algorithm Standard还陌生的话,那么如果提起另一个名字:xdais,那么就顺眼地多了。没错,我们在Codec Engine文档中经常看到的xdais,实际上就是TMS320 DSP Algorithm Standard的另一个名字。根据TI官方白皮书,xdais标准一共提供了39条规则,15条指南。这些规则和指南一共分为4个部分:
IALG接口
前面说了,xdais标准里含有39条标准,15个指南。这些标准、指南几乎涵盖了整个DSP开发的生命周期,例如使用TI的C语言啊,所有C6x算法必须支持低位优先啊。具体的规则可以参考《TMS320 DSP Algorithm Standard Rules and Guidelines User’s Guide》
xdais作为一个DSP的开发框架,定义了一些接口:
- IALG – 为算法实例对象的创建定义了独立于框架的算法接口。
- IDMA2 – 为C64X和C5000使用统一的DMA资源处理方式的定义的算法接口
- IDMA3 – 为C64+和C5000使用统一的DMA资源处理方式的定义的算法接口
《TMS320 DSP Algorithm Standard API Reference》指出,所有的算法都必须实现了IALG接口,IALG接口最主要的工作就是定义算法中需要使用的内存,提高片上系统内存使用效率,应用程序和xdais间工作关系如下:

这又遇到了一个问题,xdais的API是基于C的,我们知道,C是面向过程的,因此不存在面向对象里拥有的封装、继承、重构等特性,那么,我们的应用程序是如何实现接口的呢?对于这点,xdais的设计了一个名为IALG_Fxns的v-table:
开发人员只要遵循以上v-table定义的函数指针格式,实现自己的函数,就可以了。这些函数的作用大体上和函数名类似,框架的调用过程如下:

XDM标准
看到这里,有人要问了,既然TI已经有适用于DSP开发全过程的xdais标准,怎么又弄了个XDM标准出来。这里解释一下:我们知道xdais几乎涵盖了dsp开发的整个生命周期,是一个非常庞大的东西。如果里面的接口、准则、规定要开发人员一一实现的话,工作量还是很大的。因此,TI在xdais上又扩展了一个XDM标准,用来为数字信号处理提供一个轻量级的框架,总体上说,就是在XDAIS的基础上扩展了一个名为Digital Media的接口(xDM),然后根据数字图像处理的要求,提供了一个名为VISA的API集合,其底层远离,用的还是xdais的东西。
这样下来,应用层需和XDM标准打交道就变成以下形式了:

xDM接口实际上扩展了IALG接口,在其上增加了process和control方法,例如VISA API中的IVIDENC1接口的v-table定义如下:

而xDM的调用过程就变为:

VISA API
TI扩展xDM的目的,是为了为数字图像处理提供一个轻型的框架,为此,TI根据数字图像处理的分类,封装了一套名为VISA的API集合(这里的VISA,不是信用卡VISA,而是Video、Image、Speech和Audio的简称,想出这个名字的人太有才了),基本覆盖了数字信号处理的所有需求:
- IVIDENCx :Generic interface for video encoders
- IVIDDECx :Generic interface for video decoders
- IAUDENCx :Generic interface for audio encoders
- IAUDDECx :Generic interface for audio decoders
- ISPHENCx :Generic interface for speech encoders
- ISPHDECx :Generic interface for speech decoders
- IIMGENCx :Generic interface for image encoders
- IIMGENCx :Generic interface for image decoders
在Codec Engine的Algorithm Create过程中,开发一个算法程序往往是从实现这些接口开始,例如,我们要做一个H264的编码算法,需要从实现IVIDENCx开始。
这样的,我们在Codec Engine的开发领域里,DSP端开发流程如下:

xDAIS rules
rule 1:
All algorithms must follow the run-time conventions imposed by TI's implementation of the C programming language.
rule 2:
All algorithms must be reentrant within a preemptive environment (including time-sliced preemption).
rule 3:
Alogorithm data references must be fully relocatable (subject to alignment requirements). That is ,there must be no "hard-coded" data memory locations.
rule 4:
All alogorithm code must be fully relocatable.That is,there can be no hard coded program memory locations.
rule 5:
Algorithms must characterize therir ROM-ability,i.e.,state whether or not they are ROM-able.
rule 6:
Algorithms must never directly access any peripheral device .This includes,but is not limited to on-chip DMAs,timers,I/O devices,and cache control registers.Note,however,algorithms can utilize the DMA resource by implementing the IDMA2 interface on C64x and C5000 devices,and the IDMA3 interface on C64X+ devices using the EDMA3 controller.
rule 7:
All header files must support multiple inclusions within a single source file
rule 8:
All external definitions must be either API identifiers or API and vendor prefixed.
rule 9:
All undefined references must refer either to the operations specified in Appendix B (a subset of C
runtime support library functions and a subset of the DSP/BIOS HWI API functions) or TI’s DSPLIB or
IMGLIB functions, or other eXpressDSP-compliant modules.
rule 10:
All modules must follow the eXpressDSP-compliant naming conventions for those external declarations
disclosed to the client.
rule 11:
All modules must supply an initialization and finalization method.
Rule 12
All algorithms must implement the IALG interface.
Rule 13
Each of the IALG methods implemented by an algorithm must be independently relocatable.
Rule 14
All abstract algorithm interfaces must derive from the IALG interface.
Rule 15
Each eXpressDSP-compliant algorithm must be packaged in an archive which has a name that follows
a uniform naming convention.
Rule 16
Each eXpressDSP-compliant algorithm header must follow a uniform naming convention.
Rule 17
Different versions of a eXpressDSP-compliant algorithm from the same vendor must follow a uniform
naming convention
Rule 18
If a module’s header includes definitions specific to a “debug” variant, it must use the symbol _DEBUG
to select the appropriate definitions. _DEBUG is defined for debug compilations and only for debug
compilations
在动态DSP系统中使用xDAIS
函数表
任何操作涉及到调用的标准算法都是以 IAIG_Fxns 结构体开始的。以XMP算法为例,其函数表如:
IXMP_Fxns XMP_IXMP ={ &XMP_IXMP, /* implementationId */ xmpActivate, /* algActivate */ xmpAlloc, /* algAlloc */ xmpControl, /* algControl */ xmpDeactivate, /* algDeactivate */ xmpFree, /* algFree */ xmpInit, /* algInit */ xmpMoved, /* algMoved */ xmpNumAlloc, /* algNumAlloc */ xmpProcess /* algorithm specific processing */ };
XMP_create()函数是最高级的算法函数,用以创建算法实例,返回实例对象的地址。
XMP_Handle handle;
handle = XMP_create(&XMP_IXMP, NULL);
XMP_create()接受一个指向函数表的指针和一个创建参数的指针作为他的参数。创建参数可为空,为空时接受默认创建参数。
如果使用空指针
if (prms == NULL) {
prms = &XMP_PARAMS;
}
确认创建参数被定义后,ALG_create()函数被调用
handle = (XMP_Handle)ALG_create (
(IALG_Fxns *)fxns, /* function table */
(IALG_Handle) NULL, /* parent object or NULL */
(IALG_Params *)prms /* creation parameters */
内存需求
创建算法实例的下一步就是分配所需内存,是通过一个内存描述符表来告知其内存需求。
表的创建方法如下:
algNumAlloc()可告诉我们算法需要的最大内存块的大小,如果没有实现algNumAlloc(),则使用默认值,IALG_DEFMEMRECS默认设置为4.
/* find out the maximum number of records needed */
numRecs = fxns->algNumAlloc();
知道其需求量,就可分配内存描述符表(IALG_MemRec)。
/* allocate space for the memory descriptor table */
/* allow maximum number of records specified by algNumAlloc*/
IALG_MemRec *memTab;
memTab = malloc(numRecs * sizeof(IALG_MemRec));
这个表传递给algAlloc()由其填满。
/* fill in the memory descriptor table */
/* returned value is actual number of records initialized */
/* it might be different than the maximum records required */
numRecs = fxns->algAlloc(prms, NULL, memTab);
分配内存
size (in bytes)
alignment (byte boundaries)
space (single access, dual access, external)
attributes (scratch, persistent, write-once)
base address
按照惯例,第一个内存描述符(算法实例对象)LALG_OBJMEMREC被定义为0.
/* note: IALG_OBJMEMREC is defined as 0 *
handle = memTab[IALG_OBJMEMREC].base;
最后,调用algInit()以完成实例对象和算法的初始化。
/* init the algorithm */
if (fxns->algInit(handle, memTab, NULL, prms) == IALG_EOK) {
return(handle);
}
激活函数
删除函数 algFree()
浙公网安备 33010602011771号