Presentation is loading. Please wait.

Presentation is loading. Please wait.

C54x的程序设计有两种语言:汇编语言和C语言。

Similar presentations


Presentation on theme: "C54x的程序设计有两种语言:汇编语言和C语言。"— Presentation transcript:

1 C54x的程序设计有两种语言:汇编语言和C语言。
汇编语言程序效率高,硬件定时准确,但不够直观 ,设计周期较长,可移植性和可维护性差 山东大学生物医学工程刘忠国

2 C语言,可移植性好,可维护性好 ,配合优化编码器,可生成代码执行效率较高的可执行程序。
第5章 C54x高级C语言程序设计 C语言,可移植性好,可维护性好 ,配合优化编码器,可生成代码执行效率较高的可执行程序。 参考:TMS320C54x Optimizing C_C++ Compiler User‘s Guide.pdf, SPRU103G,2002 ,TI官网 山东大学生物医学工程刘忠国

3 一般代码用高级语言编写,缩短开发周期,还可使汇编语言编写的程序被高级语言所调用。
第5章 C54x高级C语言程序设计 一般代码用高级语言编写,缩短开发周期,还可使汇编语言编写的程序被高级语言所调用。 山东大学生物医学工程刘忠国

4 5.1 C54x C语言介绍 5.2 C54x C语言编程 5.3 C54x C代码优化 目录: 第5章 C54x高级C语言程序设计
山东大学生物医学工程刘忠国

5 第5章 C54x高级C语言程序设计 5.1 C54x C语言介绍 1. C54x C编译器支持美国国家标准委员会 (ANSI)开发的C语言标准,C54x C继承了大多数的ANSI C的语法规则 。 2. ANSI C和C54x C也有许多不同之处 。 山东大学生物医学工程刘忠国

6 5.1 C54x C语言介绍 5.1.1 C54x C与ANSI C的相同点 只要与硬件不是特别相关的部分都是它们的相同点。
山东大学生物医学工程刘忠国

7 5.1 C54x C语言介绍 5.1.1 C54x C与ANSI C的相同点 以函数作为基本单位。 函数的定义和引用方式完全一致。
大部分变量、常量、数组、结构体、枚举、联合体、指针的定义语法结构也完全一致。 山东大学生物医学工程刘忠国

8 5.1 C54x C语言介绍 5.1.1 C54x C与ANSI C的相同点 局部变量、全局变量、静态变量、动态变量等基本定义也一致。
宏定义、宏展开、宏调用的基本思想甚至语法规则上基本一致。 山东大学生物医学工程刘忠国

9 5.1 C54x C语言介绍 1.常量定义 格式: const 类型 符号=数值 ; 5.1.1 C54x C与ANSI C的相同点
例5-1:const short d1=8 ; C54x C也可以用下面的方法定义符号常量: #define Vmax 1; //程序中出现Vmax时均会以1来代替 山东大学生物医学工程刘忠国

10 5.1 C54x C语言介绍 2.变量定义 5.1.1 C54x C与ANSI C的相同点 1) 一般变量的定义: 格式: 类型 符号 ;
格式: 类型 符号 ; int pi_1; float fl_1; double d_dat; 2) 扩展变量的定义: struct, enum, union 3) 自定义变量的定义: 格式: typedef 已有类型 新数据类型 ; 山东大学生物医学工程刘忠国

11 5.1 C54x C语言介绍 1) 一般变量的定义: 例5-2: char ch_1 ;//定义一个字符变量,名字为ch_1
short sh_1;//定义了一个短整型变量,名字为sh_1 long l_dat1;//定义了一个长整型变量,名字为l_dat1 int *pi_1 ; //定义了一个指向整型数据的指针变量,名字为pi_1 short sh_a[10] ; //定义了一个短整型数组,数组的长度为10 山东大学生物医学工程刘忠国

12 5.1 C54x C语言介绍 2) 扩展变量的定义: struct str_t //定义一个结构类型str_t { short sh_a;
long l_b; float f_c; }; struct str_t str_a; //定义一个str_t型结构变量str_a。 enum TorF{false,true}; //定义一个枚举变量TorF union un_v{char c;short s;int i;long l};//定义了一个 联合体变量un_v。 山东大学生物医学工程刘忠国

13 5.1 C54x C语言介绍 3) 自定义变量的定义: 例5-3: typedef unsigned short US_DATA ;
US_DATA ush_t; 等同于: unsigned short ush_t; 山东大学生物医学工程刘忠国

14 5.1 C54x C语言介绍 3.函数的定义和组织 5.1.1 C54x C与ANSI C的相同点
C54x C和ANSI C一样,整个程序有一个主函数(main函数)和零个或者多个子函数构成。 山东大学生物医学工程刘忠国

