邬小蕙 邬吉成:CMD文件的编写 zz

来源:百度文库 编辑:中财网 时间:2024/04/30 11:08:32
CMD文件的编写
TI的代码产生工具产生的目标文件是一种模块化的文件格式—COFF格式,代码和数据在COFF文件中以段的形式组织,一个COFF段是在memory map中占连续空间的一块code或data。COFF文件中包含了段的完备信息,如段的绝对地址,名字,属性以及数据等。这些段可分为两种,已初始化段和未初始化段;或者另一种分法,namely code,初始化data和未初始化data。已初始化段主要包括数据表和可执行代码,如:.text,.cinit,.const等;未初始化段用于保留存储器空间,程序利用这些空间在运行时创建和存储变量,如.bss段,.stack段,.far段,.sysmem段等。有些段并不是一定会有的,比如.sysmem段,如果C程序没有用到malloc,calloc等这些函数来分配存储器空间的话,编译器就不创建.sysmem块。每个段的具体内容是:
.text       存放可执行代码和浮点数常量
.cinit       存放已明确初始化的全局变量和静态变量
.const      存放已明确初始化的字符串常量,全局常量和静态常量
.bss       存放没有初始化的全局变量和静态变量。在小模式中,.bss块也为常数宏保留空间。在程序开始运行时,数据从.cinit块中拷贝至.bss块,这里是可以选择的,有两个选项-c和-cr决定了全局变量和静态变量的初始化方式。-c为运行时初始化,-cr为加载时初始化。编译器生成程序时,会将C程序中初始化的全局/静态变量的初始值按一定结构放在.cinit中,但实际全局/静态变量占用的地址空间在.bss段中。如果是-c选项,那么C初始化函数c_int00()会读取.cinit段中的记录信息,分别初始化.bss段中的全局/静态变量,最后调用main()函数。如果是-cr选项,那么全局/静态变量的初始化工作由loader程序完成,而不是c_int00()函数。也就是加载程序后,loader读取.cinit段的内容,然后初始化.bss的全局/静态变量,当使用JTAG调试时,CCS就是一个loader。
.stack     为系统堆栈分配存储器。这个存储器用于将变量传递至函数以及分配局部变量。
.far        以far声明的全局/静态变量
.sysmem   为动态存储器函数malloc、calloc、realloc分配存储器空间。
每个段都有一个load和run属性,load属性告诉loader或flash烧录程序在哪里放置这个段,run属性指出设备复位后这个段从哪里执行。所以,如果load属性和run属性不同,这个段将由二级bootloader从load地址拷贝到run地址,所有对段的references都是指它的run地址。一个段的run地址基于CPU访问该段的频率,如果一个段只被CPU访问一次,这个段就可以没有run地址,这样可以节省RAM空间,比如.cinit段一般只在boot时访问一次。而需要CPU快速访问的段则在RAM中有一个run地址。工程编译后的.map文件中包含了段的link信息,如段的size,load地址和run地址,我们可以从里边找到相关信息。
首先,编写cmd文件时必须熟悉你的DSP的存储器的地址范围。CMD是主要是根据那个来编写的,还有要注意MP/MC,PON以及DON这些位,它们都在PMST中,PMST的值可以在I/0的映射地址FFE4H中手动修改。 CMD 它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间.所以不同的芯片就有不同大小的rom和ram.放用户程序的地方也不尽相同.所以要根据你的芯片进行修改.cmd文件分两部分.MEMORY和SECTIONS. MEMORY {    PAGE 0 ..........      PAGE 1......... }   SECTIONS {SECTIONS { .vectors ................. .reset ................. ................   } MEMORY是用来指定芯片的rom和ram的大小和划分出几个区间. PAGE 0 对应rom;PAGE 1对应ram PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度. 如: PAGE 0 : VECS(区间名字): origin(起始地址) = 0h , length (长度) = 040h /*VECTORS*/   SECTIONS:(在程序里添加下面的段名如.vectors.用来指定该段名以下,另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。 如引用字段名“.vectors ”的程序或数据将被放到VECS ,VECS是PAGE0即是ROM空间 00H 至40H的地方   SECTIONS { .vectors : { } > VECS PAGE 0 /* Interrupt vector table */ .reset :    { } > VECS PAGE 0 /* Reset code */ ............ }   注:1..vectors,.reset都是段名。   加不加“.”随你便,即.vectors表示名为   “.vectors”的段。
     2.{}表示段的全部,{}> VECS PAGE 0表示将段的全部放入名为 VECS PAGE 0的内存区。 例子:  
/****************************************************************************/ /******** Specify the memory configuration **********************************/ /****************************************************************************/ 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 ALLOCATION   */ /*--------------------------------------------------------------------------*/   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 }   ps:
PAGE 就是对一个存储空间进行标记,最多可以有 255 个 PAGE,不同 PAGE 上的存储器区间可以取相同的名字 origin 写成 org、 o都可以 length 写成len、 l 都可以 其实 SECTIONS 中:和>中间的{}可以省略的.   MEMORY
{
PAGE 0: VECS : origin = 0h,length = 40h /* 程序复位 */
                PVECS : origin = 40h,length = 70h /* 外围模块中断向量 */
                PROG : origin = 0b0h,length = 7F50h    /* 在片FLASH */
PAGE 1: MMRS : origin = 0h ,length = 05Fh    /* MMRS */
                B2   : origin = 0060h ,length = 020h    /* DARAM B2 块 */
                B0   : origin = 0200h , length = 100h    /* DARAM B0 块 */
                B1   : origin = 0300h , length = 100h    /* DARAM B1 块 */
                SARAM : origin = 0800h , length = 0800h /* SARAM 块 */
                EXT   : origin = 8000h , length = 8000h    /* 外部存储器 */
}
/*--------------------------------------------------------*/
/* SECTIONS ALLOCATION */
/*---------------------------------------------------------*/
SECTIONS
{
.reset : { } > VECS PAGE 0    /* 复位中断向量表 */
.vectors : { } > VECS PAGE 0   /* 中断向量表 */
.pvecs : { } > PVECS PAGE 0   /* 外围模块中断向量表    */
.text : { } > PROG PAGE 0   /* 代码 */
.cinit : { } > PROG PAGE 0
.bss : { } > SARAM PAGE 1   /* 块 B2 */
.const : { } > SARAM PAGE 1   /* 块 B2 */   
.stack : { } > B1 PAGE 1   /* 堆栈-40个单元 */
}
I
整个文件分为MEMORY和SECTIONS两部分,MEMORY部分又分为PAGE0,PAGE1等,分别代表程序存储,数据存储单元,MEMORY区的语法结构是:Block Name : origin = Start Address ,length = Length其中,Block Name 使用户定义的,用于SECTIONS区的名称,可以自己命名Start Address是区段开始地址,Length是区段长度。
II
SECTIONS区的语法结构是:segment : { } > Name PAGE n 其中 segment 为程序区段,例如.text段,.bss段等等,Name为MEMORY区定义的Block Name,也就是segment对应的代码,将要放置在Block Name区段。
PAGE n是Block Name对应的PAGE
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/henhen2002/archive/2009/08/05/4411370.aspx  自己加一条网上看到的: 注意:CMD文件中的注释只能是/*……*/,没有//。与标准C语言不一样。