890 likes | 1.09k Views
第 5 章 C54x 高级 C 语言程序设计. C54x 的程序设计有两种语言:汇编语言和 C 语言。. 汇编语言程序效率高,硬件定时准确,但不够直观 , 设计周期较长 , 可移植性和可维护性差. 参考: TMS320C54x Optimizing C_C++ Compiler User‘s Guide.pdf, SPRU103G , 2002 , TI 官网. 第 5 章 C54x 高级 C 语言程序设计. C 语言,可移植性好,可维护性好 ,可生成代码执行效率较高的可执行程序。. 第 5 章 C54x 高级 C 语言程序设计.
E N D
第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 ; US_DATA ush_t; 等同于: unsigned short ush_t;
第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程序属于应用程序,架构在操作系统,不和硬件直接打交道,对硬件的操作实际上是通过操作系统的系统调用配合相应的驱动程序来实现。
应用程序 操作系统 驱动/BSP 硬件 图5-1 PC机的软件结构 5.1.2 C54x C与ANSI C的不同点 而面向DSP的C54x C程序一般不是架构在操作系统之上,对硬件的操作也都是直接的。 应用程序 硬件 图5-2 DSP的软件结构
第5章 C54x高级C语言程序设计 5.1.2 C54x C与ANSI C的不同点 4.语法及数据结构细节上的不同 • C54x的C语言数据类型及其表示范围 • C54x的C语言特有数据类型 • DSP C语言关于变量的特殊规定
第5章 C54x高级C语言程序设计 1)C54x的C语言数据类型及其表示范围
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() { switch (i){ case 1: return 1; break; default: return 0; break; } } C语音编译时将产生 .switch段。 该段记录了开关变量和相应开关值,以及需要执行的程序起始位置的对应关系。
第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) 段的存储器定位: