DSP-CH8-C语言开发.ppt_第1页
DSP-CH8-C语言开发.ppt_第2页
DSP-CH8-C语言开发.ppt_第3页
DSP-CH8-C语言开发.ppt_第4页
DSP-CH8-C语言开发.ppt_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

8.2DSP芯片C语言开发,用C语言开发DSP程序不仅使DSP开发的速度大大加快,而且开发出来的DSP程序的可读性和可移植性都大大增加,程序的修改也极为方便。采用C编译器的优化功能可以增加C代码的效率,在某些情况下C代码的效率甚至接近手工代码的效率。在DSP芯片的运算能力不是十分紧张时,用C语言开发DSP程序是非常合适的。TI公司的CCS集成开发环境能够编译C和C+语言,TI公司还提供了DSPLIB和rts.lib等辅助的函数库,使开发人员能够直接使用fft,fir以及文件存取等特殊函数,从而大大减少了开发人员的工作量。,8.2.1TMS320C54xC/C+编译器支持的数据类型,表8-1列出了IMS320C54xC/C+编译器支持的数据类型的大小、表示形式和表示范围,这些数据类型在float.h和limits.h中定义。在C语言开发的过程中,采用合适的数据类型对于系统的正确运行有着极为重要的意义。,8.2.2C语言的数据访问方法,1.DSP片内寄存器的访问DSP片内寄存器在C语言中一般采用指针方式来访问。常采用将DSP寄存器地址的列表定义在头文件中(如reg.h)。DSP寄存器地址定义的形式为宏,如下所示:P233,在主程序中,若要读出或者写入一个特定的寄存器,就要对相应的指针进行操作。例:通过指针操作对SWWSR和BSCR进行初始化。#defineSWWSR(volatileunsignedint*)0 x0028#defineBSCR(volatileunsignedint*)0 x0029Intfunc()*SWWSR0 x2000;*BSCR0 x00;,2DSP内部和外部存储器的访问同DSP片内寄存器的访问相类似,对存储器的访问也采用指针方式来进行。例:通过指针操作对内部存储器单元0 x3000和外部存储器单元0 x8FFF进行操作。int*datal0 x3000;/*内部存储器单元*int*data2=0 x8FFF;/*外部存储器单元*intfunc()*datal2000;*data20;,3DSPI/O端口的访问DSPI/O端口的访问通过ioport关键字实现。定义的形式为:ioporttypeporthex_num其中:ioport是关键字,表明变量是io变量;type必须是char、short、int和unsigned;port表示io地址,hex_num是十六进制地址。例:ioportunsignedport10;*定义地址为10H*intfunc()port1020*write“20”toportl0H*bportl0;*readportl0Hintob*这里需要注意的是,所有的io变量必须在程序开始声明,不能够在函数中声明。,a=port10+b;/*readport10h,addb,assigntoa*/port10+=a;/*readport10h,adda,writetoport10h*/,8.2.3C语言和汇编语言的混合编程方法,用C语言和汇编语言混合编程的方法主要有以下三种:(1)独立编写C程序和汇编程序分开编译或汇编以形成各自的目标代码模块,然后用链接器将C模块和汇编模块链接起来。例如,主程序用C语言编写,中断向量文件(vector.asm)用汇编语言编写。,1)若要从C程序中访问汇编程序的变量,将汇编语言程序在.bss块中定义的变量或函数名前面加一下划线“_”,并将变量说明为外部变量,同时在C程序中也将变量说明为外部变量。如下例所示:汇编程序:.bss_var,1.global_var;DeclareitasexternalC程序:extenintvar;/*外部变量*/var=10;*访问变量*/,2)若要在汇编程序中访问C程序变量或函数C程序:globalinti;/*定义i为全局变量*globalfloatx;*定义x为全局变量*main().汇编程序:.ref_i;说明i为外部变量.ref_x;说明x为外部变量LD_i,DPSTL_x,A,(2)在C语言程序的相应位置直接嵌入汇编语句嵌入汇编语句的方法比较简单,如下所示:asm(“汇编语句”);asm(“NOP”);/*插入等待周期*asm(“ssbxINTM”);*关中断*asm(“rsbxINTM”);*开中断*/,采用这种方法的优点:1)可以在C语言中实现用C语言不好实现的一些硬件控制功能,如插入等待状态、中断使能或禁止等;2)可以用这种方法在C程序中的关键部分用汇编语句代替C语句以优化这个程序。缺点:比较容易破坏C环境,因为C编译器在编译嵌入了汇编语句的C程序时并不检查或分析所嵌入的汇编语句,在后面的注意事项中我们还会提到。TI建议不要采用这种方法改变C变量的数值,因为这容易改变C环境。,(3)对C程序进行编译生成相应的汇编程序,然后对汇编程序进行手工优化和修改。这种方法通过查看交叉列表的汇编程序,可以对某些编译不是很优但却是比较关键的汇编语句进行修改。修改汇编语句时,必须严格遵循不破坏C环境的原则。所以,这种方法需要程序员对C编译器及C环境有充分的理解,一般不推荐使用这种方法。,8.2.4中断函数,当C程序被中断时,中断处理函数与其他函数不同,进入函数前需要保护所有的寄存器的值,在中断函数返回时恢复被保护的寄存器。对于扩展精度寄存器来说,由于可能包含整数或浮点数,而中断程序并不能确定寄存器中数值的类型,因此,中断程序必须保护所有的40位数据。如果中断程序不调用其他函数,则只有那些在中断程序中用到的寄存器才予以保护。但是,如果C中断程序调用其他函数,则中断程序将保护所有的表达式寄存器。TMS320C54xC/C+中可以通过两种方式定义中断函数。,(1)通过给每个中断函数前面加关键字interrupt来声明一个函数为中断处理函数。中断函数的返回值是void的,函数没有任何的形参。中断函数可以任意使用局部变量和堆栈。例如:interruptvoidint_handler()Unsignedintflags;为了能够让相应的中断信号调用不同的中断函数,还需要在中断向量文件(vector.asm)中定义中断向量表。如下例所示:,.ref_c_int00.ref_int_handler.sect“vectors”RS:BD_c_int00NOPNOPBRINTl:BD_int_handler;McBSPl接收中断NOPNOP.end其中,_int_handler就是我们上小节提到的用C语言和汇编语言混合编程时,在汇编语言中访问C:程序变量时要在变量或函数名前面加一下划线_。,(2)c中断程序采用特殊的函数名格式为:c_intnn其中,nn代表0099之间的两位数如:c_int01就是一个有效的中断函数名。下面是一个中断函数的例子:intdatain,dateout;voidc_int05()Datain=sample(dataout);,在所有的c_intnn函数中,最特殊的是c_int00函数。c_int00是C程序入口点,是为系统复位中断保留的,这个特殊的中断程序用于初始化系统和调用_main函数。由于c_int00本身并没有调用其他的程序,因此它不需要保存任何寄存器。运行c_int00函数有多种方法:(1)跳转到这个函数;(2)调用这个函数;(3)硬件复位。推荐采用第一种方法设置中断函数,因为这种方法使程序的可读性增强。,8.2.5存储器模式,TMS320C54x将存储器分为程序空间和数据空间。程序空间存放的是可执行的代码,数据空间存放的是外部变量、静态变量和系统的堆栈。由C程序产生的代码和数据就被放置在存储空间的各个段中。1C编译器生成的段C编译器对C语言程序编译后生成6个可以进行重定位的代码和数据段,这些段可以用不同的方式分配至存储器以符合不同系统配置的需要。这6个段可以分为两种类型:,1)己初始化段主要包括数据表和可执行代码。C编译器共创建3个已初始化段:.text、.cinit、.const。.text段:包含可执行代码和字符串。.cinit段:包含初始化变量和常数表。.const段:字符串和switch表。在大存储器模式下,常数表也包含在.const段中。,2)未初始化段C编译器创建三个未初始化段:.bss、.stack和.sysmem;.bss段:保留全局和静态变量空间。在小模式中,.bss段也为常数表保留空间。在程序开始运行时,C初始化Boot程序将数据从.cinit段中拷贝至.bss段。.stack段:为系统堆栈分配存储器。这个存储器用于将变量传送至函数,以及分配局部变量。.sysmem段:为动态存储器函数malloc、calloc和realloc分配存储器空间。当然,若C程序没有用到这些函数,编译器就不创建.sysmem段。,一般地:.text、.cinit和.const连同汇编语言中的.data段可链入到系统的ROM或RAM中,.bss.stack和.sysmem段则应链入到RAM中。需要注意的是,如果系统不支持将.data块链入到数据空间,则必须将.data段链入到程序空间,运行的时候再调入数据空间,它的cmd文件如下所示:,MEMORYPAGE0:PROG:PAGEl:DATA:SECTIONS.const:loadPROGPAGE0,run=DATAPAGE1_const_run=;*GETRUNADDRESS运行地址*(.c_mark)*MARKLOADADDRESS地址标记*(.const)*ALLOCATE.const分配.const*_const_length=.-_const_run;*COMPUTELENGTH计算长度*,2C系统的堆栈C编译器利用TMS320C54X内置的堆栈机制来实现如下功能:(1)保护函数的返回地址;(2)分配局部变量;(3)传递函数变量;(4)保护临时结果。C系统的堆栈是分配的一块从高地址到低地址的连续存储空间,C编译器利用堆栈指针(SP)寄存器来管理堆找。局部帧是堆栈的一个区域,用于存储函数传递的变量和局部变量。每一个函数调用时都要在堆栈项创建一个新的局部帧。C环境在调用C函数时自动管理这些寄存器。当汇编与C语言接口时,注意必须采用与C一样的方式使用这些寄存器。,堆栈的大小可以由链接器设定。链接器创建一个全局符号_stack_size,并给它分配一个与堆栈大小一样的数值,缺省值为400H,即1K字。更改堆栈大小的方法非常简单,只需在链接器选项_stack后面加上一个大小等于堆栈的常数即可。,系统初始化后,SP指向堆栈的底部,其值等于堆栈底部的地址,也就是.stack段的首地址。因此,由于堆栈的位置取决于.stack段的分配,因而堆栈的实际位置是在链接阶段确定的。若将堆栈分配至存储器的最后一块,则堆栈具有无限的增长空间(在系统存储器的限制范围内)。特别需要注意的是,由于C编译器不提供检查堆栈溢出的任何手段,因此,必须保证有足够的空间用于堆栈,否则若发生溢出现象,将破坏程序的运行环境,从而导致程序的瘫痪。,3动态存储器分配编译器提供的运行支持函数中包含几个允许在运行时为变量动态分配存储器的函数,如malloc、calloc和recalloc。为全局变量pool或heap分配的内存定义在.sysmem段中。.sysmem段的大小可在链接时用_heap选项设定,设置方法是在该选项后面加上一个常数。同样,链接器也创建一个全局符号_sysmem_size,并将.sysmem段的大小赋予这个符号,缺省的大小为1K字。动态分配的目标一般用指针寻址,其存储区在一个独立的段中。为了在.bss段中保留空间,可用heap分配大的数据,以代替将它们说明为全局或静态。,例:对于structbigtable100;可以用指针并且调用malloc函数来实现,如下所示:Structbig*table;table(structbig*)malloc(100*sizeof(structbig);,4存储器大小模式编译器支持两种存储器模式:小存储器模式和大存储器模式。(1)小存储器模式小存储器模式是编译器的缺省存储器模式。在这种模式下,要求整个.bss段能匹配一个独立的64K字存储器页。也就是说,程序中所有的静态和全局数据必须小于64K字,并且.bss段不能跨越任何的64K字地址边界。编译器在运行初始化时,将数据页指针寄存器DP指向.bss段的开始,随后,编译器就可以用直接寻址()访问.bss中的所有目标(如全局变量、静态变量、常数表等),而不用修改DP寄存器。,(2)大存储器模式大存储器模式与小存储器模式的区别在于它不限制.bss段的大小,因此对全局变量和静态变量来说,具有无限的空间。但是,当编译器访问任意存储在.bss段中的全局或静态变量时,首先必须保证DP正确地指向目标所在的存储器页。为了做到这一点,在每次访问全局或静态变量时,编译器必须用LDP指令设置DP寄存器。由于加了这条指令,因此不仅增加了一个指令字,而且可能引入多个指令周期。,8.2.6其他注意事项,(1)c_int00函数包含在运行支持库中,必须与其他的C目标模块相链接。在链接时,如果用c或cr选项,并包含实时运行支持库rts.lib,则c_int00就自动链入。链接C程序时,链接器将可执行模块的入口点设置为c_int00。(2)采用C优化编译时,为了保证程序的正确性;要特别注意,如果使用asm行汇编语句,则必须对编译后得到的汇编语言进行仔细的检查,以确保asm语句在程序中的正确性。一般而言,当asm语句仅涉及诸如控制中断寄存器等硬件操作时,使用优化是比较安全的。,(3)可以使用volatile关键字避免优化对于下例这样的语句:unsignedint*data;while(*data!=4);由于*data是一个循环不变的表达式,因此这个循环将被优化为一个存储器读指令。为了避免这样的优化,需要将data定义为volatile,例如:volatileunsignedint*data;做了这样的定义后,优化器就不再对上述语句进行优化了。一般在reg.h中定义的寄存器地址都定义为vo1atile,例如:#defineIMR(volatileunsignedint*)0 x0#defineIFR(volatileunsignedint*)0 x001,(4)C54xC/C+编译器支持标准C的关键字const,这个关键字用来定义那些值不变的变量。但是,在定义时const的位置是十分重要的。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论