15 3.函数的定义和组织 float sub_cac(float a, float b);//子函数声明
void main() //主函数定义,整个程序内有且只有一个 { float a=1; float b=2; float c; c=sub_cac(a,b); //子函数调用 … … while(1) //死循环,等待外部事件发生 { } } 山东大学生物医学工程刘忠国

16 3.函数的定义和组织 float sub_cac(float e, float f)//子函数定义 { float g; g=e*f;
return g; } 山东大学生物医学工程刘忠国

17 5.1 C54x C语言介绍 5.1.2 C54x C与ANSI C的不同点 1.所处理数据的性质不同 2.数据的输入输出设备不同
3.“死循环”的对待上不同 4.语法及数据结构细节上的不同 山东大学生物医学工程刘忠国

18 采集好的、数据量较多的、以数据块为单位,实时性要求不高
5.1.2 C54x C与ANSI C的不同点 1.所处理数据的性质不同 ANSI C处理的数据类型 采集好的、数据量较多的、以数据块为单位,实时性要求不高 C54x C处理的数据类型 有严格的实时性要求,要求对于数据的处理时间要小于数据的采样时间间隔。 山东大学生物医学工程刘忠国

19 输入: 硬盘、内存等存储介质或键盘、实时采集数据少。输出是显示器、通信口或实时输出
5.1.2 C54x C与ANSI C的不同点 2.数据的输入输出设备不同 ANSI C 输入: 硬盘、内存等存储介质或键盘、实时采集数据少。输出是显示器、通信口或实时输出 C54x C 实时采集数据,处理结果给其他计算机或者芯片(如MCU、ARM等)使用,或者通过D/A输出。 山东大学生物医学工程刘忠国

20 怕程序内部出现“死循环”,或程序处理不当导致发生,解决的办法只有重启计算机。
5.1.2 C54x C与ANSI C的不同点 3.“死循环”的对待上不同 ANSI C程序 怕程序内部出现“死循环”,或程序处理不当导致发生,解决的办法只有重启计算机。 C54x C程序 在main函数将所有的初始化任务都完成后安排一个“死循环”语句,如:While(1){ }。 山东大学生物医学工程刘忠国

21 为什么“死循环”的对待上不同? 5.1.2 C54x C与ANSI C的不同点
面向PC机的ANSI C程序属于应用程序,架构在操作系统,不和硬件直接打交道,对硬件的操作实际上是通过操作系统的系统调用配合相应的驱动程序来实现。 山东大学生物医学工程刘忠国

22 5.1.2 C54x C与ANSI C的不同点 而面向DSP的C54x C程序一般不是架构在操作系统之上,对硬件的操作也都是直接的。
应用程序 操作系统 驱动/BSP 硬件 应用程序 硬件 图5-2 DSP的软件结构 山东大学生物医学工程刘忠国

23 5.1 C54x C语言介绍 5.1.2 C54x C与ANSI C的不同点 4.语法及数据结构细节上的不同
山东大学生物医学工程刘忠国

24 4.语法及数据结构细节上的不同 1)C54x的C语言数据类型及其表示范围 表5.1 数据类型 字长 表示意义 最小值 最大值
signed char 16 ASC‖ -32768 32767 char unsigned char 65535 short signed short 16 二进制补码 -32768 32767 unsigned short 二进制 65535 int, signed int 16 二进制补码 -32768 32767 unsigned int 二进制 65535

25 表5.1 C54X的编译器所支持的C语言数据类型 数据类型 字长 表示意义 最小值 最大值 Long, signed long 32
二进制补码 unsigned long 二进制 enum 16 二进制补码 -32768 32767 float 32 IEEE-32bit e-38 e+38 double 32 IEEE-32bit e-38 e+38 long double *(指针类型) *(pointers) 16 IEEE-32bit 0x0000 0xFFFF

26 C54x的C语言编译器设置一种地址变量来实现对指定数据存储单元(特别是MMR)的访问。
4.语法及数据结构细节上的不同 2) C54x的C语言特有数据类型 (1) 地址变量 C54x的C语言编译器设置一种地址变量来实现对指定数据存储单元(特别是MMR)的访问。 地址变量就是指定了具体地址值的指针变量。 如: volatile short *mcbsp0_drr10=0x10; short sh_drr10_data; sh_drr10_data = *mcbsp0_drr10; 山东大学生物医学工程刘忠国

27 4.语法及数据结构细节上的不同 2) C54x的C语言特有数据类型 (1) 地址变量
C54x的C语言编译器设置一种地址变量来实现对指定数据存储单元(特别是MMR)的访问。 地址变量就是指定了具体地址值的指针变量。如: volatile short *mcbsp0_drr10=0x10; short sh_drr10_data; sh_drr10_data = *mcbsp0_drr10; volatile关键字可防止C54X C编译器的优化器将一些 定义了但没有使用的变量优化掉。 山东大学生物医学工程刘忠国

