DSP2833X_C语言+程序烧写.ppt_第1页
DSP2833X_C语言+程序烧写.ppt_第2页
DSP2833X_C语言+程序烧写.ppt_第3页
DSP2833X_C语言+程序烧写.ppt_第4页
DSP2833X_C语言+程序烧写.ppt_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

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

文档简介

DSP原理与应用 The Technology & Applications of DSPs,北京交通大学 电气工程学院 夏明超 郝瑞祥 万庆祝 mchxia haorx qzhwan,第二章:DSP系统开发,第2.1节 概述 第2.2节 DSP汇编语言概述及汇编程序设计 第2.3节 DSP C语言程序设计 第2.4节 DSP C与汇编混合编程 第2.5节 DSP程序烧写 习题,第2.1节 概述,汇编语言: 开发的效率高,程序执行速度快,而且可以合理利用芯片的硬件资源 开发难度较大,开发周期长,可读性和可移植性差。 C语言开发: 具有兼容性和可移植的优点,有利于缩短开发周期和减少开发难度 在运算量较大的情况下,C代码的效率还是无法和手工编写的汇编代码的效率相比,比如FFT运算, C和汇编的混合编程则可以充分利用前两者的优点,以达到最佳利用DSP资源的目的。 C和汇编语言混合编程必须遵循相关函数调用规则和寄存器调用规则,否则会带来意想不到的问题。,第2.1节 概述,CCS开发实例演示,第二章:DSP系统开发,第2.1节 概述 第2.2节 DSP汇编语言概述及汇编程序设计 第2.3节 DSP C语言程序设计 第2.4节 DSP C与汇编混合编程 第2.5节 DSP程序烧写 习题,第2.2节 DSP汇编语言概述及汇编程序设计,汇编语言: 累加,算术计算和逻辑运算 辅助寄存器和数据页操作 TREG,PREG和乘法指令 直接内存访问指令(DMA)和IO操作指令 程序空间访问指令 跳转指令、寄存器操作指令 浮点运算指令 汇编程序设计: 生成可执行代码过程 示例文件,第2.2.1累加,算术计算和逻辑运算,第2.2.1累加,算术计算和逻辑运算,第2.2.1累加,算术计算和逻辑运算,第2.2.1累加,算术计算和逻辑运算,第2.2.2辅助寄存器和数据页操作,第2.2.2辅助寄存器和数据页操作,第2.2.3 TREG,PREG和乘法指令,第2.2.3 TREG,PREG和乘法指令,第2.2.3 TREG,PREG和乘法指令,第2.2.4直接内存访问(DMA)和IO操作指令,第2.2.5程序空间访问指令,第2.2.6 跳转指令,第2.2.7 寄存器操作指令,第2.2.7 寄存器操作指令,第2.2.7 寄存器操作指令,第2.2.8 浮点运算指令,浮点数简介(IEEE754) 单精度浮点数:1位符号位,8位指数,23位有效数,IEEE754-IEEE Standard 754 for Binary Floating Point Arithmetic,单精度浮点数范围:3.4028235*1038 在此范围内也无法精确表述所有浮点数 精度:1.19209290 * 10-38 可精确表述的数必须可以用2的指数幂次组合描述,第2.2.8 浮点运算指令,浮点数简介(IEEE754) 单精度浮点数:1位符号位,8位指数,23位有效数,IEEE754-IEEE Standard 754 for Binary Floating Point Arithmetic,例:00111111 01100110 01100110 01100110 16进制为:0X3F666666 整形数为1063675494 单精度下:符号位0(+) 指数位E(01111110) 2=126,e=-1 尾数1100110 01100110011001102 1.799999952316284179687510 实际值0.89999997615814208984375,第2.2.8 浮点运算指令,浮点数简介(IEEE754) 单精度浮点数:1位符号位,8位指数,23位有效数,IEEE754-IEEE Standard 754 for Binary Floating Point Arithmetic,单精度运算精度:加、减、乘、除、平方根、余数、将浮点格式的数舍入为整数值、在不同浮点格式之间转换、在浮点和整数格式之间转换以及比较。 四种舍入方向:向最近数方向,向负无穷大,向正无穷大以及向0。 五种类型的浮点异常是:无效运算、被零除、上溢、下溢和不精确。 *常犯错误: f=0,应该为-efe。,第2.2.8 浮点运算指令,8个浮点结果寄存器(RnH) 浮点状态寄存器(STF) 重复块寄存器,TMS320C28x Floating Point Unit and Instruction Set Reference Guide,第2.2.8 浮点运算指令,算术运算 ABSF32:32位浮点数绝对值运算 ADDF32:32位浮点数加法运算 SUBF32:32位浮点数减法运算 MPYF32:32位浮点数乘法运算, MACF32:32位浮点数乘加运算 EINVF32:32位浮点数倒数运算(1/X) EISQRTF32:32位浮点数开方倒数运算(1/sqrt(x) NEGF32:32位浮点数取反 CMPF32,MAXF32,MINF32:32位浮点数比较、最大、最小值,第2.2.8 浮点运算指令,整数浮点数转换 F32TOI16,F32TOI16R:32位浮点数转为16位整数 F32TOI32:32位浮点数转为32位整数 F32TOUI16,F32TOUI16R:32位浮点数转为16位无符号整数 F32TOUI32:32位浮点数转为32位无符号数整数 I16TOF32:16位整数转为32位浮点数 I32TOF32:32位整数转为32位浮点数 UI16TOF32:16位无符号整数转为32位浮点数 UI32TOF32:32位无符号整数转为32位浮点数,第2.2.8 浮点运算指令,寄存器操作 MOV16:16位浮点数内存操作 MOV32:32位浮点数内存操作 MOVD32:32位浮点数内存操作及复制 MOVF32:32位浮点数立即数内存操作 MOVI32:32位浮点数立即数(16进制)内存操作 MOVIZ32.MOVIZF32:浮点寄存器高16位操作 MOVXI:浮点寄存器低16位操作 MOVST0:STF内容放至ST0,第2.2.8 浮点运算指令,寄存器操作 TESTTF:测试STF中标志位 SETFLAG:STF中标志位置位 SAVE FLAG:保存STF寄存器内容 ZERO,ZEROA:浮点寄存器清零 SWAPF:浮点寄存器内容交换 PUSH:压栈 POP:出栈 RESTORE:恢复 RPTB:重复执行,第2.2.9 汇编程序设计-生成可执行代码,第2.2.9 汇编程序设计-示例文件,.cmd文件:链接控制文件,用于定义目标的程序,数据,I/O存储映射.,MEMEORY PAGE 0: /* Program Memory */ ZONE0: origin = 0x004000, length = 0x001000 /* XINTF zone 0 */ RAML0: origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 */ RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */ RAML2 : origin = 0x00A000, length = 0x001000 /* on-chip RAM block L2 */ RAML3 : origin = 0x00B000, length = 0x001000 /* on-chip RAM block L3 */ ZONE6A : origin = 0x100000, length = 0x00FC00 /* XINTF zone 6 - program space*/ ZONE7 : origin = 0x200000, length = 0x100000 /* XINTF zone 7 */ FLASHH : origin = 0x300000, length = 0x008000 /* on-chip FLASH */ ,第2.2.9 汇编程序设计-示例文件,.cmd文件:链接控制文件,用于定义目标的程序,数据,I/O存储映射.,SECTIONS /* Allocate program areas: */ .cinit : FLASHA PAGE = 0 .pinit : FLASHA, PAGE = 0 .text : FLASHA PAGE = 0 codestart : BEGIN PAGE = 0 ramfuncs : LOAD = FLASHD, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0 csmpasswds : CSM_PWL PAGE = 0 csm_rsvd : CSM_RSVD PAGE = 0 /* Allocate uninitalized data sections: */ .stack : RAMM1 PAGE = 1 .ebss : RAML4 PAGE = 1 .esysmem : RAMM1 PAGE = 1 ,第2.2.9 汇编程序设计-示例文件,.h文件:标号,地址,中断向量等定义,; File name: 280x.h IMR .set 0004h ; Interrupt Mask Register IFR .set 0006h ; Interrupt Flag Register ; System configuration and interrupt registers SCSR1 .set 7018h ; System Control Peripheral Interrupt Acknowledge register 2,; File name: vector.h .sect “vectors“ RSVECT B START ; Reset Vector INT1 B GISR1 ; Interrupt Level 1 INT2 B GISR2 ; Interrupt Level 2 INT3 B GISR3 ; Interrupt Level 3 INT4 B GISR4 ; Interrupt Level 4 INT5 B GISR5 ; Interrupt Level 5 INT6 B GISR6 ; Interrupt Level 6 RESERVED B PHANTOM ; Reserved SW_INT8 B PHANTOM ; Software Interrupt SW_INT9 B PHANTOM ; Software Interrupt SW_INT10 B PHANTOM ; Software Interrupt SW_INT11 B PHANTOM ; Software Interrupt SW_INT12 B PHANTOM ; Software Interrupt SW_INT13 B PHANTOM ; Software Interrupt SW_INT14 B PHANTOM ; Software Interrupt SW_INT15 B PHANTOM ; Software Interrupt SW_INT16 B PHANTOM ; Software Interrupt TRAP B PHANTOM ; Trap vector NMI B NMI ; Nonmaskable Interrupt EMU_TRAP B PHANTOM ; Emulator Trap SW_INT20 B PHANTOM ; Software Interrupt SW_INT21 B PHANTOM ; Software Interrupt SW_INT22 B PHANTOM ; Software Interrupt SW_INT23 B PHANTOM ; Software Interrupt SW_INT24 B PHANTOM ; Software Interrupt,第2.2.9 汇编程序设计-示例文件,.asm文件: 程序文件,* File Name: SPI.asm .include 280xA.h .include vector.h .bss GPR0,1 ;General purpose registers. .bss GPR3,1 KICK_DOG .macro ;Watchdog reset macro LDP #00E0h SPLK #05555h, WDKEY SPLK #0AAAAh, WDKEY LDP #0h .endm ; M A I N C O D E starts here .text START: LDP #0 SETC INTM SPLK #0h,GPR3 OUT GPR3,WSGR CLRC SXM CLRC OVM CLRC CNF LDP #WDCR7 SPLK #006Fh,WDCR KICK_DOG LDP #SCSR17 SPLK #0020h,SCSR1,第二章:DSP程序设计,第2.1节 概述 第2.2节 DSP汇编语言概述及汇编程序设计 第2.3节 DSP C语言程序设计 第2.4节 DSP C与汇编混合编程 第2.5节 DSP程序烧写 习题,第2.3节 DSP C语言程序设计,支持ANSI C: 提供相应的编译器和优化工具 对ANSI C进行了限定和扩展 运行库: 字符串操作 动态地址分配 数据转换 ,第2.3节 DSP C语言程序设计,变量和标识: 变量和标识符长度100个字符,区分大小写 变量和标识符的符号集为ASCII,不支持多字节符号(如汉字)。 字符或字符串常量中的16进制ESC码(特殊字符,如0X07)可能会有32位的值。 多字符的字符变量最后一个有效,如abc是c 数据类型: Size_t(sizeof的结果)定义为unsigned int Ptrdiff_t(指针加减结果)定义为int 所有的整数类型(char, short, int, 以及这些类型的无符号型)都是相同类型,并代表16位的二进制值. Long和unsigned long代表32位二进制值.,第2.3节 DSP C语言程序设计,数据类型: 有符号数是用二进制补码表示. 数据单元的基础是字(16位),BYTE和WORD一样 char是有符号类型,等同于int 枚举型(enum)用16位值表示,等同于int 浮点类型(float,double)是相同的,遵循TMS320C2x/C2xx/C5x的32位浮点类型. Long 和float的数据存储格式为低有效字存储在低地址的方式. Long long 和long double是64位的.,第2.3节 DSP C语言程序设计,数据类型:,第2.3节 DSP C语言程序设计,类型转换: 浮点数转为整数为取整截断 指针类型(pointer)和int可以自由转换 far pointer 为22位有效位 表达式: 有符号整数相除,商符号由两个数共同决定,余数符号同被除数 10/-3=-3,余1; -10/3=-3余-1 有符号数右移为算术右移,符号位不变,第2.3节 DSP C语言程序设计,C访问16位乘法结果的高16位: int m1,m2; int result; result=(long)m1*(long)m2) 16; 浮点数:32bits FPU +,-, 比较(,=,=,=,!=) 同int,long的相互转换 以上操作均通过相应的汇编指令(即内部硬件机制)实现。(无FPU时处理浮点运算需要通过浮点数运算库,运算效率低),第2.3节 DSP C语言程序设计,直接访问寄存器 通过cregister语句实现: extern cregister volatile unsigned int IFR; IFR = 0;,第2.3节 DSP C语言程序设计,预处理: 预处理忽略所有不支持的#pragma指令 支持如下#pragma: . CODE_ALIGN CODE_SECTION DATA_ALIGN DATA_SECTION FAST_FUNC_CALL FUNC_EXT_CALLED INTERRUPT MUST_INTERATE UNROLL 预处理必须在函数外,在所有声明之前,第2.3节 DSP C语言程序设计,CODE_ALIGN: 为某一段程序指定特定的代码存储边界,以保证某函数代码存于特定位置。 #pragma CODE_ALIGN(func, constant) #pragma CODE_ALIGN(constant) Constant必须是2的幂次,以保证内存边界问题,第2.3节 DSP C语言程序设计,CODE_SECTION: 为某一段程序指定特定的代码存储段,以便单独分配存储空间 #pragma CODE_SECTION(symbol, “section_name”) #pragma CODE_SECTION(“section_name”) 例:#pragma CODE_SECTION(fn, “my_sect”) int fn(int x) return 0; 汇编结果: .file “CODEN.c” .sect ”my_sect” .global _fn .sym _fn,_fn,36,2,0 .func 3,第2.3节 DSP C语言程序设计,DATA_ALIGN: 为某一段数据指定特定的代码存储边界,以保证特定数据存于特定位置。 #pragma DATA_ALIGN(symbol,constant) #pragma DATA_ALIGN(constant) Constant必须是2的幂次,以保证内存边界问题,第2.3节 DSP C语言程序设计,DATA_SECTION: 为某一段数据指定特定的数据存储段,以便单独分配存储空间,例如同.bss内存分开,或单独分配连续的存储空间 #pragma DATA_SECTION(symbol, “section_name”) 例:#pragma DATA_SECTION(bufferB, “BufferB_sect”) char bufferA512; char bufferB512; 汇编结果: .global _bufferA .bss _bufferA, 512, 4 .global _bufferB _bufferB: .usect “BufferB_sect”,512,4,第2.3节 DSP C语言程序设计,SECTIONS VECTORS: PM PAGE 0 .TEXT : PM PAGE 0 .BSS : BLK_B2 PAGE 1 .DATA : BLK_B1 PAGE 1 BufferB_sect : SARAM_D PAGE 1 ,第2.3节 DSP C语言程序设计,FAST_FUNC_CALL: 指明某一函数调用时采用快速函数调用(FFC)机制,而不是使用普通函数调用流程: FFC进栈出栈及函数返回有所不同,调用更快速。 #pragma FAST_FUNC_CALL (func) 这类函数返回时的asm代码必须是: LB *XAR7,第2.3节 DSP C语言程序设计,FUNC_EXT_CALLED: 指明某一未使用的函数,使其不会在C优化时被删除。 #pragma FUNC_EXT_CALLED (func),第2.3节 DSP C语言程序设计,INTERRUPT: 指明函数为中断处理函数(函数返回机制使用IRP) #pragma INTERRUPT ( func ); #pragma INTERRUPT; #pragma INTERRUPT (func, HPI|LPI); #pragma INTERRUPT ( HPI|LPI);) FPU有高优先级中断(HPI)和低优先级中断(LPI)处理机制,通过此预编译实现。,第2.3节 DSP C语言程序设计,MUST_ITERATE: 指明循环必须被执行的次数,以防止循环被优化掉 #pragma MUST_ITERATE (min,max,mult); 有时通过空循环建立必须的延时,单在程序优化时会被自动优化掉。 例如: For( i=0; i100; i+) 编译器在优化时会去掉此循环,使用MUST_ITERATE可以保证此循环执行。,第2.3节 DSP C语言程序设计,嵌入汇编代码: asm(“assembler text”); 例如: asm(“clrc intm”); 编译器不会进行语法检查,直接生成汇编代码 嵌入的汇编指令应不破坏C语言的环境,例如堆栈结构、当前AR等,或不可控的跳转等。 带asm语句的代码,使用优化器时须小心,因为优化器可能会改变asm语句附近的代码顺序,而引起不期望的结果.,第2.3节 DSP C语言程序设计,访问IO:先定义io端口号,然后使用 ioport type porthex_num type用16位数据表示 例: ioport int portd0ff;/*IO端口d0ff*/ portd0ff=a; /*输出a值到portd0ff*/ b=portd0ff; /*读输入portd0ff值到b*/ IN *+FP7,*(0d0ffH) ioport变量定义必须在文件头位置定义,不能在函数中定义.ioport变量的使用跟普通变量一样。 call(portd0ff); a=portd0ff+b; portd0ff+=a;,第2.3节 DSP C语言程序设计,中断处理:查询式和回调(中断服务程序)两种方式。 查询式: 程序中查询中断标志及相应的寄存器,判断中断的发生并进行相应处理。 优点:流程易于控制,不会发生中断嵌套问题,一般不会丢失中断。 缺点:中断实时性差。,第2.3节 DSP C语言程序设计,回调式: 为中断指定回调处理函数(中断服务程序),由CPU中断处理机制自动调用。 优点:中断实时性好,程序结构简洁,类似于windows的消息驱动机制。 缺点:处理不好容易造成中断嵌套或丢失中断,造成逻辑混乱。,第2.3节 DSP C语言程序设计,中断服务函数:两种方式定义中断服务函数。 a)c_intd方式定义的函数,c_int00作系统复位函数 b)Interrupt关键词定义的函数。 例: void c_int01() interrupt void timer2_isr() ,第2.3节 DSP C语言程序设计,中断服务函数与相应的中断对应: 通过vectors字段对应: * cvectors.asm .ref _c_int00, _timer2_isr .sect ”vectors” rset: B _c_int00 ;00h reset int1: B int1 ;02h INT1 int2: B int2 ;04h INT2 int3: B _timer2_isr ;06h INT3 int4: B int4 ;08h INT4,第2.3节 DSP C语言程序设计,cmd文件: MEMORY PAGE 0: /* Program Memory */ VECS: org=00000h, len=00040h /* internal FLASH */ SECTIONS /* Sections generated by the Ccompiler */ .text: FLASH PAGE 0 /* initialized */ /* Sections declared by the user */ vectors: VECS PAGE 0 /* initialized */ ,第2.3节 DSP C语言程序设计,中断服务函数: 中断服务函数类型必须是void。 中断服务函数要尽量短小,减少中断服务占用时间,以避免发生中断嵌套或丢中断。 多个中断可以共用一个中断服务函数,除了int00。 注意IMR、INTM等中断控制量的设置。 中断服务函数可能和某些编译选项和优化冲突,需注意协调。,第2.3节 DSP C语言程序设计,中断服务函数: 中断服务函数可以像其他函数一样访问全局变量、分配局部变量和调用其它函数。 进入中断服务函数,编译器自动保护与运行上下文相关的寄存器,并在中断服务函数结束时恢复运行环境。但并不保存所有寄存器 中断服务程序可以任意修改不被保护的寄存器,如外设控制寄存器。 中断服务函数也可以被其他c程序调用,但效率较差。 c_int00是系统保留的复位中断函数,不会被调用,也不需要保护任何寄存器。 中断服务函数入口地址放在相应的中断向量处。,第2.3节 DSP C语言程序设计,第二章:DSP程序设计,第2.1节 概述 第2.2节 DSP汇编语言概述及汇编程序设计 第2.3节 DSP C语言程序设计 第2.4节 DSP C与汇编混合编程 第2.5节 DSP程序烧写 习题,第2.4节 DSP C与汇编混合编程,C语言和汇编语言混合编程的四种方法 (1) 独立编写汇编程序和C程序,分开编译或汇编成各自的目标代码模块,再用链接器将二者链接起来。这种方法比较灵活,但是设计者必须自己维护各汇编模块的入口和出口代码,自己计算传递的参数在堆栈中的偏移量,工作量较大,但是能做到对程序的绝对控制。 (2) 在C程序中使用汇编程序中定义的变量和常数。 (3) 在C程序中内嵌汇编语句。这种方法可以实现C语言无法实现的一些硬件控制功能,如修改中断控制寄存器。 (4) 将C语言编译生成相应的汇编代码,手工修改和优化C编译器生成的汇编代码。采用这种方法可以控制C编译器,从而产生具有交叉列表的汇编程序,而设计者可以对其中的汇编语句进行修改,然后对汇编程序进行编译,产生目标文件。 后3种方法由于在C中直接嵌入了汇编语言,易造成程序混乱,破坏C环境,甚至导致程序崩溃,而开发者又很难对不良结果进行预期和有效控制。而如果采用第一种方法,只要遵循有关C语言函数调用规则和寄存器规则,就能预见到程序运行的结果,保证程序正确。,第2.4节 DSP C与汇编混合编程,DSP C编译器将存储空间分为两个线性空间: 程序存储空间,存储可执行码 数据存储空间,存储程序执行过程中的数据和堆栈 编译器将存储空间以分段(section)的方式分配和管理。用户以不同的方式分配存储器,可以形成不同的系统配置,连接器将各个段连接在一起形成最终完整的存储器结构。 *注意:是由连接器决定存储器影射而不是由编译器。,第2.4节 DSP C与汇编混合编程,已初始化的段:,第2.4节 DSP C与汇编混合编程,未初始化的段:,汇编自动生成.text,.bss和.data段。C编译器不使用.data段。,第2.4节 DSP C与汇编混合编程,用户定义的段: 用户使用CODE_SECTION,DATA_SECTION定义的段,如上面的 my_sect, BufferB_sect,第2.4节 DSP C与汇编混合编程,/*/ / Linker command file link.cmd /*/ -c /* ROM autoinitialization model */ -m example.map /* Create a map file */ -o example.out /* Output file name */ main.obj /* First C module */ sub.obj /* Second C module */ asm.obj /* Assembly language module */ l rts25.lib /* Runtimesupport library */ l matrix.lib /* Object library */,MEMORY PAGE 0 : PROG: origin = 30h, length = 0EFD0h PAGE 1 : DATA: origin = 800h length 0E800h SECTIONS .text PROG PAGE 0 .cinit PROG PAGE 0 .switch PROG PAGE 0 .bss DATA PAGE 1 .const DATA PAGE 1 .sysmem DATA PAGE 1 .stack DATA PAGE 1 ,第2.4节 DSP C与汇编混合编程,系统堆栈: DSP 硬堆栈:8级,用于保存函数调用、中断服务函数等的返回地址,也可以用PUSH等保存其他变量 C编译器可以生成一定大小的软堆栈: 分配局部变量 传递函数参数 保存处理器状态 保存函数返回地址 保存临时结果 保存寄存器内容,第2.4节 DSP C与汇编混合编程,系统堆栈: 编译器利用两个辅助寄存器来管理堆栈: SP堆栈指针(Stack Pointer),指向当前堆栈顶。 XAR2帧指针(FP, Frame Pointer),指向当前帧的起始点,每个函数都会在堆栈顶部建立一个新的帧,用来保存局部或临时变量。 C语言环境自动操作这两个寄存器。如果编写用到堆栈的汇 编语言程序,一定要注意正确使用这两个寄存器。 默认堆栈大小是1k。用-stack连接选项可以指定软件堆栈的大小,用C编写DSP程序一定注意保留足够的堆栈空间! 注意:编译器不会检查堆栈溢出情况,堆栈溢出会破坏DSP 运行环境,导致程序失败。编写DSP程序和配置DSP 存储器资源要注意防止堆栈溢出的发生。,第2.4节 DSP C与汇编混合编程,动态内存分配: TMS320C2x/C2xx/C5x C语言可调用malloc、calloc或realloc 函数动态申请内存,申请的内存将分配在.sysmem块。 动态分配的内存只能通过指针进行访问,动态分配使用后可以释放,这样可以用于其它目的。将大数组通过这种方式来分配可以节省.bss块的空间。 通过连接器的-heap选项可以定义.sysmem块。 unsigned int data100; unsigned int *data; data =(unsigned int *) malloc (100 * sizeof (unsigned int);,第2.4节 DSP C与汇编混合编程,寄存器使用规则: TMS320C2x/C2xx/C5x运行环境对寄存器的使用有严格的要求,编写涉及到寄存器的汇编程序,必须严格遵守这些规则,否则可能造成系统工作异常。寄存器规则规定了编译器如何使用寄存器,和寄存器在函数调用的过程中如何进行保护。 寄存器按照保护方式分为两种: 调用保存(save on call),调用其它函数的函数负责保存这些寄存器的内容。 入口保存(save on entry),被调用的函数负责保存这些寄存器的内容。 注:无论是否使用优化编译,都必须遵守这些寄存器规则。,第2.4节 DSP C与汇编混合编程,寄存器使用规则:,第2.4节 DSP C与汇编混合编程,寄存器使用规则:,第2.4节 DSP C与汇编混合编程,状态寄存器使用:,第2.4节 DSP C与汇编混合编程,函数调用规则: TMS320C2x/C2xx/C5x运行环境对函数调用有严格的要求,要调用C函数或要被C程序调用的汇编语言程序必须遵守这些规则,否则可能破坏C运行环境,造成程序失败。 当进行函数调用时,调用者要将传递参数压入系统堆栈传给被调用的函数,并将函数返回地址压栈。 被调用的函数要在函数运行结束时将返回值放在累加器里返回给调用者函数。 函数参数及返回地址等都是通过堆栈传递的,要编写汇编函数,必须明确函数调用的过程中堆栈的变化和应该进行的处理,函数调用过程中堆栈情况:,第2.4节 DSP C与汇编混合编程,C语言调用函数时的工作: 将参数反向压入堆栈(最右端的参数最先压栈,最左端的参数最后压栈),这样,当函数被调用时,最左端的参数会在堆栈的最顶部。 使用被调用函数。 被调用函数返回前处理各寄存器。 当被调用函数运行结束时,调用者函数要将压入堆栈的参数弹出以恢复堆栈状态。 注:如果用C程序调用汇编语言程序,C编译器会自动产生代码完成这些工作。,第2.4节 DSP C与汇编混合编程,C语言函数被调用时的工作: 将返回地址从硬件堆栈弹出,压入软件堆栈。 将FP(SP)压入软件堆栈。 分配局部帧(Frame)。 如果函数中要修改AR6、AR7,将它们压入堆栈,其它寄存器不用进行保护就可以进行修改。 实现函数功能。 如果函数返回标量数据,将它放入累加器。 如果保护了AR6、AR7,恢复这两个寄存器。 删除局部帧。 恢复FP(SP)。 将返回地址从软件堆栈中弹出,压入硬件堆栈。 返回。,第2.4节 DSP C与汇编混合编程,POPD *+ ; 返回地址从硬堆栈中弹出,压入软堆栈(由AR1指示) SAR AR0,*+ ; AR0(FP)入软堆栈 SAR AR1,* ; AR1(SP)入软堆栈 LARK AR0,SIZE ; FP=局部帧大小 LAR AR0,*0+ ; FP = SP, SP += SIZE: 分配局部帧 SAR AR6,*+ ; 保存AR6 SAR AR7,*+ ; 保存AR7 . ; 函数功能部分 MAR *,AR1 ; 设置当前AR为AR1 MAR *- ; LAR AR7,*- ; 恢复AR7 LAR AR6,*- ; 恢复AR6 SBRK SIZE+1 ; 释放局部帧(恢复AR1(SP) LAR AR0,*- ; 恢复AR0(FP) PSHD * ; 返回地址压入硬堆栈 RET ; 返回,第2.4节 DSP C与汇编混合编程,一些特殊的情况: 返回一个结构:当函数的返回值为一个结构时,调用者负责分配存储空间,并将存储空间地址作为最后一个输入参数传递给被调用函数。被调用函数将要返回的结构拷贝到这个参数所指向的内存空间。 不将返回地址移动到软件堆栈:当被调用函数不再调用其它函数,或者确定调用深度不会超过8级,可以不用将返回地址移动到软件堆栈。 不分配局部帧:如果函数没有输入参数,不使用局部变量,就不需要修改XAR2(FP),因此也不需要对其进行保护。,第2.4节 DSP C与汇编混合编程,C与汇编混合: C程序调用汇编函数必须要满足前面介绍的调用规则和寄存器规则,C程序可以访问汇编语言定义的变量或调用汇编语言函数,同样汇编语言也可以访问C程序定义的变量或调用C函数。用C程序调用汇编函数有以下注意事项: 所有的函数(不论用C编写还是用汇编语言编写)都必须满足前面介绍的寄存器规则。 对于一些寄存器,如果函数要修改其内容,则必须事先对其进行保护。这些寄存器包括:XAR2(FP),SP,AR6,AR7。其它的寄存器可以不用保护自由使用。,第2.4节 DSP C与汇编混合编程,注意事项: 如果函数改变了状态寄存器某些有假定值的位,则必须在函数结束前恢复其原有值。尤其要注意ARP必须为AR1。 中断服务程序必须保护所有其用到的寄存器。 long型和float型变量在存储器中的存储方式为低有效位在低端地址。 函数返回值要通过累加器进行传递。 编译器会在所有对象的名称前面加下横线“_”,因此汇编语言模块定义对象名称时也要以下横线为前缀,才能使定义的对象可以被C代码访问。例如C语言对象x在汇编语言中就是_x。汇编语言可以使用任何不带下横线前缀的变量而不会和C语言对象冲突。 任何汇编语言定义的对象,如果要被C程序访问,则必须用.global修饰。同样任何C语言定义的对象,如果要被汇编语言访问,也必须以.global修饰。 C和汇编互相调用函数时,需保证参数压栈和出栈的一致性。,第2.4节 DSP C与汇编混合编程,第2.4节 DSP C与汇编混合编程,C中访问汇编变量:通常有两种方式。 1.访问.bss块中的变量: 将要访问的变量定义在.bss块中。 用.golbal修饰要访问的变量。 在汇编语言中以下横线“_”为前缀声明要访问的变量。 在C语言中将变量声明为外部变量(extern),就可以进行正常访问。 C: extern int var; var = 1; asm: .bss _var,a1,

温馨提示

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

评论

0/150

提交评论