探析基于C语言的DSP程序设计

更新时间:2024-03-15 作者:用户投稿原创标记本站原创 点赞:28072 浏览:130533

【摘 要】本文介绍了基于C语言的DSP工程的基本结构,C程序中的CMD文件,同时分析了C编程的其他问题,旨在对基于C语言的DSP程序设计起到抛砖引玉的作用.

【关 键 词】C语言;DSP程序;main()函数

传统的汇编语言依赖于计算机硬件,程序的可读性和可移植性比较差.一般的高级语言具有很好的移植性,但是又难以实现汇编语言的某些功能.而C/C++语言作为一种高级语言,既可以访问物理地址又可以进行位操作,能直接对硬件进行操作,适合用作DSP开发语言.

1.C语言的基本结构

一个最小的C应用程序项目至少包含如下几个文件:

(1)有且必须有一个作为C程序入口点的包含main﹙﹚函数的C语言源文件(.C).系统库初始化完毕后,就把控制权交给main﹙﹚函数.

(2)连接命令文件.该文件包含了DSP和目标板的存储空间的定义以及代码段、数据段是如何分配到这些存储空间的.

(3)C运行库文件rts2xx.lib.C运行库提供了编译器提供的所有功能,包括初始化C语言环境、设置堆栈及提供标准C的库函数如printf等.库文件及其源代码位于CCS安装目录下的\c2000\cgtools\lib目录下.

若用户所写程序要写进ROM存储器并在上电后直接运行,还必须包含中断向量表文件,中断向量表文件通常是汇编文件(.a)的形式,此文件需要被链接器命令文件准确定位在DSP复位后执行指令的地址.

一个用C编写的DSP程序的常规执行流程为:中断向量表的第一条指令可设置为“B_c_int00”,从而在上电复位后,把控制权交给rts2xx.lib运行库中的C环境入口点_c_int00,在c_int00()函数中完成堆栈指针的初始化及全局变量初始化等操作,再调用main()函数,把控制权交给main()函数,从而执行用户的应用程序.

2.C程序中CMD文件

TI的CCS开发环境提供了将C语言编译为汇编语言的C/C++编译器.与汇编器类似,C/C++编译器对C程序编译后也产生已初始化段和未初始化段,具体的段名稍有不同.

C/C++编译器不会生成.data段,但也产生了一些新的段.

TMS320C2xx的C/C++编译器生成以下几种段.

(1)包括数据表或可执行代码的初始化段.编译器生成以下几种初始化段.

.text段:包括所有的可执行代码和常量.

.cinit段:包括初始化数量和常量的表.

.const段:包括字符串常量、明显初始化的全局和静态变量的定义和初始化.

.switch段:包含Switch语句表.

(2)用于保留空间的未初始化段.程序可在运行时使用这些空间建立和存储变量.编译器生成以下几种未初始化段.

.bss段:为全局和静态变量保留存储空间.若设置了-c连接选项,C的引导程序会将数据从.cinit段复制到bss段.

.ebss段:与bss段类似,只为far修饰的全局和静态变量保留存储空间.若设置了-c链接选项,C的引导程序再将数据从cinit段中复制到edss段.

.stack:段:系统堆栈段,通过堆栈可以给函数传递参数或为局部变量分配空间.

.syem段:为动态存储器分配保留空间.函数malloc()、calloc()和realloc()使用该保留空间.若程序没有使用这些函数,不会产生.syem段.

.esyem段:与.syem段类似,只为far修饰的malloc()、calloc()和realloc()才能使用该保留空间.若程序没有使用这些函数,不会产生.esyem段.

链接器将不同模块中同名段组合为输出段,一个完整的程序就是由这些输出段组成.用户可以将这些输出段分配到特定的地址空间,以满足系统需要.

通常.text、.cinit和switch段会被链接到ROM或RAM,且必须分配到程序存储器;.const段被链接到ROM或RAM,且必须分配到数据存储器;.bss/.ebss、.symem/.esyem段必须被链接到RAM,且必须分配到数据储存器中.

使用#pragma伪指令,也可以在C程序中自定义代码段和数据段,#pragma是标准C中保留的预处理命令,它告诉编译器的预处理器如何处理函数和数据.#pragma必须在符号被定义和使用前使用,且不能在函数体内声明#pragma.


CODE-SECTIONpragma伪指令函数在指明的段中分配空间,使用该伪指令创建的段可与.text段分配到不同的区域.它的语法为:

#pragmaCODE-SECTION(func,“sectionname”)

其中func为函数名,sectionname是用户自己定义在程序空间的段名.

3.C编程的其他问题

(1)关键字

与标准C一样,DSP的C编译器也支持关键字,下面对常用的关键字进行介绍.

1)const关键字.DSP的C/C++编译器支持ANSIC中的const关键字,用于限定值不能被修改的变量或数组.若变量或数组被const关键字所修饰,则该变量或数组所占的存储空间会被分配到.const段.

2)volatile关键字.使用volatile关键字修饰的变量每次被访问时,执行部件都会从其所在的内存单元中取出值.而未使用volatile修饰的变量在访问时则可能直接从CPU的寄存器中取值,因为该变量之前可能被访问过,读取寄存器的速度比读取内存要快得多.使用volatile修饰的变量会被分配到末初始化段中.程序设计时,那些随时可能被外部硬件改变的内存地址的内容要使用volatile修饰,如芯片内部的外设寄存器或某个随时可能改变的外部硬件的寄存器.

3)crgister关键字.使用crgister关键字可用高级语言直接访问DSP的控制寄存器,但crgister修饰的对象的名字要与C28xDSP的控制寄存器名相符,否则编译器会报错.该关键字不能在函数内部使用,且只能修饰整型或指针变量,而不能修饰浮点型及任何结构体及共用体.

4)interrupt关键字.interrupt关键字用于指定一个函数作为中断怎么写作函数.使用该关键字指定一个函数后,编译器会按照中断怎么写作函数的要求对寄存器进行保护并使用正确的返回顺序,函数的入口参数必须是void类型,函数返回值也必须是void类型,函数体内使用局部变量,也可自由是堆栈和全局变量.

(2)C运行支持库

同标准C一样,C28x的开发也可使用库函数来实现常用任务.C运行支持库的库文件位于\C2000\cgtools\lib,该库文件包括标准的C/C++运行支持库函数、浮点运算函数、I/O函数及程序的入口点c_int00等.在CCS的安装目录\C2000\cgtoo\lib中有库对应的源程序文件rts.src,用户可以利用归档器和建库器对rts.src中的文件进行提取、修改等操作,并重新生成自己需要的库文件.