CCS中对F2812进行编程时,有个重要的文件,是以.cmd为后缀的,称为链接命令文件(Linker Command File),简称CMD文件。这个CMD文件是跟2812的存储器结构有关的。2812的存储器分为程序存储器和数据存储器,程序存储器中的主要内容是可执行代码、初始化数据、开关量等,数据存储器中存储的是外部变量、静态变量、系统堆栈等。
CCS编译产生若干可重定位的代码和数据块,称为section(段),这些段会通过CMD文件重定位到相应地存储空间中。这些段可分为初始化段和非初始化段。
初始化段包含可执行代码和数据表,编译器产生以下各初始化段:
1).text段:包含所有可执行的代码和常量。
2).cinit段:初始化的变量和常量表,主要用于C程序中;
3).pinit段:初始化的变量和常量表,主要用于C++程序中;
4).const段:包含字符串常以及用const声明的全局变量和静态变量;
5).econst段:同.const段,但用于far const声明的变量或编译器采用大存器模式时;
6).switch段:为开关语句(switch)建立的数据表。
非初始化段是在存储器中保留空间,通常是中RAM中,程序在运行时,可此空间创建和存储变量。编译器会产生的非初始化段如下:
1).bss段:为全局变量和静态变量保留的空间,在程序引导时,引导程序会将ROM中的.cinit段中的数据复制到.bss段中;
2).ebss段:为far声明的或大存储器模式下声明的全局变量和静态变量保留空间。在程序引导过程中,引导程序会将ROM中的.cinit段中的数据复制到.ebss段中;
3).stack段:为C系统堆栈分配的空间,用于函数调用时传递参数以及为局部变量分配空间。
4).sysmem段:为动态存储器分配保留空间,如果没有用到malloc函数,则该段空间大小为0;
5).esysmem段:为动态存储器分配保留空间,如果没有用到far malloc函数,则该段空间大小为0.
除了上述C编译器产生的段,在F281x中用户还可以通过#pragma预编译指令产生用户定义的段。#pragma的用法有两种:
1) #pragma CODE_SECTION(symbol, ”section name”)
2) #pragma DATA_SECTIOM(symbol, “section name”)
说明:
1)symbol既可以是函数名,也可以是全局变量名,section name是用户自定义的段名;
2)CODE_SECTION为用户自定义代码段,DATA_SECTION为用户自定义的数据段;
3)使用#pragma预编译指定要注意,一是不能在函数体中声明#pragma,二是必须在symbol被定义之前使用#pragma.
举例1:
#pragma CODE_SECTION(sum, “sectionA”)
int sum(int a, int b)
{
return(a + b);
}
void main(void)
{
……
}
这里编译器就把函数sum的代码编译到段名为sectionA的程序段中。
举例2:
#pragma DATA_SECTION(sin[256], “sinesection”)
int sin[256] = {……};
这里编译器把数组sin[256]编译到段名为sinesection的数据段中。
在CMD文件中,上述这些段都被分配到如下的页中,其中PAGE 0表示程序存储空间,PAGE 1表示数据存储空间。
段 |
被分配的存储空间 |
.text |
PAGE 0 |
.cinit |
PAGE 0 |
.pinit |
PAGE 0 |
#pragma CODE_SECTION定义的段 |
PAGE 0 |
.switch |
PAGE 1 |
.const |
PAGE 1 |
.econst |
PAGE 1 |
.bss |
PAGE 1 |
.ebss |
PAGE 1 |
.stack |
PAGE 1 |
.sysmem |
PAGE 1 |
.esysmem |
PAGE 1 |
#pragma DATA_SECTION定义的段 |
PAGE 1 |
在CMD文件中主要通过两个伪指令MEMORY和SECTIONS,来实现指示存储空间和分配段到相应存储空间两个功能的。
MEMORY语法如下:
MEMORY
{
PAGE 0: name 0 [(attr)]: origin=constant, length=constant
PAGE n: name n [(attr)]: origin=constant, length=constant
}
说明:
1)PAGE用来标示存储空间的关键字,n最大为255,2812中,如前面所述,PAGE 0表示程序存储空间,PAGE 1表示数据存储空间;
2)name表示某一属性和地址范围的存储空间名称,名称可以是1~8个字符,在同一页内,名称不能相同,不同页的名称可以相同;
3)attr表示该存储空间的属性,共有四种属性——只读R、只写W、该空间包含可执行代码X、该空间包含被初始化代码I,此选型通常忽略;
4)origin是用来定义存储空间起始地址的关键字;
5)length是用来定义存储空间起始地址的关键字。
SECTIONS语法如下:
SECTIONS
{
name 0: >存储空间名称, PAGE=页数
name n: >存储空间名称, PAGE=页数
}
说明:
1) name表示编译器输出段的名称;
2) 存储空间名称,是指用MEMORY伪指令指示的存储空间名称;
3) PAGE是对应的页。
在C程序中,有如下的声明:
#pragma DATA_SECTION(sin[256], “sinetable”)
int sin[256]={………..};
在CMD文件中:
MEMORY
{
PAGE 0:
SIN: origin=0x0000, length=0x0100 /*起始地址为0x0000,长度为256*/
……
PAGE 1:
……
}
SECTIONS
{
……
sinetable :>SIN, PAGE=0
……
}
这样CCS在编译时,就将程序中定义的正弦表sin[256],放到程序存储器地址以0x0000开头的长度为256的存储空间中。
用户403664 2012-10-30 09:34
飞言走笔 2012-10-28 21:45