28 4.语法及数据结构细节上的不同 优化器还尽可能避免访问存储器。volatile关键字防 止编译器对存储单元的读写的理解与作者本来意愿不 一致情况的出现。例: unsigned int *ctrl; while(*ctrl !=0xFF); 只在循环开始读一次*ctrl 优化器认为*ctrl不会改变,所以只读一次,若第一次读*ctrl ≠ 0xFF,程序将一直执行死循环。 为解决此问题,可以定义*ctrl为: volatile unsigned int *ctrl; while(*ctrl !=0xFF); 每次循环都读*ctrl。

29 ioport 数据类型 porthex_num ;
2)C54x的C语言特有数据类型 (2) I/O端口变量 I/O端口变量的定义格式如下: ioport 数据类型 porthex_num ; ioport unsigned port10; 其中: ioport: 端口变量定义关键字 数据类型:只能是 char,short,int, unsigned等16位的类型 hex_num:该I/O端口的16进制格式表示 的端口地址 山东大学生物医学工程刘忠国

30 (2) I/O端口变量 举例 ioport unsigned port10; /* 定义地址为10H的I/O端口变量*/
int func ( ) { ... port10 = 20; /* write a to port 10H */ b = port10; /* read port 10H into b */ } 山东大学生物医学工程刘忠国

31 register type AR1或register type AR6
2) C54x的C语言特有数据类型 (3) 寄存器变量 在一个C函数内部最多可以使用两个寄存器变量,编译器在编译这两个寄存器变量时用AR1和AR6这两个辅助寄存器分别做了对应: AR1被赋给了第一个寄存器变量; AR6被赋给了第二个寄存器变量; C54x C语言通过全局声明扩展寄存器变量为全局定位。全局声明格式: register type AR1或register type AR6 山东大学生物医学工程刘忠国

32 (3) 寄存器变量 2) C54x的C语言特有数据类型
C54X C编译器在一个函数中可使用最多2个寄存器变量。C54X C编译器使用AR1和AR6作为寄存器变量: AR1被赋给第一个寄存器变量 AR6被赋给第二个寄存器变量 将变量的地址放进分配好了的寄存器以简化访问,因此,可用16位类型char、short、int和pointers声明寄存器变量 。 设置寄存器变量需要大约4个指令周期,为了有效利用这一特性,仅在变量被访问多于2次时,才设置寄存器变量。

33 (3) 寄存器变量 2) C54x的C语言特有数据类型
寄存器变量必须在变量列表或函数的第一块语句中声明寄存器变量,在嵌套块中声明的寄存器被处理为正常的变量。 例5.5 int fa(int a, int b) { …… // 可在此声明使用寄存器变量 …… // 不能在此声明使用寄存器变量 }

34 (3) 寄存器变量 全局寄存器变量 C54x C编译器允许分配全局寄存器,声明格式如下: register type regid
其中regid可以是AR1或AR6 全局寄存器的使用方法: register struct data_struct *AR6 #define data_pointer AR6 data_pointer->member data_pointer++

35 ANSI C(ISO C)语言规定:没有显式初始化的变量都将初始化为0。
4.语法及数据结构细节上的不同 3)DSP C语言关于变量的特殊规定 (1) 变量的初值问题 ANSI C(ISO C)语言规定:没有显式初始化的变量都将初始化为0。 DSP的C语言规定:没有显式初始化的变量仍保持未初始化状态。 山东大学生物医学工程刘忠国

36 4.语法及数据结构细节上的不同 3)DSP C语言关于变量的特殊规定 (2) 有符号数的右移
山东大学生物医学工程刘忠国

37 4.语法及数据结构细节上的不同 3)DSP C语言关于变量的特殊规定 (3) 除法和取余 10/-3==-3 ; 10%-3==1 ;
10/-3==-3 ; 10%-3==1 ; -10/3==-3 ; -10%3==-1 即:余数的符号与被除数的符号保持一致。 山东大学生物医学工程刘忠国

38 浮点数转换到整数时,DSP的C语言采用朝0截止的方式,即简单地去掉分数部分 ,如:
4.语法及数据结构细节上的不同 3)DSP C语言关于变量的特殊规定 (4) 浮点数转换到整数 浮点数转换到整数时,DSP的C语言采用朝0截止的方式,即简单地去掉分数部分 ,如: int a,b; a=1.3; → a=1 b=-1.3; → b=-1 山东大学生物医学工程刘忠国

39 标准C规定:字符用单引号括起来,其本质是代表一个整数,如:
4.语法及数据结构细节上的不同 3)DSP C语言关于变量的特殊规定 (5) 多字符常量 标准C规定:字符用单引号括起来,其本质是代表一个整数,如: char c=‘r’; 标准C还允许单引号内包含多个字符,通常取里面的第一个或最后一个字符有效,没有硬性规定。TI公司的DSP C语言规定取最后一个字符有效 ‘abc’ == ‘c’ 山东大学生物医学工程刘忠国

