510|0

6803

帖子

0

资源

五彩晶圆(中级)

OMAPL138学习----Codec Engine之xDAIS [复制链接]

本帖最后由 Jacktang 于 2019-11-7 21:24 编辑

认识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个部分:

360截图20191107212313064.jpg

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开始。

 在动态DSP系统中使用xDAIS

 函数表

  任何操作涉及到调用的标准算法都是以 IAIG_Fxns 结构体开始的。

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);
}


回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

最新文章 更多>>
    关闭
    站长推荐上一条 1/7 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表