DSP 中的自定义段和CMD
(2012-12-12 14:32:14)
标签:
dspcmdpragma杂谈 |
分类: DSP |
1.
1>
2>
3>
2.
1>
.text可执行代码
.data已初始化数据
.bss为未初始化数据保留的空间
2>
未初始化块
初始化块
未初始化块(data)
初始化块
3>
在CCS编程中,如果我们不指定变量的存放位置,编译器会自动的给变量分配一个位置,但是如果有的时候需要把变量放在一个特定的空间内,我们应该如何操作呢,CCS提供了如下的两个指令
#pragma CODE_SECTION
#pragma DATA_SECTION
其中data_section是针对数据空间的,code_section是针对程序空间的,具体的使用办法是
#pragma DATA_SECTION(bufferB, ”my_sect”)
char bufferB[512];
在.cmd文件中建立对应的section就可以使用了。
#pragma DATA_SECTION(函数名或全局变量名,"用户自定义在数据空间的段名");
#pragma CODE_SECTION(函数名或全局变量名,"用户自定义在程序空间的段名");
注意
不能在函数体内声明。
必须在定义和使用前声明
#pragma可以阻止对未调用的函数的优化
3.
它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间.所以不同的芯片就有不同大小的rom和ram.放用户程序的地方也不尽相同.所以要根据芯片进行修改.分两部分.MEMORY和SECTIONS.
(1):存储器(MEMORY)伪指令,用来定义目标系统的存储器空间。MEMORY可以定义存储器的区域,并指定起始地址和长度。
(2):段(SECTOINS)伪指令,告诉链接器如何将输入段结合成输出段并告诉链接器将输出段放在存储器的何处。
MEMORY伪指令的一般语法:
MEMORY
{
}
PAGEn中的页号n最大为255。每个PAGE代表一个完全独立的地址空间。通常PAGE0为程序存储器,PAGE1为数据存储器。
Name1:存储器区间名。可包含8个字符。不同PAGE可以取同样的name1,但在同一个PAGE内区间名不可以相同。
Attr:可选项。规定存储器属性。
R,可以对存储器执行读操作
W,可以对存储器执行写操作
X,破除可以装入可执行的程序代码
I,规定可以对存储器进行初始化
Origin:起始地址。
Length:区间长度。
初始化段用SECTIONS可定位两次:装入和运行。如:一些关键的执行代码必须装在系统的ROM中,但希望在较快的RAM中运行。
未初始化段只可被定位一次。
1、MEMORY是用来指定芯片的rom和ram的大小和划分出几个区间.
例如:
MEMORY
{
}
其中o和l参数反映了该区间的起始地址和长度。
2、SECTIONS:
在程序里添加下面的段名如.vectors.用来指定该段名以下,另一个段名以上的程序放到“>”符号后的空间名字所在的地方。
例如
SECTIONS
{
}
3>
-l
rts2800_ml.lib
-o
filename.out
-m
filename.map
-stack
0x200
下面是一个例子
在CMD 文件中:
MEMORY
{
PAGE 0 :
PAGE 1 :
}
SECTIONS
{
}
在C语言中
#define BUF_SIZE
#pragma DATA_SECTION(DMABuf1,"DMARAML4");
#pragma DATA_SECTION(DMABuf2,"ZONE7DATA");
volatile Uint16 DMABuf1[BUF_SIZE];
volatile Uint16 DMABuf2[BUF_SIZE];
再比如,配置28335从内部flash启动时,
我们预定义
#pragma CODE_SECTION(epwm1_timer_isr, "ramfuncs");
#pragma CODE_SECTION(epwm2_timer_isr, "ramfuncs");
程序中调用一个函数
// The
// symbols are created by the linker. Refer to the
定义如下
void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)
{
}
系统自带的段名:(选择部分)(常见于DSP28x_CodeStartBranch.asm)
.reset
用法如下:
SECTIONS
{
.reset
}
codestart
FLASH的控制寄存器受代码安全模块CSM保护,因此如果DSP是安全的(烧写后的FLASH往往处于这种状态),则必须从受保护的RAM中执行FLASH寄存器初始化代码。
InitFlash()位于DSP281x_SysCtril.c文件中,为FLASH寄存器初始化用,将次程序放进.ramfuncs块中。
{
上例中SECTIONS段的语法如下:
SECTIONS
{
name : [property,property,……]
}
name:输出段的名称
property:输出段的属性:
另:CMD文件中只出现一个关键字load或run时,表示两者的地址时表示两者的地址时重合的。
LOAD_ START(_RamfuncsLoadStart)令编译器创建了一个变量RamfuncsLoadStart,该变量指向段ramfuncs的装载地址的首地址(LOAD_ START为编译伪指令,请见CCS的帮助文档);
LOAD_ START(_RamfuncsLoadEnd)令编译器创建了一个变量RamfuncsLoadEnd,该变量指向段ramfuncs的装载地址的末地址(LOAD_ END为编译伪指令,请见CCS的帮助文档);
LOAD_ START(_RamfuncsRunStart)令编译器创建了一个变量RamfuncsRunStart,该变量指向段ramfuncs的运行地址的首地址(LOAD_ START为编译伪指令,请见CCS的帮助文档);
在C函数中,为了使用变量RamfuncsLoadStart、RamfuncsLoadEnd和RamfuncsRunStart,必须先声明。MemCpy()位于DSP281x_MemCopy.c文件中,在对FLASH寄存器初始化时,用于将指定的FLASH中的程序段复制到指定的RAM区中。如例:
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
……
Void main(main)
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
……
}
根据自己的经验,codestart块与reset块并没有什么用处。
在运行C程序(main函数)之前,必须创建C运行环境。这个任务由C引导程序(BOOTRAM中固化的导引加载程序)使用名为c_int00()的子程序来执行。此函数位于rts.lib文件中。
在系统开始运行时,c_int00()可以被调用,通常由硬件复位来调用。必须将c_int00()与其他的目标模块连接起来,当使用C连接器并且包含rts28xx.lib作为连接器输入文件时,以上调用自动实现。当连接C程序时,连接器将可执行输出模块中的入口点的值赋给c_int00()函数,这些可执行输出模块不尽相同,但最为人关心的则是由c_int00()来启动main()函数运行自己的C程序。
而在 .codestart 和 .reset代码块的编写的汇编程序的功能也仅仅是引导BOOTROM中的导引加载程序与c_int00()函数的衔接。