40 (6) 16位数相乘 3)DSP C语言关于变量的特殊规定 DSP C语言规定:
16位数相乘,如果只想获得乘积结果的高16位可通过 把乘积结果右移16位来获得 例5-6: int m1, m2, result1; result1=((long)m1*m2)>>16; //16位*16位结果应用32位表示 unsigned m3, m4, result3; result3=((unsigned long)m3*m4)>>16; 这里的m1*m2的中间结果作了强制long转换,是为了 防止有效数据位的丢失。 山东大学生物医学工程刘忠国

41 C编译器对源程序进行编译后生成汇编程序, 汇编程序再经过汇编将成为COFF格式的目标文件;
5.2 C54x C语言编程 5.2.1 C54x C语言开发的存储器结构 1.C54x C语言开发的段结构 C编译器对源程序进行编译后生成汇编程序, 汇编程序再经过汇编将成为COFF格式的目标文件; 该文件将包含七个可以进行重新定位的代码和数据段: 已初始化段: .text, .cinit, .const, .switch; 未初始化段: .bss, .stack, .sysmem 山东大学生物医学工程刘忠国

42 ② .cinit段 — 包含明显初始化的全局变量和静态变量;
5.2.1 C54x C语言开发的存储器结构 1.C54x C语言开发的段结构 已初始化段: ① .text 段 — 包含了可执行代码; ② .cinit段 — 包含明显初始化的全局变量和静态变量; ③ .const段 — 包含字符串常数和全局常量; ④ .switch段— 包含大型switch语句的跳转表 山东大学生物医学工程刘忠国

43 ⑦.sysmem段 — 为动态存储器函数malloc,calloc, realloc(这些函数由运行支持库提供)分配存储器空间
1.C54x C语言开发的段结构 未始化段: ⑤.bss 段 — 包含了未初始化的全局变量 和静态变量; ⑥.stack段 — 定义软件堆栈 ⑦.sysmem段 — 为动态存储器函数malloc,calloc, realloc(这些函数由运行支持库提供)分配存储器空间 山东大学生物医学工程刘忠国

44 1.C54x C语言开发的段结构 1)已初始化段: (1).cinit段
在DSP上电时,系统初始化函数(bootloader) 会自动调用段.cinit的值来初始化段.bss,如图所示 山东大学生物医学工程刘忠国

45 显式初始化全局变量和静态变量的初始化过程
1.C54x C语言开发的段结构 .cinit段实际上就包含了一些全局变量存放位置与其初始值的对应关系,也就是一些关于全局变量的记录。 显式初始化全局变量和静态变量的初始化过程

46 1.C54x C语言开发的段结构 例5-7:假设在C程序中定义了两个初始化变量: int a=45;
int b[5]={2,3,4,5,6}; 则这两个变量的初始化信息如下: .sect “.cinit” ;初始化段 *** 变量a 的记录 *********** .word 1 ; 数据长度为1 .word _a ; .bss中的地址 .word ; 数据 *** 变量b的记录 ************ .word 5 ; 数据长度5 .word _b ; .bss中的地址 .word 2,3,4,5,6 ; 数据

47 1.C54x C语言开发的段结构 (2).switch段 当C语言程序中有分支语句Switch时,如: int i;
  int function()    {    switch (i) {      case 1:       return 1;       break;      default:       return 0;        }    } C语言编译时将产生 .switch段。 该段记录了开关变量和相应开关值,以及需要执行的程序起始位置的对应关系。 山东大学生物医学工程刘忠国

48 注意:C编译器并不提供检查堆栈溢出的手段,因此,必须保证有足够的空间用于堆栈,否则,发生溢出现象将破坏程序的运行环境,从而导致程序的瘫痪。
1.C54x C语言开发的段结构 2)未初始化段 (1).stack段 .stack段定义了软件堆栈,用于函数调用、变量传递以及局部变量分配。堆栈大小由连接器选项设置,如-stack 40,默认大小400h即1k. 注意:C编译器并不提供检查堆栈溢出的手段,因此,必须保证有足够的空间用于堆栈,否则,发生溢出现象将破坏程序的运行环境,从而导致程序的瘫痪。 山东大学生物医学工程刘忠国

49 .sysmem段用来为动态存储器函数malloc, calloc, realloc分配存储器空间。大小由连接器选项设置,如-heap 40。
1.C54x C语言开发的段结构 2)未初始化段 (2).sysmem段 .sysmem段用来为动态存储器函数malloc, calloc, realloc分配存储器空间。大小由连接器选项设置,如-heap 40。 对于比较大的数据变量,一般利用这种动态分配的方式在sysmem段中分配这些变量的空间,以便节省.bss段的空间 山东大学生物医学工程刘忠国

