|
一个最小的C应用程序项目必须至少包含3个文件:
(1)主程序 main.c 这个文件必须包含一个main()函数作为C程序的入口点。
(2)连接命令文件 .cmd 这个文件包含了dsp和目标板的存储器空间的定义以及代码段、数据段是如何分配到这些存储器空间的。这个文件可有用户自己编写(DSP/BIOS中可以系统生成)
(3)C运行库文件 rts*.lib C运行库提供了如printf等标准C函数,还提供了C环境下的初始化函数c_int00()。这个文件位于ccs安装目录下的\c6000\cgtools\lib子目录中。
如果用户的程序是准备写进EPROM并在上电之后直接运行的,那么还必须包含.asm文件
Vectors.asm 这个文件的代码将作为IST(中断服务表),并且必须被连接命令文件(.cmd)分配到0地址。dsp复位之后,首先跳到0地址,复位向量对应的代码必须跳转到C运行环境的入口点c_int00()(该入口点在连接的rts*.lib库中)。然后在c_int00()函数中完成诸如初始化堆栈指针和页指针以及初始化全局变量等操作,最后调用main函数,执行用户的功能。
在这几个文件当中,连接命令文件最重要,在编写连接命令之前,应首先了解3个基础知识:C6000的存储器映射,C6000编译器的C环境实现和COFF文件格式以及连接器的使用。
1. C6000的存储器映射
在C6000 4G地址空间内,程序和数据的存放并不是随意的,要合理的安排程序和数据的存放地址,就必须了解C6000的存储器地址映射。
2. COFF文件格式和C6000编译器的C环境实现
TI代码产生工具产生的目标文件是一种模块化的文件格式—COFF格式。程序中的代码和数据在COFF文件中是以段的形式组织。
对于C语言文件,编译器生成的代码段取名为.text。全局变量和静态变量(用static关键字定义的变量)分配在 .bss段中,而一般的局部变量或是使用寄存器,或是分配在 .stack中。由于堆栈和存储器分配函数的需要,编译器所产生的目标文件中有两个段(.stack和.sysmem)专门用于为堆栈和动态分配存储器函数保留存储空间。如果用户程序没有使用malloc、calloc和realloc这样的函数,那么编译器就不会产生.sysmem段。另外,对于用关键字far定义的变量,专门分配在.bss以外的数据段.far(.bss段与.far段内的数据访问方式不一样,分配在.bss段内的数据具有较高的访问效率)。
除此之外,还要关注一下程序编译生成的.map文件,因为.map文件中记录了段的各种详细信息,通过观察.map文件可有知道段的地址分配是否正确。
C编译器产生的默认代码段和数据:
初始化段: .text 代码
.cinit 变量初值表
.const 常量和字符串
.switch 用于大型switch语句的跳转表
非初始化段:.bss 全局变量和静态变量
.sysmem 全局堆(用于存储器分配函数)
.stack 堆栈
.far 以far声明的全局/静态变量
.cio 用于stdio函数
除了上面默认的代码段和数据段,用户还可以在C程序内利用#prama CODE_SECTION或DATA_SECTION来说明用户自己定义的代码段和数据段。
3 连接器的使用
连接器的输入文件是汇编器产生的浮动地址目标文件(.obj),产生的输出文件是可执行目标文件(.out)和连接过程结果说明文件(.map)。在连接过程中,连接器把所有目标文件中的同名段合并,并按照用户的连接器命令文件(.cmd)给各个段分配地址,最后生成可执行的.out文件。
还有一个连接器选项-c或-cr关系到全局/静态变量的初始化问题,需要用户自己设置,这个选项对基于JTAG的开发关系不大,但对于脱机运行的最终系统关系很大。
|
|