以.CMD 为扩展名的文件,这个文件的作用是用来分配存储空间的。由于DSP 编译器的编译结果是未定位的,DSP 也没有操作系统来定位执行代码,DSP 系统的配置需求也不尽相同,因此我们根据实际的需求,自己定义代码的存储位置。打个通俗的比喻,就是我们有一个仓库,现在需要把货物存放到仓库里面去,为了便于日后取用货物,我们将货物分门别类,然后把它们存放到指定的位置去。把哪些货物放到哪个位置的规则,就是我们的CMD文件的内容。
CMD文件,又称链接命令文件,主要作用是分配rom和ram空间,它告诉链接程序怎样计算地址和分配空间。例如,应该把程序放在哪块地址内,把数据放在哪块地址内以及把程序中定义的某些变量(如图中的 i 所示)放在哪块地址内。
首先,CMD文件分为三大部分:a.输入输出定义;b.MEMORY 和c .SECTIONS。
输入输出定义: 这一部分,可以通过ccs的“Build Option…”菜单设置
。obj 链接的目标文件
。lib 链接的库文件
。map 生成的交叉索引文件
。out 生成的可执行代码
以及堆栈的设置:
-stack :又称系统栈(system stack),用于:保存函数调用后的返回地址;给局部变量分配存储空间;传递函数参数;保存临时结果。
-heap :编译器提供的运行时支持库的一些函数(如malloc/calloc/realloc),允许运行时为变量动态分配存储器。这些存储器就放置在.system段的全局池(global pool)或堆(heap)中。这个动态存储池的大小仅仅受限与系统中实际的存储容量。
这2个选项都可以在project-build options的连接器选项中设置
综上所述,简单比较堆和栈的区别是:堆是程序中动态申请内存的地方,栈是函数嵌套调用,中断,任务切换时保护现场时存储相关寄存器的地方。
.MEMORY: 用来表示实际存在目标系统中的可以使用的存储器范围,在这里每个存储器都有自己的名字,起始地址和长度。也就是说MEMORY是用来指定芯片的rom和ram的大小和划分存储区间的。
.SECTIONS: 在程序里添加段名.XXXX(如.vectors.)用来指定该段名以下,另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。
例如:
-c
-o hello.out
-m hello.map
-stack 100
-l rts2xx.lib
MEMORY
{
PAGE 0: VECS: origin = 00000h, length = 00040h
LOW: origin = 00040h, length = 03FC0h
SARAM: origin = 04000h, length = 00800h
B0: origin = 0FF00h, length = 00100h
PAGE 1: B0: origin = 00200h, length = 00100h
B1: origin = 00300h, length = 00100h
B2: origin = 00060h, length = 00020h
SARAM: origin = 08000h, length = 00800h
}
SECTIONS
{
.text : { } > LOW PAGE 0
.cinit : { } > LOW PAGE 0
.switch : { } > LOW PAGE 0
.const : { } > SARAM PAGE 1
.data : { } > SARAM PAGE 1
.bss : { } > SARAM PAGE 1
.stack : { } > SARAM PAGE 1
.sysmem : { } > SARAM PAGE 1
}
存储模型说明:
.cinit 存放程序中的变量初值和常量
.const 存放程序中的字符常量、浮点常量和用const声明的常量
.switch 存放程序中switch语句的跳转地址表
.text 存放程序代码
.bss 为程序中的全局和静态变量保留存储空间
.far 为程序中用far声明的全局和静态变量保留空间
.stack 为程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递、存 储局部变量和保存中间结果
.sysmem 用于程序中的malloc 、calloc 、和realoc 函数动态分配存储空间.text可执行代码
注意: CMD文件里的注释,不能用双斜线,只能用/*… */
其次,撰写CMD文件的MEMORY部分时,需清楚特定型号的DSP芯片,其ROM、RAM和各个外部存储器的读取速度快慢和存储空间地址范围分别是多少;以及存放程序、数据和程序数据可共享的地址范围分别是多少和对应的读取速度快慢;同时还需了解各个存储模块的存储特性,是掉电丢失还是掉电不丢失,然后在平衡“非易失”和“速度”的情况下,才能根据需要定义程序、数据和变量等的存储空间。
对于SECTIONS部分的撰写,则需要清楚其各个模块所代表的含义是什么,是存放程序代码的还是存放程序中的变量的亦或是存放数据的,才能将SECTIONS中的各个模块正确指向MEMORY中分配的合适的地址。
文章中部分内容参考自网络,如有侵权,请联系作者,立即删除!!!
参考资料:
1.https://blog.csdn.net/nuaamkx/article/details/7698303
2.https://www.cnblogs.com/leaven/p/6370565.html