50 1.C54x C语言开发的段结构 3)自定义段: 利用#pragma伪指令产生,可支持的自定义段: CODE_SECTION
DATA_SECTION FUNC_EXT_CALLED FUNC_CANNOT_INLINE FUNC_IS_PURE FUNC_IS_SYSTEM FUNC_NEVER_RETURNS FUNC_NO_GLOBAL_ASG FUNC_NO_IND_ASG IDENT INTERRUPT NO_INTERRUPT 不同于.text段 不同于.bss段 山东大学生物医学工程刘忠国

51 #pragma CODE_SECTION(symbol, “section name”)
3) 自定义段 (1) CODE_SECTION pragma 不同于.text段 其语法结构为: #pragma CODE_SECTION(symbol, “section name”) (2) DATA_SECTION pragma 不同于.bss段 其语法结构为: #pragma DATA_SECTION(symbol, “section name”) 山东大学生物医学工程刘忠国

52 (3) FUNC_EXT_CALLED pragma 保持没被C调用的函数不被优化掉。
1.C54x C语言开发的段结构 3) 自定义段 (3) FUNC_EXT_CALLED pragma 保持没被C调用的函数不被优化掉。 其语法结构为: #pragma FUNC_EXT_CALLED(func) 注:pragma必须出现在对要保持的函数的任何声明或引用前。 山东大学生物医学工程刘忠国

53 2.C54x C语言开发的存储结构 1) 段的存储器定位: 例5.10 段名及段的类型 存储器类型 Page类型 已 初 始 化 段
.cinit ROM or RAM .const 1 .text .switch .bss RAM 1 .stack sysmem CODE_SECTION ROM or RAM DATA_SECTION RAM 1

54 2.C54x C语言开发的存储结构 2) 存储器模式: DSP编译器支持两种存储器模式:
小存储器模式(little endian)和大存储器模式(big endian)。对.bss有影响, 对.text, .cinit等无影响。 (1) 小存储器模式: 小存储器模式是编译器的缺省存储器模式。要求.bss段在128个字(一个数据页)范围内,这样编译成汇编时,不需修改DP值。 (2) 大存储器模式。大存储器模式与小存储器模式 的区别在于它不限制.bss段的大小,因此对全局变量和 静态变量来说,具有无限的空间。

55 5.2.2 C54x C语言开发的函数及其约定 5.2 C54x C语言编程
计算机硬件结构不同,函数在参数传递的实现上有差异,函数参数传递规则 : 1.C54x C语言开发的寄存器约定规则 2.C54x C语言开发的函数调用规则 3.C54x C语言开发的标识符命名约定和混合语言编程 山东大学生物医学工程刘忠国

56 编译器的寄存器约定规则规定了在函数内如何使用寄存器,以及在函数之间相互调用时如何保存(或称为保护)这些寄存器的值。
5.2.2 C54x C语言开发的函数及其约定 1.C54x C语言开发的寄存器约定规则 编译器的寄存器约定规则规定了在函数内如何使用寄存器,以及在函数之间相互调用时如何保存(或称为保护)这些寄存器的值。 寄存器值的保存分成两种基本类型: 入口保存(save on entry):寄存器原来的值 由被调用函数负责保存, 一般放在函数入口处。 调用保存(save on call):调用保存寄存器的 值由调用函数保存。 山东大学生物医学工程刘忠国

57 表5.3 C54x C编译器的寄存器约定 寄存器名 用途 入口保存 调用保存 AR0 指针和表达式 No Yes AR1 AR2 - AR5 AR6 AR7 指针和表达式,局部帧指针 (当需要时)

58 表5.3 C54x C编译器的寄存器约定 寄存器名 用途 入口保存 调用保存 A 表达式,第一个入口参数,函数返回结果 No Yes B 表达式 SP 堆栈指针 T 乘和移位表达式 ST0,ST1 状态寄存器 有一定状态要求 BRC Block repeat counter †被压栈的数据必须在返回前被弹出The SP is preserved by the convention that everything pushed on the stack is popped off before returning。

59 Auxiliary register pointer Yes
表5.4 C54x C编译器的状态寄存器约定 状态寄存器的域 名称 约定值 编译器生成的程序是否对其更改 ARP Auxiliary register pointer Yes ASM Accumulator shift mode - BRAF Block repeat active bit No C Carry bit C16 Dual 16-bit math bit

60 Saturate-multiply bit
表5.4 C54x C编译器的状态寄存器约定 状态寄存器的域 名称 约定值 编译器生成的程序是否对其更改 OVM Overflow mode Only with intrinsics SXM Sign extension mode - Yes SMUL Saturate-multiply bit SST Saturate-store bit No TC Test control bit

