第5章C54x高级C语言程序设计20121102pptx

Report
第5章 C54x高级C语言程序设计
C54x的程序设计有两种语言:汇编
语言和C语言。
 汇编语言程序效率高,硬件定时准
确,但不够直观 ,设计周期较长,
可移植性和可维护性差
参考:TMS320C54x Optimizing C_C++ Compiler
User‘s Guide.pdf, SPRU103G,2002 ,TI官网
第5章 C54x高级C语言程序设计
 C语言,可移植性好,可维护
性好 ,可生成代码执行效率
较高的可执行程序。
第5章 C54x高级C语言程序设计
 一般代码用高级语言编写,
缩短开发周期,还可使汇编
语言编写的程序被高级语言
所调用。
第5章 C54x高级C语言程序设计
目录:
5.1 C54x C语言介绍
5.2 C54x C语言编程
5.3 C54x C代码优化
第5章 C54x高级C语言程序设计
5.1 C54x C语言介绍
1.C54x C编译器支持开发的C语言
标准,继承了大多数的ANSI的语
法规则 。
2.ANSI C和C54x C也有许多不同
之处 。
第5章 C54x高级C语言程序设计
5.1 C54x C语言介绍
5.1.1 C54x C与ANSI C的相同点
 只要与硬件不是特别相关的部分
都是它们的相同点。
第5章 C54x高级C语言程序设计
5.1.1 C54x C与ANSI C的相同点
 以函数作为基本单位。
 函数的定义和引用方式完全一致。
 大部分变量、常量、数组、结构
体、枚举、联合体、指针的定义
语法结构也完全一致。
第5章 C54x高级C语言程序设计
5.1.1 C54x C与ANSI C的相同点
 局部变量、全局变量、静态变量、
动态变量等基本定义也一致。
 宏定义、宏展开、宏调用的基本
