第7章 XDAIS算法标准
7.1 概述
XDAIS(eXpressDSP algorithm standard)算法标准是TI公司提出的一套DSP算法编程时所应遵循的规范。
DSP算法标准在三个层次上定义了一系列编程规范,其内容包括图7-1中的第1层到第3层。
图7-1 DSP算法标准
●第1层,定义所有算法必须遵循的通用编程规范,适用于任何DSP。
●第2层,定义在一个系统中同时存在多种算法时各算法应遵循的编程规范,包括内存
使用、外部标识符的命名以及算法封装等。
●第3层,定义针对特定DSP的编程规范。
●第4层,包含各种应用,不属于DSP算法标准所涉及的范围。
如果DSP算法遵循了第1层到第3层的编程规范,则该算法满足XDAIS。XDAIS算法标准的内容分为规则和建议两类:规则是满足XDAIS的算法必须遵循的;建议不作强制规定,但极力推荐程序员遵循。
7.2 通用编程规范
通用编程规范面向所有应用和所有DSP。
7.2.1 C语言的使用
所有的算法都必须遵循C语言编程规范,从而保证系统集成时可以使用C语言将各种算法“捆绑”在一起。
【规则1】所有算法必须遵循TI的C语言规范。
算法可以用纯汇编语言编写,但是它必须能被C语言调用并且遵循C语言规范。软件内部可能有许多内部函数,这些内部函数并不需要遵循C语言规范,只要求软件的最高层接口满足C语言规范即可。但是内部函数的操作不能让最高层接口违反C语言规范。
7.2.2 线程和可重入
DSP系统中可能出现各种类型的线程,要求算法能够可重入,即一段程序能够同时被多个线程使用。
可重入代码中不能包含自身的“状态”信息,否则不同的线程都会使用相同的状态数据进行计算,从而得到相同的结果。如果在程序代码中无法避免状态信息的出现,那么保护状态信息的最号方法是在某些特定的程序段运行时禁止线程调度。
【规则2】所有算法必须能够在抢先式多任务环境下可重入。
7.2.3 数据存储器
DSP的片内存储器和片外存储器(即使在片外使用SRAM)在性能上存在很大的差异。因此大部分程序员在编程时都尽可能使用片内存储器。
单独考虑一个算法时,DSP的片内存储器容量一般足够大。但是当单片DSP同时处理多个算法时,片内存储器容量就无法满足要求了。因此必须引入某种机制,使所有算法可以有效地共享宝贵的片内存储器。
【规则3】所有算法对数据的访问必须是完全可重载的,即不能使用绝对地址。
汇编语言转c语言的软件DSP算法中,存储器可分为两类:
●临时存储器(scratch memory),每个算法都可以自由使用,无须考虑之前它的内容。
●持久存储器(persistent memory),在算法实例不运行时用来保存算法状态的存储器。
每个算法的持久存储器不允许重叠,而临时存储器可以重叠。如果不区分持久存储器和临时存储器,所需要的存储器空间大小是所有算法存储器空间大小之和;如果区分持久存储器和临时存储器,所需要的存储器空间大小是所有算法持久存储器空间大小之和加上最大的临床存储器空间大小。
【建议1】算法应尽量减少使用持久存储器,而尽可能使用临时存储器。
按照存储器的物理特性,可分为三类:
●双访问存储器,在一个指令周期允许两次访问的片内存储器。
●单访问存储器,在一个指令周期只允许一次访问的片内存储器。
●片外存储器,一般情况下,访问片外存储器至少需要1个等待周期。
算法实现时,需要考虑存储器的以上特性。
7.2.4 程序存储器
【规则4】所有程序代码必须是可重载的,即不包括固定地址信息。
【建议2】初始化和结束处理函数都定义在独立的目标模块中,且该模块不包含其他代码。
7.2.5 代码固化
在算法中,有多种数据寻址方式,如指针、全局变量等。当访问全局变量时,需要绝对地址。在这种情况下,在相应数据放置的位置固定之前,这些代码是不能固化到ROM中去的。
【规则5】算法必须对该程序是否能进行固化作出说明。
7.2.6 外设的使用
【规则6】算法不能直接访问任何外设。这些外设包括但不限于片上的DMA、定时器、I/O 设备和缓存控制寄存器等。
7.3 算法级规范
7.3.1 接口和模块
满足XDAIS的基本软件组成单位是模块。接口是与算法相关的一系列数据类型定义、函数、常数和变量,在C语言中通常在头文件中说明。模块是包含一个或多个接口的实现(即实现某种功能的程序)。
图7-2 模块接口和实现
【规则7】所有的头文件必须允许在一个源文件中多次包含。
一个系统中往往集成了多种算法和系统控制代码,所以需要算法API作为外部标识(即对象代码的标号)被系统引用。
【规则8】所有的外部定义必须是API识别符或带开发商前缀的API。
模块的所有外部识别符必须带<module>_<vendor>前缀,其中<module>是模块的名称,<vendor>是开发商的名称。
【规则9】所有在程序中未显式定义的符号必须来自C语言运行库、DSP/BIOS库或其他符合XDAIS的模块。
【规则10】所有提供给用户的外部声明必须符合DSP/BIOS的命名规则。
DSP/BIOS命名规则如表7-1所示。
表7-1 DSP/BIOS命名规则
Convention Desctription Example
variables and functions variables and functions begin with lowercase
(after prefix)
LOG_printf( )
constants constants are all uppercase G729_FRAMELEN
types data types are in title case (after prefix) LOG_Obj
structure fields structure fields begin with lowercase buffer
macros macros follow the conventions of constants
or functions as appropriate
FIR_create( )
此外,多单词的标识不要用短划线“_”来分隔单词,例如LOG_getBuffer( )不要写成
LOG_get_buffer( )。这样可以避免在解释前缀时产生歧义。
【规则11】所有模块必须提供初始化和结束处理。
应用程序调用模块前,首先对模块进行初始化;结束时,初始化过的模块需要作结束处
理。初始化函数主要完成模块使用的全局数据的初始化。结束处理函数对运行时收集的调试
信息按适当方式输出。除模块的调试版本外,其他版本的结束处理函数通常是空的。
静态系统的资源(如存储器、MIPS和I/O等)是固定不变的。如果需要设计一个严格控
制成本、功耗受限、MIPS受限的系统,设计者往往希望在设计阶段就将该系统固定下来(即
设计为静态系统)。即使整个系统不是静态的,其包含的若干子系统在设计阶段是可以固定的。
【建议3】所有支持对象创建的模块应该支持在设计阶段创建对象。
建议3在实际中意味着在运行时完成对象创建的函数需要放置在单独的段内。最理想的
情况是每一个创建函数都放置在独立的目标文件中。
【建议4】所有支持对象创建的模块应该支持在运行阶段创建对象。
在理想的情况下,一个模块实现一个API,所有的系统都可以调用这个API。但是在实际
中模块在实现时往往需要在性能和特定应用要求之间作折中。因此软件架构需要支持同一个
API的多种实现。
此外,模块通常需要作一些配置,以便于系统集成人员在设计时根据系统的实际情况选
择适当的优化配置。
模块的配置参数应该集中在一个C语言结构中,并且在头文件中作出声明。
模块和模块对象的设计过程分别参见表7-2和表7-3。
表7-2 模块XYZ的设计
Element Desctription Required
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论