61 Compatibility mode bit
表5.4 C54x C编译器的状态寄存器约定 状态寄存器的域 名称 约定值 编译器生成的程序是否对其更改 CMPT Compatibility mode bit No CPL Compiler mode bit 1 FRCT Fractional mode bit OVA Overflow flag for A - Yes OVB Overflow flag for B

62 5.2.2 C54x C语言开发的函数及其约定 2.C54x C语言开发的函数调用规则 遵循严格的函数调用规则,否则破坏C环境。举例:
调用关系:main( )→funciton1(… )→function2(…) 函数function1(非main函数,更具代表性), 它接收了调用者(main函数)传递给它的参数; 它有自己的局部变量,它还要调用另一个函数 function2,function1也需要传递参数给 function2,并从function2中返回计算结果。 山东大学生物医学工程刘忠国

63 funciton1调用函数function2前后的堆栈使用情况
function2 funciton2(参数1, 参数2… 参数n) 参数1→A 调用前 调用 参数1→A funciton1 (AR7) local frame main( )→funciton1(… ) →function2(…)

64 2.C54x C语言开发的函数调用规则 例:main.asm → _C_SUB (*num1, *num2, *jieguo, *chang) diaoyong: ; 汇编程序调用c子程序的例子 LD #_chang, A ;第四个参数入栈; NOP PSHM AL LD #_jieguo1, A ;第三个参数入栈 PSHM AL LD #num2, A ;第二个参数入栈 LD #num1, A ;第一个参数存入AL nop CALL _C_SUB ;调用C子程序 ADDM #3, *(SP);恢复堆栈指针到原位置, 数为调用参数个数-1

65 调用 funciton2(参数1, 参数2… 参数n) 调用前
funciton1调用函数function2前后的堆栈使用情况 调用 function2 funciton2(参数1, 参数2… 参数n) 调用前 参数1→A 参数1→A funciton1 local frame main( )→funciton1(… )→function2(…) 山东大学生物医学工程刘忠国

66 C编译器在编译C语言程序时, 会自动在所有标识符(函数名、变量名等)之前加下划线“_”;
5.2.2 C54x C语言开发的函数及其约定 3.C54x C语言开发的标识符命名约定和混合语言编程 C54X C语言标识符命名约定。 C编译器在编译C语言程序时, 会自动在所有标识符(函数名、变量名等)之前加下划线“_”; 若希望C语言程序能够调用汇编语言定义的 标识符,汇编语言应将该标识符定义成开头 为“_x”的标识符,而在C语言程序中调用该 标识符时要去掉该标识符如x来调用。 山东大学生物医学工程刘忠国

67 如果在C程序中定义的变量(或函数)需要在汇 编中访问,则应该在汇编中用.global或.ref 声明为全局引用标识符。
5.2.2 C54x C语言开发的函数及其约定 3.C54x C语言开发的标识符命名约定和混合语言编程 汇编程序和C语言程序一般都是在两个不同 的文件之中的,在不同文件中的变量或者函 数的应用,必须加以全局说明。 如果在C程序中定义的变量(或函数)需要在汇 编中访问,则应该在汇编中用.global或.ref 声明为全局引用标识符。 山东大学生物医学工程刘忠国

68 3.C54x C语言开发的标识符命名约定和混合语言编程
1)在C中访问.bss中定义的汇编变量和汇编常量: (1) 在C中访问.bss中定义的汇编变量 汇编程序: .bss _var, ;定义变量 .global _var ;说明为外部变量 C程序: extern int var; /*声明为外部变量*/ var = 1; /*访问外部变量*/

69 3.C54x C语言开发的标识符命名约定和混合语言编程
1)在C中访问.bss中定义的汇编变量和汇编常量: (2) 在C中访问汇编常数 汇编程序: .global _table_size ;说明外部变量 _table_size .set, :定义常数 C程序: extern int table_size; /*声明为外部变量*/ for (i=0; i<table_size; i++ ) { … }

70 3.C54x C语言开发的标识符命名约定和混合语言编程
int i; /*全局变量*/ main() { … } 汇编程序: .global _i; 说明为外部变量 STM @_i, AR0 ; AR0=_i

71 3.C54x C语言开发的标识符命名约定和混合语言编程
int h[20]; /*全局数组变量*/ main() { … } 汇编程序: .global _h; 说明为外部变量 .data h_add .word _h; 数组h的起始地址 .text STM h_add, AR0 ; 地址立即数#h_add送AR0 @h_add错

72 3.C54x C语言开发的标识符命名约定和混合语言编程
extern int asmfunc(); /*声明汇编中定义的外部函数*/ int gvar; /*定义全局变量*/ main( ) { int i; i= asmfunc(); /*调用函数*/ } 汇编程序: FP .set AR7;定义变量 .mmregs ;使能存储器映像寄存器 .global _asmfunc ;说明为外部变量 .text _asmfunc frame #-1 …… RET