思想甚至语法规则上基本一致。
第5章 C54x高级C语言程序设计
5.1.1 C54x C与ANSI C的相同点
1.常量定义
格式: const 类型 符号=数值 ;
例5-1:const short d1=8 ;
C54x C也可以用下面的方法定义符号常量:
#define Vmax 1 ;
//程序中出现Vmax时均会
以1来代替
第5章
C54x高级C语言程序设计
5.1.1 C54x C与ANSI C的相同点
2.变量定义
1) 一般变量的定义:
格式: 类型
符号 ;
2) 扩展变量的定义: struct, enum
3) 自定义变量的定义:
格式: typedef 已有类型
新数据类型 ;
第5章 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
第5章 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。
第5章 C54x高级C语言程序设计
3) 自定义变量的定义:
例5-3:
typedef unsigned short
US_DATA
ush_t;
等同于:
unsigned short ush_t;
US_DATA ;
第5章 C54x高级C语言程序设计
5.1.1 C54x C与ANSI C的相同点
3.函数的定义和组织
C54x C和ANSI C一样,整个程序有一个
主函数(main函数)和零个或者多个子函
数构成。
第5章 C54x高级C语言程序设计
如下所示:
float sub_cac(float a, float b);//子函数声明
void main()
//主函数定义,整个
程序内有且只有一个
{
float a=1;
float b=2;
float c;
c=sub_cac(a,b);
//子函数调用
……
第5章 C54x高级C语言程序设计
While(1)
//死循环,等待外部事件发生
{}
}
float sub_cac(float e,float f)//子函数定义
{
float g;
g=e*f;
return g;
}
第5章 C54x高级C语言程序设计
5.1.2 C54x C与ANSI C的不同点
1.所处理数据的性质不同
2.数据的输入输出设备不同
3.“死循环”的对待上不同
4.语法及数据结构细节上的不同
5.1.2 C54x C与ANSI C的不同点
1.所处理数据的性质不同
ANSI C处理的数据类型
采集好的、数据量较多的、以数据块为单
位,实时性要求不高
C54x C处理的数据类型
有严格的实时性要求,要求对于数据的处
理时间要小于数据的采样时间间隔。
5.1.2 C54x C与ANSI C的不同点
2.数据的输入输出设备不同
ANSI C
输入: 硬盘、内存等存储介质或键盘、实时采
集数据。输出是显示器、通信口或实时输出
C54x C
实时采集数据,处理结果给其他计算机或
者芯片(如MCU、ARM等)使用,或者通
过D/A输出。
5.1.2 C54x C与ANSI C的不同点
3.“死循环”的对待上不同
ANSI C程序
程序内部出现“死循环”,或者程序的
处理不当,解决的办法只有重启计算机。
C54x C程序
在main函数将所有的初始化任务都完
成后安排一个“死循环”语句,如:
While(1){ }。
第5章 C54x高级C语言程序设计
为什么“死循环”的对待上不同?
面向PC机的ANSI C程序属于应用程
序,架构在操作系统,不和硬件直接打交
道,对硬件的操作实际上是通过操作系统
的系统调用配合相应的驱动程序来实现。
5.1.2 C54x C与ANSI C的不同点
而面向DSP的C54x C程序一般不是架构在操作
系统之上,对硬件的操作也都是直接的。
应用程序
操作系统
应用程序
驱动/BSP
硬件
图5-1 PC机的软件结构
硬件
图5-2 DSP的软件结构
第5章 C54x高级C语言程序设计
5.1.2 C54x C与ANSI C的不同点
4.语法及数据结构细节上的不同
1)C54x的C语言数据类型及其表示范围
2)C54x的C语言特有数据类型
3)DSP C语言关于变量的特殊规定
第5章 C54x高级C语言程序设计
1)C54x的C语言数据类型及其表示范围
数据类型
表示意义
最小值
最大值
16
ASC‖
-32768
32767
16
ASC‖
0
65535
short, signed
short
16
二进制补码
-32768
32767
unsigned
short
16
二进制
0
65535
-32768
32767
0
65535
signed char
unsigned char
char
int, signed int
unsigned int
字长
16
16
二进制补码
二进制
表5.1 C54X的编译器所支持的C语言数据类型
数据类型
字长 表示意义
最小值
Long, signed
32 二进制补码 -2147483648
long
unsigned long 32
0
二进制
enum
16 二进制补码
-32768
1.175494efloat
32 IEEE-32bit
38
1.175494e38
double
32 IEEE-32bit
最大值
2147483647
4294967295
32767
3.40282346e+
38
3.40282346e+
38
long double
1.175494e3.40282346e+
38
32 IEEE-32bit
38
*(指针类型)
*(pointers)
16 IEEE-32bit
0x0000
0xFFFF
5.1.2 C54x C与ANSI C的不同点
2)C54x的C语言特有数据类型
(1) 地址变量
C54x的C语言编译器设置一种地址变量来实现
对指定数据存储单元的访问。
地址变量实际上就是指定了具体地址值的指
针变量。如:
volatile short *mcbsp0_drr10=0x10;
short sh_drr10_data;
sh_drr10_data = *mcbsp0_drr10;
2)C54x的C语言特有数据类型
(2) I/O端口变量
I/O端口变量的定义格式如下:
ioport 数据类型 porthex_num ;
其中:
ioport: 端口变量定义关键字
数据类型:只能是 char,short,int,
unsigned等16位的类型
hex_num:该I/O端口的16进制格式表示
的端口地址
(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 */
...
}
2)C54x的C语言特有数据类型
(3) 寄存器变量
DSP的C语言扩展了寄存器变量。在一个C函
数内部最多可以使用两个寄存器变量,编译
器在编译这两个寄存器变量时用AR1和AR6
这两个辅助寄存器分别做了对应:
•AR1被赋给了第一个寄存器变量;
•AR6被赋给了第二个寄存器变量;
寄存器变量的定义格式:
register type AR1或register type AR6
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(1) 变量的初值问题
ANSI C(ISO C)语言规定:没有显式初始
化的变量都将初始化为0。
DSP的C语言规定:没有显式初始化的变量
仍保持未初始化状态。
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(2) 有符号数的右移
DSP的C语言规定,有符号数的右移等
价于算术右移
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(3) 除法和取余
DSP的C语言做了如下规定:
10/-3==-3 ; 10%-3==1 ;
-10/3==-3 ; -10%3==-1
即:余数的符号与被除数的符号保持一致。
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(4) 浮点数转换到整数
浮点数转换到整数时,DSP的C语言采用朝0
截止的方式,即简单地去掉分数部分 ,如:
int a,b;
a=1.3; → a=1
b=-1.3; → b=-1
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(5) 多字符常量
标准C规定:字符用单引号括起来,其本质是
代表一个整数,如:
char c=‘r’;
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(5) 多字符常量
标准C还允许单引号内包含多个字符,通
常取里面的第一个或最后一个字符有效,
没有硬性规定。TI公司的DSP C语言规
定取最后一个字符有效
‘abc’ == ‘c’
第5章 C54x高级C语言程序设计
3)DSP C语言关于变量的特殊规定
(6) 16位数相乘
DSP C语言规定:
16位数相乘,如果只想获得乘积结果的高
16位可通过把乘积结果右移16位来获得。
3)DSP C语言关于变量的特殊规定
(6) 16位数相乘
DSP C语言规定:
16位数相乘,如果只想获得乘积结果的高16位可通过
把乘积结果右移16位来获得
例5-6:
int m1,m2,result1;
unsigned m3,m4,result3;
result1=((long)m1*m2)>>16; //16位*16位结果应用
32位表示
result3=((unsigned long)m3*m4)>>16;
这里的m1*m2的中间结果作了强制long转换,是为了
防止有效数据位的丢失。
第5章 C54x高级C语言程序设计
5.2 C54x C语言编程
5.2.1 C54x C语言开发的存储器结构
1.C54x C语言开发的段结构
汇编程序经过汇编将成为COFF格式的目标
文件,该文件将包含七个可以进行重新定位
的代码和数据段: 已初始化段和未初始化段
第5章 C54x高级C语言程序设计
已初始化段:
①.text 段 — 包含了可执行代码;
②.cinit段 — 包含明显初始化的全局变量和静
态变量;
③.const段 — 包含字符串常数和全局常量;
④.switch段— 包含大型switch语句的跳转表
第5章 C54x高级C语言程序设计
未始化段:
⑤.bss 段 — 包含了未初始化的全局变量
和静态变量;
⑥.stack段 — 定义软件堆栈
⑦.sysmem段 — 为动态存储器函数
malloc,calloc, realloc(这些函数由运行支持
库提供)分配存储器空间
第5章 C54x高级C语言程序设计
1.C54x C语言开发的段结构
1)已初始化段:
(1).cinit段
在DSP上电时,系统初始化函数
(bootloader)会自动调用段.cinit的值来
初始化段.bss,如图所示
5.2.1 C54x C语言开发的存储器结构
显式初始化全局变量和静态变量的初始化过程
.cinit段实际上就包含了一些全局变量存放位置与其初始
值的对应关系,也就是一些关于全局变量的记录。
第5章 C54x高级C语言程序设计
5.2.1 C54x C语言开发的存储器结构
例5-7:假设在C程序中定义了两个初始化
变量:
int a=45;
int b[5]={2,3,4,5,6};
则这两个变量的初始化信息如下:
.sect “.cinit”
;初始化段
5.2.1 C54x C语言开发的存储器结构
int a=45
int b[5]={2,3,4,5,6};
.sect “.cinit”
;初始化段
******* 变量a 的记录 ***********
.word 1
; 数据长度为1
.word _a
; .bss中的地址
.word 45
; 数据
******* 变量b的记录 ************
.word 5
; 数据长度5
.word _b ; .bss中的地址
.word 2,3,4,5,6 ; 数据
1.C54x C语言开发的段结构
(2).switch段
当C语言程序中有分支语句Switch时,如:
int i;
int function()
C语音编译时将产生 .switch
{
段。 该段记录了开关变量和
switch (i){
case 1:
相应开关值,以及需要执行
return 1;
的程序起始位置的对应关系。
break;
default:
return 0;
break;
}
}
第5章
C54x高级C语言程序设计
2)未初始化段
(1).stack段
.stack段定义了软件堆栈,用于函数调用、变
量传递以及局部变量分配。堆栈大小由连接器
选项设置,如-stack 40,默认大小400h即1k.
注意:C编译器并不提供检查堆栈溢出的手
段,因此,必须保证有足够的空间用于堆栈,
否则,发生溢出现象将破坏程序的运行环境,
从而导致程序的瘫痪。
第5章
C54x高级C语言程序设计
2)未初始化段
(2).sysmem段
.sysmem段用来为动态存储器函数malloc,
calloc, realloc分配存储器空间。大小由连
接器选项设置,如-heap 40。
对于比较大的数据变量,一般利用这种动态
分配的方式在sysmem段中分配这些变量的
空间,以便节省.bss段的空间
3) 自定义段
(1) CODE_SECTION pragma
其语法结构为:
不同于.text段
#pragma CODE_SECTION(symbol,
“section name”)
(2) DATA_SECTION pragma
其语法结构为:
不同于.bss段
#pragma DATA_SECTION(symbol,
“section name”)
第5章 C54x高级C语言程序设计
3) 自定义段
(3) FUNC_EXT_CALLED pragma
保持没被C调用的函数不被优化掉。
其语法结构为:
#pragma
FUNC_EXT_CALLED(func)
注:pragma必须出现在对要保持的函数的
任何声明或引用前。
第5章 C54x高级C语言程序设计
2.C54x C语言开发的存储结构
1) 段的存储器定位:
段名及段的类型
已
初
始
化
段
存储器类型
Page类型
.cinit
ROM or RAM
0
.const
ROM or RAM
1
.text
ROM or RAM
0
.switch
ROM or RAM
0
段名及段的类型
未
初
始
化
段
命
名
段
存储器类型
Page类型
.bss
RAM
1
.stack
RAM
1
sysmem
RAM
1
CODE_SECTION
ROM or RAM
0
DATA_SECTION
RAM
1
表5.2
C54X的段存储器分配
第5章 C54x高级C语言程序设计
5.2.2 C54x C语言开发的函数及其约定
参数传递规则
1.C54x C语言开发的寄存器约定规则
2.C54x C语言开发的函数调用规则
3.C54x C语言开发的标识符命名约定和混
合语言编程
第5章 C54x高级C语言程序设计
5.2.2 C54x C语言开发的函数及其约定
1.C54x C语言开发的寄存器约定规则
编译器的寄存器约定规则规定了在函数内如
何使用寄存器,以及在函数之间相互调用时
如何保存(或称为保护)这些寄存器的值。
寄存器值的保存分成两种基本类型,即:入口
保存和调用保存。
C54x
C编译器的寄存器约定
寄存器名
用途
入口保存
调用保存
AR0
指针和表达式
No
Yes
AR1
指针和表达式
Yes
No
AR2 AR5
指针和表达式
No
Yes
AR6
指针和表达式
Yes
No
AR7
指针和表达式,
局部帧指针
(当需要时)
Yes
No
C54x
寄存器名
C编译器的寄存器约定
用途
B
SP
T
表达式, 第一个
入口参数,函数
返回结果
表达式
堆栈指针
乘和移位表达式
ST0, ST1
状态寄存器
A
入口保存
调用保存
No
Yes
No
†
No
有一定的状态
要求
Yes
†
Yes
Block repeat
BRC
No
Yes
counter
† The SP is preserved by the convention that everything
pushed on the stack is popped off before returning.
表5.4 C54x
状态寄存器的
域
ARP
ASM
BRAF
C
C16
C编译器的状态寄存器约定
名称
Auxiliary register
pointer
Accumulator shift
mode
Block repeat
active bit
Carry bit
Dual 16-bit math
bit
编译器生成的
程序是否对
约定值
其更改
0
Yes
-
Yes
-
No
-
Yes
0
No
表5.4 C54x
状态寄存器
的域
C编译器的状态寄存器约定
名称
编译器生成的程
约定值 序是否对其更改
Only with
intrinsics
OVM
Overflow mode
0
SXM
Sign extension
mode
-
SMUL
Saturate-multiply
bit
0
SST
Saturate-store
bit
0
No
TC
Test control bit
-
Yes
Yes
Only with
intrinsics
表5.4 C54x
状态寄存器
的域
CMPT
CPL
FRCT
OVA
OVB
C编译器的状态寄存器约定
名称
Compatibility
mode bit
Compiler mode
bit
Fractional mode
bit
Overflow flag
for A
Overflow flag
for B
编译器生成的程
约定值 序是否对其更改
0
No
1
No
0
No
-
Yes
-
Yes
5.2.2 C54x C语言开发的函数及其约定
2.C54x C语言开发的函数调用规则
例:
假定有一个函数function1(不是main函数,更具有
代表性),它接收了调用者(比如说是main函数)
传递给它的参数,它自己有自己的局部变量,它还要
调用另一个函数function2,function1也需要传递参
数给function2,并从function2中返回计算结果。其
调用关系是:
main( )→funciton1(… )→function2(…)
函数调用前后的堆栈使用情况
main( )→funciton1(… )→function2(…)
第5章
C54x高级C语言程序设计
3.C54x C语言开发的标识符命名约定和混合语言编程
C54X C语言标识符命名约定。
C编译器在编译C语言程序时,会自动在
所有标识符(函数名、变量名等)之前加
下划线“_”; 若希望C语言程序能够调用
汇编语言定义的标识符,应将该标识符定
义成开头为“_x”的标识符,而在C语言程
序中调用该标识符时要去掉该标识符如x来
调用。
第5章 C54x高级C语言程序设计
3.C54x C语言开发的标识符命名约定和混合语言编程
汇编程序和C语言程序一般都是在两个不同
的文件之中的,在不同文件中的变量或者函
数的应用,必须加以全局说明。
如果在C程序中定义的变量(或函数)需要在汇
编中访问,则应该在汇编中用.global或.ref
声明为全局引用标识符。
第5章 C54x高级C语言程序设计
在C程序中访问汇编程序变量或函数:
汇编程序:
.bss _var, 1
;定义变量
.global _var
;说明为外部变量
C程序:
extern int var;
/*外部变量*/
var=1;
/*访问变量*/
若要在汇编程序中访问C程序变量或函数,
也可以采用同样的方法。
C程序: int var;
/*全局变量*/
main()
{
…
}
在汇编程序中访问C程序变量或函数:
C程序:
int
i;
/* 定义i为全局变量*/
float x;
/* 定义x为全局变量*/
main( )
{ …. }
汇编程序:
.ref _i; ; 说明_i为外部变量
.ref _x; ; 说明_x为外部变量
LD @_i, DP
STL _x, A
4) 在C中使用内嵌(inline)汇编:
在C语言程序的相应位置直接嵌入汇编语
句,这是一种C和汇编之间比较直接的接口
方法。
嵌入汇编语句的方法比较简单,只需在
汇编语句的左、右加上一个双引号,用小括
弧将汇编语句括住,在括弧前加上asm标识
符即可,如下所示:
asm(“ 汇编语句 ”);
功能是控制C语言难以实现的DSP芯片
的一些硬件资源;优化程序。
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库函数中定义的系统复
位中断处理程序,完成系统上电初始化。
第5章 C54x高级C语言程序设计
如:
void c_int01()
{
……
}
该方法定义的中断处理函数数目较少(只
有9个),另外,函数名称与其功能的对
应关系不够直观。
5.2.3 C54x C语言中断处理函数的实现
2)interrupt函数
定义的另一种方法就是利用interrupt关键字,将
该关键字后面所定义的函数声明为中断函数。
如下所示:
interrupt void isr()
{
……
}
void 既可放在interrupt前面,也可放在interrupt后面。
这种方法,可以对每种中断服务函数的功能起个直观的
名字,同时,中断服务函数的个数也没有严格的限制。
5.2.3 C54x C语言中断处理函数的实现
2.关于C语言中断函数的说明
1.中断函数的返回类型必须是void类型,并且
不能有参数。
2.对于中断函数来讲,所有自己用到的寄存器
包括状态寄存器和累加器都需要保护
3.在返回时中断函数使用的是RETE,而一般
函数使用的是RET。
4.中断函数不能被普通的C代码直接 调用。
2.关于C语言中断函数的说明
5.进入中断服务函数时,要求SP的内容是偶数。
6.一个中断程序可以处理一个或多个中断。
7.中断处理和具体某种中断的联系,由中断向
量表来声明。
8.在汇编语言中,需要访问这些中断处理函数
时,不要忘记在函数名前加上“_”。
9.中断程序和它们调用的任何函数都不能由-oe
命令选项(认为不存在中断)进行编译。
例5-11 C语言外部中断0的中断处理函数和中断向量表
中断处理函数:interrupt void int_INT0()
{ …. }
sint17 .space 4*16
中断向量表处理:
sint18
.space
4*16
.sect ".vectors"
sint19 .space 4*16
.ref _c_int00
sint20 .space 4*16
.ref _int_INT0
sint21 .space 4*16
.align 0x80
sint22 .space 4*16
RESET: BD_c_int00
sint23 .space 4*16
STM #128,SP
sint24 .space 4*16
NOP
sint25 .space 4*16
NMI:
RETE
sint26 .space 4*16
NOP
NOP
sint27 .space 4*16
NOP
sint28 .space 4*16
例5-11 C语言外部中断0的中断处理函数和中断向量表
中断向量表处理:
sint29 .space 4*16
sint30 .space 4*16
int0: B _int_INT0
NOP
NOP
NOP
int1: RETE
NOP
NOP
NOP
int2: RETE
NOP
NOP
NOP
tint: RETE
NOP
NOP
rint0: RETE
NOP
NOP
NOP
xint0: RETE
NOP
NOP
NOP
rint1: RETE
NOP
NOP
NOP
xint1: RETE
NOP
NOP
NOP
int3: RETE
NOP
NOP
NOP
.end
3. C语言中断函数c_int00的作用
C程序开始运行时,必须首先初始化C运行环境,
这是通过c_int00函数完成的,这个函数在运行支持库
rts.lib中。连接器会将这个函数的入口地址放置在复
位中断向量处,使其可以在初始化时被调用。
c_int00函数进行以下工作以建立C运行环境:
①为系统堆栈产生.stack块,并初始化堆栈指针。
②从.cinit块将初始化数据拷贝到.bss块中相应的变量。
③调用main函数,开始运行C程序。
第5章 C54x高级C语言程序设计
5.2.4 C54x C语言库函数调用
TI公司提供了一些库函数,对C语言编程环境的运
行提供支持,称为运行时支持库(rts, runtimesupport library) 。两种形式的运行时支持库:目
标代码的“rts.lib”和源代码的“rts.src”。
对源代码库函数可以修改,例:想查看源代码库里
面的两个文件“atoi.c”和“strcpy.c”的内容,并对
它进行调整,可以采用如下的步骤实现:
第5章 C54x高级C语言程序设计
5.2.4. C54x C语言库函数调用
1.抽取文件
使用的命令如下:
ar500 x rts.src atoi.c strcpy.c
2.查看并修改文件。
3.编译修改后的文件。使用的命令是:
cl500 -options atoi.c strcpy.c ;重编译
第5章 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
第5章
C54x高级C语言程序设计
5.2.4 C54x C语言库函数调用
在使用这些标准的库函数时,一定要
注意在使用这些库函数的文件中把包
含这些库函数声明的头文件包含到自
己的文件中 。
第5章 C54x高级C语言程序设计
5.2.4 C54x C语言库函数调用
例如:要使用标准的输入输出函数
“fprintf”,就要在自己的文件中加上
一条语句“ #include <stdio.h>”把与
“fprintf”函数有关的头文件“stdio.h”
包含上。
第5章 C54x高级C语言程序设计
5.3 C54x C代码优化
对C代码进行手工汇编优化有二种方法:
1.对照C代码写出汇编代码
2.先用编译器产生汇编代码,然后改写汇
编代码
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
DSP C代码优化过程
C代码
剖析器
优化器
代码生成器
汇编代码
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
CCS提供了4级的文件优化方案,分别是
O0、O1、O2、O3,只要调用编译程序之
前明确采用-O0、-O1、-O2还是-O3优化等
级选项,编译程序就会按照这些优化等级
的要求进行优化。
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
我们在做优化时,选的是O2级别的优
化,因为使用O2级别优化后产生的汇
编文件带有比较多的注释信息,比较
容易看懂程序
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
1. O0 寄存器级别
• 执行控制流程简化
• 用寄存器分配变量
• 执行循环
• 排除未用的代码
• 简化语句和表达式
• 扩大对内连函数的调用
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
2. O1 局部级别
• 执行所有O0级别的优化
• 执行局部拷贝和常量传播
• 排除未用的赋值
• 排除局部共用表达式
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
3.O2 函数级别
• 执行所有O1级别的优化
• 执行循环优化
• 排除全局共用子表达式
• 排除全局不用的赋值
• 执行循环展开
第5章 C54x高级C语言程序设计
5.3.1 产生汇编代码
4. O3 文件级别
• 执行所有O2级别的优化
• 排除未被调用的函数
• 简化返回值没被使用的函数
• 让小函数变成内联调用
• 保存函数说明,以便主函数被优化时知道被
调用函数的属性
• 识别文件级别的变量的特性
作业
习题5.2-5.4

similar documents