一、前言
CMD文件,全名连接命令文件(linker command files),以后缀.cmd结尾。CMD文件就是用户的一个声明,用来分配DSP工程中rom和ram空间的,告诉链接程序怎样计算地址和分配空间。
1、 用户声明的整个系统里的存储器资源。无论是DSP 芯片自带的,还是用户外扩的,凡是可以 使用的、需要用到的存储器和空间,用户都要一一声明出来:有哪些存储器,它们的位置和大小。如果有些资源根本用不到,可以视为不存在,不必列出来;列出来也无所谓。
2、 用户如何分配这些存储器资源,即关于资源分配情况的声明。用户根据自己的需要,结合芯片的要求,把各 种数据分配到适当种类、适当特点、适当长度的存储器区域。
二、cmd文件的构成
目标文件至少包含三个默认段:
.text 文本段 通常包含可执行代码
.data 数据段 通常包含初始化的数据
.bss 保留空间段 通常为没有初始化的变量保留空间
自定义段:
.usect 保留空间段 为没有初始化的数据保留空间的自定义段
.sect 初始化段 自定义段
.asect 初始化段
和默认段的使用相同,但它们被单独汇编。例如,重复使用.text段在目标文件中创建单个.text段,在链接时,这个.text段作为单个单元分配到存储器中。假中有一部分可执行代码(如初始化程序)不希望和.text段分配在一起,可以将它们汇编进一个自定义段,这样就可以分配在与.text段不同的地方。
三、如何编写一个cmd文件
在编写CMD文件时,主要采用MEMORY和SECTIONS 两条伪指令(必须大写)。
MEMORY伪指令
作用:指示存储空间,资源清单标识,具体内容写在后面的大括号{ } 里面。对DSP系统的ROM(如DSP芯片内ROM,FLASH,外挂ROM)和RAM划分为N个不同的区间。这些区间根据存储目的可以分为两大类:程序存储(对应于PAGE 0)和数据存储(对应于PAGE 1)。
语法如下:
MEMORY
{
PAGE 0 : name 0[(attr)]:origin = constant, length = constant
PAGE n : name n[(attr)]:origin = constant, length = constant
}
PAGE:用来指示存储空间的关键字。PAGE n的最大值为255。
name:代表某一属性和地址范围的存储空间名称。长度可以是1~8个字符,在同一页内名称不能相同,不同页内名称可以相同。
attr:用来规定存储空间的属性,共有四种属性:R-只读、W-只写、X-该空间包含可执行代码、I-该空间可以被初始化。实际使用,常忽略此选项。
orgin:用来定义存储空间起始地址的关键字。
length:用来定义存储空间长度的关键字。
举例
MEMORY
{
PAGE 0 :
FLASH : origin = 0x3D8000, length = 0x01FF80 /* FLASH */
BEGIN : origin = 0x3F7FF6, length = 0x000002
ROM : origin = 0x3FF000, length = 0x000FC0
RESET : origin = 0x3FFFC0, length = 0x000002
RAML0 : origin = 0x008000, length = 0x001000
PAGE 1 :
RAMM0 : origin = 0x000000, length= 0x000400 /* RAM M0 */
RAMM1 : origin = 0x000400, length= 0x000400 /* RAM M1 */
RAML1 : origin = 0x009000, length = 0x001000 /* RAM L1 */
RAMH0 : origin = 0x3F8000, length= 0x002000 /* RAM H0 */
}
SECTIONS中的段名有两个来源:系统自动生成和用户自定义。
如下为系统自动生成的段名:(通用部分)
.cinit 存放程序中的变量初值和常量
.const 存放程序中的字符常量、浮点常量和用const声明的常量
.switch 存放程序中switch语句的跳转地址表
.text 存放程序代码
.bss 为程序中的全局和静态变量保留存储空间
.far 为程序中用far声明的全局和静态变量保留空间
.stack 为程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递、存储局部变量和中间结果
.sysmem 用于程序中的malloc 、calloc 、和realoc 函数动态分配存储空间。
SECTIONS伪指令
作用:分配段到存储空间,也就是指定段的实际硬件地址空间。
语法如下:
SECTIONS
{
name 0 : > 存储空间名称, PAGE = 页数
name n : > 存储空间名称, PAGE = 页数
}
name :编译器输出段的名称。
存储空间名称:采用MEMORY伪指令指示的存储器空间名称。
PAGE :前面存储器空间名称对应的存储器页。
举例
SECTIONS
{
.cinit : > FLASH, PAGE = 0
.text : > FLASH, PAGE = 0
.const : > FLASH, PAGE = 0
.econst : > FLASH, PAGE = 0
.stack : > RAMM0, PAGE = 1
.bss : > RAML1, PAGE = 1
.ebss : > RAML1, PAGE = 1
}
段分为两类:已初始化段 (Initialized Sections)和未初始化段(Uninitialized Sections)。以下是常用的一些段(不全):
“.vectors” , 表示“中断向量段”
“.text” , 编译后生成的二进制指令代码段
“.cinit”段,“对全局变量和静态变量初始化的常数” 。
“.bss” ,“保存全局变量和静态变量”,它属于“未初始化的”段,
“.stack”,堆栈,它属于“未初始化的”段,定位在数据空间。
“.extdata”,用户自定义的段, 属于“未初始化的”
未初始化段
未初始化段在存储器(通常是RAM)中保留空间,程序在运行时可在此空间创建和存储变量。C编译器创建如下非初始化块:
.bss段:为全局和静态变量保留空间。程序引导过程中,C引导程序会将ROM中的.cint块中的数据复制到.bss块中;
.ebss段:为用far声明的或大存储器模式下的全局和静态变量保留空间。程序引导过程中,C引导程序会将ROM中的.cint块中的数据复制到.bss块中;
.stack段:为C系统的堆栈分配的空间,用于函数调用时传递参数以及为局部变量分配空间;
.sysmem段:为动态存储器分配保留空间,如果未用到malloc函数,则该块的空间为0;
.esysmem段:为动态存储器分配保留空间,如果未用到far malloc 函数,则该块的空间为0。
四、注意事项
1.主要有PAGE0和PAGE1,PAGE0上的memory可以overlay到PAGE1 and so on
2. origin和length都是22bit的常数,在以前的一些dsp由于它的地址总线是16bit的,所以相应的origin和length只能为16bit的常数。
3. Sections以name开始,name就是定义的输出段。
4. load的格式有: load=allocation or allocation or >allocation
5. run的格式有:run = allocation or run>allocation
具体cmd文件的使用ti有详细的文档说明,不再重复。