73 4) 在C中使用内嵌(inline)汇编: 在C语言程序的相应位置直接嵌入汇编语句,这是一种C和汇编之间比较直接的接口方法。 嵌入汇编语句的方法比较简单,只需在汇编语句的左、右加上一个双引号,用小括弧将汇编语句括住,在括弧前加上asm标识符即可,如下所示: asm(“ 汇编语句 ”); 功能是控制C语言难以实现的DSP芯片的一些硬件资源;优化程序。

74 C编译器约定,任何具有名为c_int d的函数(d为00~09)都被假定为一个中断程序。
5.2.3 C54x C语言中断处理函数的实现 对于使用C语言编程的DSP应用程序,应该尽量使用C语言编写中断处理函数。 1.C语言中断函数的定义 C语言中断函数的定义有两种实现方法 1) c_int d 函数 C编译器约定,任何具有名为c_int d的函数(d为00~09)都被假定为一个中断程序。 其中c_int00是rts.lib库函数中定义的系统复位中断处理程序,完成系统上电初始化。 山东大学生物医学工程刘忠国

75 该方法定义的中断处理函数数目较少(只有9个),另外,函数名称与其功能的对应关系不够直观。
5.2.3 C54x C语言中断处理函数的实现 1) c_int d 函数 如: void c_int01() { …… } 该方法定义的中断处理函数数目较少(只有9个),另外,函数名称与其功能的对应关系不够直观。 山东大学生物医学工程刘忠国

76 interrupt void timesr()
5.2.3 C54x C语言中断处理函数的实现 2) interrupt 函数 定义的另一种方法就是利用interrupt关键字,将该关键字后面所定义的函数声明为中断函数。 如下所示: interrupt void isr() { …… } void 既可放在interrupt前面,也可放在interrupt后面。 这种方法,可以对每种中断服务函数的功能起个直观的 名字,同时,中断服务函数的个数也没有严格的限制。 interrupt void timesr() void interrupt isr() 山东大学生物医学工程刘忠国

77 中断函数的返回类型必须是void类型,并且不能有参数。 对于中断函数来讲,所有自己用到的寄存器包括状态寄存器和累加器都需要保护
5.2.3 C54x C语言中断处理函数的实现 2.关于C语言中断函数的说明 中断函数的返回类型必须是void类型,并且不能有参数。 对于中断函数来讲,所有自己用到的寄存器包括状态寄存器和累加器都需要保护 3.在返回时中断函数使用的是RETE,而一般函数使用的是RET。 4.中断函数不能被普通的C代码直接调用。 山东大学生物医学工程刘忠国

78 5.进入中断服务函数时,要求SP的内容是偶数。 6.一个中断程序可以处理一个或多个中断。
2.关于C语言中断函数的说明 5.进入中断服务函数时,要求SP的内容是偶数。 6.一个中断程序可以处理一个或多个中断。 7.中断处理和具体某种中断的联系,由中断向量表来声明。 8.在汇编语言中,需要访问这些中断处理函数时,不要忘记在函数名前加上“_”。 9.中断程序和它们调用的任何函数都不能由-oe命令选项(认为不存在中断)进行编译。 山东大学生物医学工程刘忠国

79 例5-11 C语言外部中断0的中断处理函数和中断向量表
中断处理函数:interrupt void int_INT0() { …. } sint17 .space 4*16 sint18 .space 4*16 sint19 .space 4*16 sint20 .space 4*16 sint21 .space 4*16 sint22 .space 4*16 sint23 .space 4*16 sint24 .space 4*16 sint25 .space 4*16 sint26 .space 4*16 sint27 .space 4*16 sint28 .space 4*16 sint29 .space 4*16 sint30 .space 4*16 中断向量表处理: .sect ".vectors" .ref _c_int00 .ref _int_INT0 .align 0x80 RESET: BD _c_int00 STM #128,SP ;NOP NMI: RETE NOP 双字 双字

80 例5-11 C语言外部中断0的中断处理函数和中断向量表
中断向量表处理: int0: B _int_INT0 ;nop nop int1: RETE int2: RETE tint0: RETE brint0: RETE nop bxint0: RETE dmac0:RETE tint1: RETE int3: RETE hpint: RETE nop brint1: RETE bxint1: RETE dmac4: RETE dmac5: RETE .end

81 3. C语言中断函数c_int00的作用 C程序开始运行时, 须首先初始化C运行环境, 这通过 c_int00函数完成, 这个函数在运行支持库rts.lib中。 链接选项中若有-c 或-cr, 则定义_c_int00为程序入口 地址。连接器会将这个函数的入口地址放置在复位中 断向量处,使其可以在初始化时被调用。 c_int00函数进行以下工作以建立C运行环境: 为系统堆栈产生.stack块,并初始化堆栈指针。 从.cinit块将初始化数据拷贝到.bss块中相应的变量。 调用main函数,开始运行C程序。 山东大学生物医学工程刘忠国

