DSP课件第八章C语言编程基础.ppt_第1页
DSP课件第八章C语言编程基础.ppt_第2页
DSP课件第八章C语言编程基础.ppt_第3页
DSP课件第八章C语言编程基础.ppt_第4页
DSP课件第八章C语言编程基础.ppt_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

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

文档简介

第8章 C语言编程基础,为了提高程序开发的效率,同时使程序能与高级语言接轨,目前所有生产DSP芯片的公司都提供了C语言编译器。这样,除了对于一些运算量较大或对运算时间要求很严格的程序代码外,一般性的代码都可采用C语言编程,从而缩短程序的开发周期。C编译器还同时提供了汇编语言接口,可使汇编模块方便地被C语言调用。,(1)C编译器 (2)C代码优化 (3)C代码链接 (4)C语言 (5)C运行环境和库函数,以上5部分不再关注C语言本身的语法,而是关注如何在CCS集成环境中对拥护已经编写好的C代码有效地进行编译、汇编和链接,以生成可执行代码这样的工程问题。,8.1 C编译器和C优化代码,8.1.1 C编译器特性,C编译器的主要功能是将用户编写的C语言代码翻译为汇编语言程序。(1)支持ANSI标准C。 (2)支持ANSI标准实时运行库。 (3)汇编程序输出。 (4)生成COFF目标文件。 (5)编译器的Shell程序。 (6)灵活的汇编语言接口。 (7)完整的预处理程序。 (8)最优化。 (9)初始化数据到ROM存储器中。 (10)原程序交互列表功能。 (11)库构造工具。,CCS开发环境可以看成是一个大的软件包,里面包含了源代码编辑器,以及工程文件组织、编译和调试等一切功能模块。该软件包里,shell程序可以完成3个功能:编译、汇编和链接。shell程序缺省在C盘安装时,被安装在C:tic2400cgtool子目录下,对应的文件名为dspcl.exe。,(1)编辑器:包括分析器、优化器、代码产生器。把C语言程序编译成汇编语言程序。 (2)汇编器:把汇编语言源代码或C语言已经编译成汇编语言代码进行汇编,以产生COFF目标文件。 (3)链接器:将文件链接,产生可执行的目标文件。,8.1.2 Shell程序,8.1.3 C代码优化,C编译器中含有一个C优化程序。启用C优化程序可以提高程序执行速度,减少C程序代码长度。对于C语言,可以采用简化循环,使用软件流水线,重新安排、语句和表达式以及将变量分配到寄存器等方法实施优化。,在CCS中,选择菜单Project/Build Options选项,可以直接在弹出的对话框中对优先级别进行设置。,8.2 C程序代码链接,C编译器和汇编语言工具为用户链接程序提供了以下两种方法。 (1)先编译各个模块,最后将他们链接在一起。 (2)一次执行Shell程序的dspcl命令,直接完成各个模块的编译、汇编和链接。,在CCS集成环境下,还有少量设置CCS环境和工程文件组织工作需要人工干预。为链接C程序,需要DSP开发人员做以下工作: (1)把运行支持库包含到工程文件中; (2)指定程序运行时的初始化类型; (3)确定如何将由C语言程序编译、汇编和链接产生出的可执行代码分配到物理存储器中。,8.2.1 把运行支持库包含到工程文件中,所有C程序都必须与运行支持库链接。因为运行支持库包含了标准C函数,如sin()函数,以及编译器用来创建和管理CCS中C语言运行环境的函数。,运行支持库中包含了一个boot.obj目标模块,C程序链接时必须与它链接。当C程序开始运行时,首先执行boot.obj。链接时,链接器会自动提取boot.obj并链接它。,boot.obj包含了用于初始化运行环境的代码和数据。该模块执行以下任务: (1)建立堆栈; (2)处理运行时,初始化表和自动初始化全局变量; (3)调用C语言主程序main( ); (4)当C语言主程序main( )结束时,调用exit( )。,boot.obj中有一个重要的汇编语言函数_c_int0。它是boot.obj中的起点。链接时, _c_int0被自动定义为程序的入口点。如果程序从复位开始运行,则应将复位向量转移到_c_int0,以便DSP首先执行_c_int0。,8.2.2 指定初始化类型,用C语言编程时,会根据需要定义全局变量和静态变量。有些全局变量和静态变量具有初始值,有些全局变量和静态变量没有初始值。C编译器对C程序编译后,为具有初始值的全局变量和静态变量建立了一个专门的数据块.cinit。该块在程序运行后调入到RAM的.bss中。 .cinit调入到RAM中有两种方法: (1)在运行时,自动初始化全局变量和静态变量; (2)在加载时,自动初始化全局变量和静态变量。 当创建新工程时,第一种是缺省状态。,8.2.3 把块分配到物理存储器中,把块分配到物理存储器中就是把程序和数据分配到物理存储器中。 当使用C编译器对C程序编译后,可产生数据块和代码块。这些块根据各种不同的应用系统硬件配置和扩展情况,可以使用不用的方法将这些块分配到物理存储器中。,8.3 创建C语言软件,8.3.1 创建C语言寄存器头文件,与汇编语言相同,C语言编程也需要相应的头文件。 2407控制寄存器数量较多,为了方便编程,可以将这些寄存器地址定义在一个头文件(*.h)中。这样,在编程时只要将该文件包含其中,直接引用寄存器在*.h中定义的英文缩写名,而不必记它的地址。 在该头文件中,寄存器是以指针方式进行寻址。,8.3.2 创建main( )函数,在C语言应用软件中,用户必须定义一个main( )函数作为自己应用程序的开始。因为系统完成C语言环境设置后,boot.obj会自动调用main( )函数作为程序的开始。因此,程序员在程序中编写main( )函数是一种预定,也是一种强制。,void main(void) sys_ini(); for(;) delay(); /*xf管脚置低*/ asm(“ clrc xf“); delay(); /*xf管脚置高*/ asm(“ setc xf“); ,8.3.3 创建2407芯片初始化函数,初始化内容包括: (1)2407芯片初始化; (2)工程应用中所甬道的片内外设初始化; (3)片内外存储器初始化; (4)应用系统硬件接口初始化。,#include “exp4_2407.h“ void sys_ini() /系统初始化子程序 /*关总中断*/ asm(“ setc INTM“); /*抑制符号位扩展*/ asm(“ clrc SXM“); /*累加器中结果正常溢出*/ asm(“ clrc OVM“); /*禁止看门狗*/ * WDCR=0x00E8; /*CLKIN=10M,CLKOUT=40M*/ * SCSR1=0x0000; ,8.3.4 创建假中断处理函数,(1)2407工作时,如果意外引发了内核级中断,但是却没有低层外设中断 向量装入外设中断寄存器中时,假中断向量0000h装入PIVR; (2)CPU执行一个软件中断指令INTR时,使用了参数16,企图用软件中 断去服务于外设中断INT1INT6。这显然是一个错误,这时,假中断向量装 入PIVR ; (3)中断请求线发生故障,外设发出中断请求,而其INTn标志却在CPU应 答请求之前被软件清0,此时,外设中断的请求可能还没有被中断控制器确 认,中断控制器也不知道哪个外设中断向量应装PIVR,这时,假中断向量装 入PIVR .,interrupt void nothing() /假中断子程序 return; ,8.3.5 _c_int0函数,在运行C程序之前,用户必须首先建立起C语言运行环境。 建立C语言运行环境的函数在库rts2xx.lib中。把_c_int0函数作为硬件复位后的中断矢量入口来运行_c_int0函数。,rsvect B _c_int0 这样,当系统复位后,通过执行一条无条件转移指令来调用_c_int0函数,以建立C语言运行环境。,_c_int0函数初始化C环境时执行了如下任务: (1)为系统堆栈定义一个名为.stack的块,并建立初始化堆栈和帧指针; (2)将.cinit块的初始化数据表中的数据复制到.bss块,对全局变量和静态变量进行初始化; (3)调用main函数,开始运行C程序。,8.4 TMS320C240x C语言,8.4.1 数据类型,TMS320x 的C语言数据类型具有如下特征: (1)所有的整形类型,包括char、short和int及其它们对应的无符号类型, 是16位二进制数,相互间是等价的。 (2)长整型和无符号长整型类型是32位二进制数。 (3)带符号类型以2进制补码表示。 (4)char类型等同于int类型,为带符号类型。 (5)enum类型的对象以16位值表示,在表达式中enum类型和int类型等同。 (6)所有浮点类型(float、double和long double)是等价的类型,都以 32位浮点格式表示。 (7)长整型和浮点数保存在存储器中,低位数值保存在低地址。,8.4.2 C语言标准库函数的使用,TI公司的C编译器提供了C语言标准库函数。它与boot.asm等一起封装在rts2xx.lib中。 在使用标准库函数时,首先要声明这一函数。TI公司的所有标准库函数以分类的形式在不同的头文件中声明,全部声明库函数的头文件为assert.h、limits.h、stddef.h、ctype.h 、math.h 、stdlib.h 、setjmp.h 、string.h 、stdarg.h 、time.h 、和ioports.h。 为了使用一个库函数,用户必须首先使用#include来包含声明函数的头文件。,8.5 TMS320C24x C语言程序开发,TMS320C24x C语言具有特定的运行环境,为了确保C语言程序正确运行,C语言程序开发必须维护这个环境。,8.5.1 存储器模式,TMS320C24x 的C编译器将存储器分为程序存储器和数据存储器。程序存储器包含可执行代码,数据存储器包含外部变量、静态变量和系统堆栈。,由C程序生成的每一块代码或数据存放于存储空间的一个连续块中。,存储器映射及代码和数据存储空间的分配由链接器决定。编译器不考虑可用存储空间类型,也不考虑存储空间是否可以被代码和数据使用或者存储空间是否保留以用于I/O或控制。编译器只生成可重新分配的代码,链接器完成将代码和数据分配到合适的存储空间。,C汇编器对C语言程序编译生成7个可以进行重定位的代码和数据块:.text、.cinit、.const、.switch、.bss、.stack、.sysmem。,1、C编译器生成的块,(1).text块包含所有可执行代码和浮点常量。,(2).text块包含初始化变量和常量的表。,(3).const块包含字符串变量、明显初始化的全局和静态变量的定义和初始化。,(4).switch块包含switch语句表。,(5).bss块为全局和静态变量保留空间。,(6).stack块为C系统堆栈。,(7).sysmem块为动态存储器分配保留空间。,.text、.cinit和.switch块通常被链接到ROM或RAM,必须处于程序存储器中;.const块可以被链接到ROM或RAM,但必须处于数据存储器中;.bss、.stack和.sysmem块必须被链接到RAM,并必须处于数据存储器中。,这些块根据不同的系统配置以不同的方式被放到存储器中。链接器将不同模块相同的块组合为输出块。完整的程序由这些输出块组成,包括汇编器的.data块。,2、C系统堆栈,C编译器使用软件堆栈实现以下功能: (1)分配局部变量 (2)给函数传递参数 (3)保存处理器状态 (4)保存函数返回值 (5)保存临时变量 (6)保存寄存器,堆栈运行时从低地址向高地址增加。编译器使用2个辅助寄存器管理堆栈: (1)AR1为堆栈指针(SP)。指向当前堆栈顶部。 (2)AR0为帧指针(FP)。指向当前帧的起始处。每个函数调用会在堆栈顶创建一个新的帧,用于保存局部和临时变量。,局部帧是堆栈的一个区域,用于存储函数传递的变量和局部变量,每一个函数调用时都要在堆栈顶部创建一个新的局部帧。在调用C函数时,C环境会自动管理这些寄存器,堆栈的大小由链接器确定。全局符号_STACK_SIZE的值等于堆栈长度(缺省值为1KB)。,3、动态存储空间的分配,编译器运行支持库提供了几个函数,可以在运行时为变量动态地分配存储空间,如malloc、calloc、realloc等。 动态分配是由标准运行支持函数提供的。动态存储空间来自定义在.sysmem块中的全局池(pool)或堆(heap)。 .sysmem块的大小可在链接时由heap选项设定。同样,链接器也可创建一个名为_SYSMEM_SIZE的全局符号,并将.sysmem块的大小符给该符号。对动态分配的目标一般通过指针对其进行访问,并且他们的存储区被分配在一个独立的段中。,4、静态和全局变量的存储器分配,在C程序中说明的每一个外部或静态变量都是被分配给一个唯一的连续空间的,空间的地址由链接器确定,编译器保证这些变量的空间分配多个字,以便每个变量按字边界对准。,5、结构的对准,编译器为结构分配空间时,它将分配足够的字以包含所有的结构成员。在一组结构中,每个结构开始于字边界。,6、域的对准,非域类型对准于字的边界。对域分配足够多的位,相邻域组装进一个字的相邻位,但不跨越两个字。如果一个域要跨越两个字,则整个域将分配到下一个字中。,8.5.2 存储器规则,TMS320C2xx编译器严格规定:在C语言环境中,特殊的寄存器和特殊的操作联系在一起。如果要将汇编语言与C程序接口,必须遵循对这些寄存器的规定。 寄存器规则定义编译器如何使用寄存器和在函数调用时如何保存值。,上表列出了编译器如何使用寄存器,并说明了在函数调用时寄存器在保存值时所起的具体作用。,上表列出了编译器所使用的所有状态位。预设值是编译器在函数进入和返回时的期望值,修改栏是编译器产生的代码是否修改该域。,2、堆栈指针、帧指针和局部变量指针,编译器创建和使用自己的软件堆栈以用于保存函数返回地址、分配局部变量和给函数传递参数。当函数需要存储局部变量时,可以在堆栈中创建自己的工作空间(局部帧)。局部帧在函数入口时分配,在函数返回时释放。,系统提供堆栈指针(SP)、帧指针(FP)和局部变量指针(LVP)3个寄存器来管理堆栈和局部帧。,寄存器AR1用做堆栈指针。堆栈从低地址向高地址增长,SP指向堆栈中下一个可用的字。寄存器AR0用做帧指针。FP指向当前函数局部帧的起始地址。PF直接指向局部帧的第一个字,该字用做临时存储单元,可以用于实现寄存器到寄存器值的传递,同时在创建可重入C函数时也必须使用该存储单元。寄存器AR2用做局部变量指针,所有存储在局部帧的对象包括参数都要通过LVP间接引用。,3、寄存器变量,寄存器变量是指存储于寄存器而不是RAM的局部变量或编译器临时变量。,(1)不使用优化器,不使用优化器时,编译器至多为使用register关键字的两个变量分配寄存器。变量必须在参数列表中或函数的第一块中定义。编译器采用AR6和AR7作寄存器变量寄存器。 AR6保存第一个变量, AR7保存第二个变量。,(2)使用优化器,使用优化器时,所有寄存器变量定义将被忽略,由优化器决定寄存器分配。优化器直接将变量而不是地址分配给寄存器。优化器可以将AR5、AR6和AR7用作寄存器变量。AR5在函数调用时不保存,所以它在使用时可以跨越多个函数使用。,4、表达式寄存器,编译器使用没有用做寄存器变量的寄存器来计算表达式值和存储临时结果。在函数调用时不保留表达式寄存器内容。在函数调用时,用做临时存储的寄存器保存到局部帧,被调函数不用保存和恢复表达式寄存器。,5、返回值,如果函数返回值为标量类型(integer、pointer或float),则返回值保存在累加器中。当返回值为16位类型变量时,返回值在累加器中符号扩展。,8.5.3 函数结构和调用规则,1、函数如何进行调用,主调函数在调用另一个函数时完成以下工作(ARP必须为AR1): (1)主调函数以逆顺序将参数压入堆栈(最右边的参数最先压入,最左边的 参数最后压入)。函数调用时最左边的放在堆栈顶部。 (2)主调函数调用被调函数。 (3)主调函数假定在函数返回时ARP会被设定为AR1。 (4)当被调函数结束,主调函数用以下命令将参数弹出堆栈。 SBRK n,2、被调函数响应(函数入口时ARP应该设为AR1,AR1用作SP),(1)从硬件堆栈中弹出返回地址,并将其压入软件堆栈; (2)将帧指针FP压入软件堆栈; (3)分配局部帧; (4)如果被调函数修改AR6或AR7,将其压入堆栈。其他被修改的寄存器可 以不保存; (5)执行函数代码; (6)如果函数返回标量值,将返回值放入累加器。如果返回值为16位整型和 指针,在用累加器保存返回值时进行正确的符号扩展; (7)将ARP改为AR1; (8)如果保存了AR6或AR7,则恢复AR6或AR7; (9)释放局部帧; (10)恢复FP; (11)将返回地址从软件堆栈中弹出并压入硬件堆栈; (12)返回。,;假定ARP=AR1 POPD *+ ;将返回地址从硬件堆栈弹出,压入软件堆栈 SAR AR0,*+ ;将AR0(FP)压入堆栈 SAR AR1,* ;*SP=SP LAR AR0,#SIZE ;FP=帧大小 LAR AR0,*0+ ;FP=SP,SP+=SIZE分配局部帧空间 SAR AR6,*+ ;AR6压栈 SAR AR7,*+ ;AR7压栈 ;函数代码 MAR *,AR1 ;设置ARP=SP MAR *- ;指针指向AR7 LAR AR7,*- ;弹出AR7 LAR AR6,*- ;弹出AR6 SBRK SIZE+1 ;释放局部帧 LAR AR0,*- ;弹出局部帧指针FP PSHD * ;将返回地址从软件堆栈弹出,压入硬件堆栈 RET ;返回,8.5.4 中断处理,遵循中断原则就是在不影响C环境的情况下实现中断处理并返回C代码。,c_int0为C程序入口点,它同时也是引导函数,用来完成C环境初始化。 在初始化工作中,没有对中断进行任何处理,中断的全部控制寄存器和状态 位处于缺省状态。在缺省状态下,中断没有使能。,如果系统中要使用中断,用户必须作相应处理,使中断使能。这些操作 很容易用asm语句实现,或调用汇编函数来实现,对C环境没有影响 。,调用中断程序时,首先应调用运行时支持库中的子程序I$SAVE。 这个子程序保存了所有的寄存器。同样,在中断程序返回时,应调用调用 运行支持库中的子程序I $RET,用于恢复被保存的寄存器。以上过程都是 自动的,不需要用户编程时干预。,interrupt是C编译器中的中断关键字,用来声明中断函数。格式如下:,interrupt void nothing() /哑中断子程序 return; ,8.6 C语言和汇编语言混合编程,用C语言和汇编语言的混合编程方法主要有以下四种: (1)独立编写C程序和汇编程序,分开编译或汇编形成各自的目标代码模块, 然后用链接器将C程序和汇编程序链接起来。 (2)直接在C语言程序的相应位置嵌入汇编程序。 (3)在C语言程序中使用汇编程序的变量。 (4)对C程序进行编译生成相应的汇编程序,然后对汇编程序进行手工优化和 修改。,8.6.1 独立的C和汇编程序模块接口,(1)不论是用C编写的函数还是汇编编写的函数,都必须遵守寄存器使用规则。 (2)必须保护C函数要用到的几个特定寄存器。 (3)如果要改变状态寄存器的任何位,必须确保恢复出它们的值。 (4)中断程序必须保护所有用到的寄存器。 (5)从汇编程序调用C函数时,以逆序方式将参数压入堆栈,调用之后,将参 数弹出。 (6)调用C函数时,注意C函数只保护了几个特定的专用寄存器,其他寄存器 C函数可以自由使用。 (7)长整型和俘点数在存储器中存放的顺序是低位字在低地址,高位字在高 地址。 (8)如果函数有返回值,返回值存放在累加器ACC中。 (9)汇编模块不能改变由C产生的.cinit块。 (10)编译器在所有的标识符(函数名、变量名等)前加一下划线“_”。因 此,编写汇编语言程序时,必须在C程序可以访问的所有对象前加“_”。 (11)任何在汇编中定义的对象或函数,如果需要在C中访问或调用,则必须 用汇编指令.global定义。同样,如果在C中定义的对象或函数,需要在汇编中 访问或调用,在汇编中也必须用.global定义。,(1)C主程序: /*cmian.c*/ extern int asmfunc() ;定义外部的汇编函数 int gvar ;定义全局变量 main() int i; i=asmfunc(i) ;调用函数 (2)汇编语言函数_asmfunc: /*asmsub.c*/ .global _asmfunc .global _gvar .text _asmfunc: POPD *+ ;将返回地址保存至C堆栈 SAR AR0,*+ ;保护FP SAR AR1,* ;保护SP LAR AR0,#1 ;帧长度 LAR AR-,*0+,AR2 ;建立FP和SP,LDP #_gvar ;指向_gvar SETC SXM LACC _gvar LAR AR2,#_3 ;参数偏移 MAR *0+ ;指向参数 ADD *,AR0 ;将参数加至gvar SACL _gvar MAR *,AR1 SBRK 2 LAR AR0,*- ;恢复帧指针 PSHD * ;返回地址压入C24x堆栈 RET .end,8.6.2 在C语言中直接嵌入语句,是一种直接的C和汇编接口方法。可以在C程序中实现用C语言无法实现的一些硬件控制功能。,asm( “ 汇编语句 ” ),注意以下几点: (1)防止嵌入的asm语句破坏C环境。 (2)在C代码中插入跳转或标号可能会影响代码产生器的寄存器跟踪算法,产 生不可预测的结果。 (3)插入影响编译环境的伪指令也可能会造成麻烦。 (4)不要改变C变量值,但可以读取变量值。,如上,在程序中直接嵌入汇编语句的典型应用是控制芯片的一些硬件资源。,#include “exp4_2407.h“,void sys_ini() /系统初始化子程序 1000 8AA0 POPD *+ 1001 80A0 SAR AR0,*+ 1002 8180 SAR AR1,* 1003 B001 LAR AR0,#1h 1004 00E0 LAR AR0,*0+ /*关总中断*/ asm(“ setc INTM“); 1005 BE41 SETC INTM /*抑制符号位扩展*/ asm(“ clrc SXM“); 1006 BE46 CLRC SXM /*累加器中结果正常溢出*/ asm(“ clrc OVM“); 1007 BE42 CLRC OVM,/*禁止看门狗*/ *WDCR=0x00E8; 1008 BD00 LDP #100h 1009 0300 LAR AR3,0h 100A B9E8 LACL #e8h 100B 8B8B MAR *,AR3 100C 908C SACL *,0,AR4 /*CLKIN=10M,CLKOUT=40M*/ *SCSR1=0x0000; 100D 0401 LAR AR4,1h 100E B900 LACL #0h 100F 9089 SACL *,0,AR1 1010 7C02 SBRK #2h 1011 0090 LAR AR0,*- 1012 7680 PSHD * 1013 EF00 RET,void delay() 1014 8AA0 POPD *+ 1015 80A0 SAR AR0,*+ 1016 8180 SAR AR1,* 1017 B004 LAR AR0,#4h 1018 00EA LAR AR0,*0+,AR2 unsigned int k; for(k=0;k60000;k+); 1019 B900 LACL #0h 101A B201 LAR AR2,#1h 101B 8BE0 MAR *0+ 101C 9080 SACL *,0 101D 6980 LACL * 101E E302 BCND 1020h,NOV 1020 8BA0 MAR *+ 1021 90A0 SACL *+,0 1022 9890 SACH *-,0 1023 73A0 LT *+,1024 C001 MPY #1h 1025 7580 LPH * 1026 BE46 CLRC SXM 1027 BF80 LACC #ea60h,0 1029 BE05 SPAC 102A E302 BCND 1030h,NOV 102C E304 BCND 104

温馨提示

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

评论

0/150

提交评论