82 第5章 C54x高级C语言程序设计 5.2.4 C54x C语言库函数调用 TI公司提供了一些库函数,对C语言编程环境的运行提供支持,称为运行时支持库(rts, runtime-support library) 。两种形式的运行时支持库:目标代码的“rts.lib”和源代码的“rts.src”。 对源代码库函数可以修改,例:想查看源代码库里面的两个文件“atoi.c”和“strcpy.c”的内容,并对它进行调整,可以采用如下的步骤实现: 山东大学生物医学工程刘忠国

83 5.2 C54x C语言编程 5.2.4. C54x C语言库函数调用 1.抽取文件 使用的命令如下:
ar500 x rts.src atoi.c strcpy.c 2.查看并修改文件。 3.编译修改后的文件。使用的命令是: cl500 -options atoi.c strcpy.c ;重编译 山东大学生物医学工程刘忠国

84 5.2.4. C54x C语言库函数调用 4.把修改后的文件加入源代码库“rts.src”,使用的命令是:
ar500 -r rts.src atoi.c strcpy.c ;重建库 5.重新生成目标库 目标库“rts.lib”可以由新的源代码库“rts.src”重新生成,使用的命令是: mk500 --u -o2 rts.src -l rts.lib 山东大学生物医学工程刘忠国

85 5.2 C54x C语言编程 5.2.4 C54x C语言库函数调用 在使用这些标准的库函数时,一定要注意在使用这些库函数的文件中把包含这些库函数声明的头文件包含到自己的文件中 。 山东大学生物医学工程刘忠国

86 5.2 C54x C语言编程 5.2.4 C54x C语言库函数调用 例如:要使用标准的输入输出函数“fprintf”,就要在自己的文件中加上一条语句“ #include <stdio.h>”把与“fprintf”函数有关的头文件“stdio.h”包含上。 山东大学生物医学工程刘忠国

87 5.3 C54x C代码优化 对C代码进行手工汇编优化有二种方法: 对照C代码写出汇编代码:优化效率高,难度大,易出错。
先用编译器产生汇编代码,然后改写汇编代码。优化效率低,难度小,不易出错。 山东大学生物医学工程刘忠国

88 CCS的C编译器可对C代码进行优化,DSP C代码优化过程 :
5.3 C54x C代码优化 5.3.1 产生汇编代码 CCS的C编译器可对C代码进行优化,DSP C代码优化过程 : C代码(.c) 代码生成器 剖析器 优化器 CCS提供了4级的文件优化方案,分别是O0、O1、O2、O3,只要调用编译程序之前明确采用-O0、-O1、-O2或者-O3优化等级选项,编译程序就会按照这些优化等级的要求进行优化。 汇编代码 (.asm) 山东大学生物医学工程刘忠国

89 在做优化时,一般选用O2(默认)级别的优化,因为使用O2级别优化后产生的汇编文件带有比较多的注释信息,比较容易看懂程序。
5.3 C54x C代码优化 5.3.1 产生汇编代码 在做优化时,一般选用O2(默认)级别的优化,因为使用O2级别优化后产生的汇编文件带有比较多的注释信息,比较容易看懂程序。 山东大学生物医学工程刘忠国

90 5.3 C54x C代码优化 5.3.1 产生汇编代码 1. O0 寄存器级别 执行控制流程简化 用寄存器分配变量 执行循环 排除未用的代码
简化语句和表达式 扩大对内连函数的调用 山东大学生物医学工程刘忠国

91 5.3 C54x C代码优化 5.3.1 产生汇编代码 2. O1 局部级别 执行所有O0级别的优化 执行局部拷贝和常量传播 排除未用的赋值
排除局部共用表达式 山东大学生物医学工程刘忠国

92 5.3.1 产生汇编代码 3.O2 函数级别 5.3 C54x C代码优化 执行所有O1级别的优化 执行循环优化 排除全局共用子表达式
排除全局不用的赋值 执行循环展开 山东大学生物医学工程刘忠国

93 保存函数说明,以便主函数被优化时知道被调用函数的属性
5.3 C54x C代码优化 5.3.1 产生汇编代码 4. O3 文件级别 执行所有O2级别的优化 排除未被调用的函数 简化返回值没被使用的函数 让小函数变成内联调用 保存函数说明,以便主函数被优化时知道被调用函数的属性 识别文件级别的变量的特性 山东大学生物医学工程刘忠国

94 5.3 C54x C代码优化 5.3.2 手工汇编优化经验 12条,略 山东大学生物医学工程刘忠国

95 作业 习题 山东大学生物医学工程刘忠国


Download ppt "C54x的程序设计有两种语言:汇编语言和C语言。"

Similar presentations


Ads by Google