DSP之CMD文件

DSP之CMD文件

在这里插入图片描述

用户希望将某一段,尤其是自定义段,放在什么存储器的什么位置,这也是链接器不知道的。为了告诉链接器,即将使用的芯片其内部存储空间的分配和程序各段的具体存放位置,这就需要编写一个配置文件,即CMD文件了。

CMD是链接器配置文件,指明连接器如何链接obj、lib等文件,生成可执行文件(.out)。

cmd文件是使用TI芯片很重要的一步,了解它,能对整个软件系统的分布,对芯片本身资源的使用有一个更清晰的了解,从而达到优化系统的目的。

CMD文件一句话来表达:定义芯片内部硬件资源和分配管理软件代码的一个配置文件。因此从cmd文件的组织上你能看到两个部分:1定义硬件资源,2管理软件代码,用户通过编写CMD 文件,来管理、分配系统中的所有物理存储器和地址空间。

CMD文件里面最重要的就是两段,即由MEMORY和SECTIONS两个伪指令指定的两段配置。简单的说,MEMORY就是用来建立目标存储器的模型,而SECTIONS指令就是根据这个模型来安排各个段的位置。

功能:
指示存储空间
分配段到存储空间
修改链接配置,如:
① -l test.lib链接文件
② -o test.out重定义生成可执行文件名称
③ -m test.map 重定义生成map文件名称
④ -stack 0x1000 栈大小0x1000字节
⑤ -heap 0x10000 堆大小为0x10000字节
注:在CMD文件中修改配置会覆盖工程配置

CMD文件其实就是用户的“声明” ,包括两方面的内容:

1、用户声明的整个系统里的存储器资源。无论是DSP 芯片自带的,还是用户外扩的,凡是可以 使用的、需要用到的存储器和空间,用户都要一一声明出来:有哪些存储器,它们的位置和大小。如果有些资源根本用不到,可以视为不存在,不必列出来;列出来也无所谓。

2、用户如何分配这些存储器资源,即关于资源分配情况的声明。用户根据自己的需要,结合芯片的要求,把各 种数据分配到适当种类、适当特点、适当长度的存储器区域

MEMORY                  /* #2 声明存储空间 */

{

PAGE 0 ://PAGE 0程序存储空间

VECS  : origin = 0000h , length =0040h  /* 中断向量   */  /* #3 */

PROG  : origin = 0100h , length =7F00h  /* 片上 FLASH  */  /* #4 */

 

PAGE 1 ://PAGE1 数据存储空间

B2   : origin = 0060h , length =0020h  /* DARAM B2 块 */  /* #5 */

B0B1  : origin = 0200h , length =0200h  /* DARAM B0 块 */  /* #6 */

SARAM : origin = 0800h , length = 0800h /* SARAM 块  */  /* #7  */

ExtSRAM : origin = 8000h , length = 8000h /* 外部存储器  */  /* #8  */

}

/**********************************************************************************************/

SECTIONS                  /* #9 分配段到存储空间 */

{

.vectors :  > VECS  PAGE 0  /* 中断向量表  */  /* #10 */.vectors代表输出段, >VECS同样可以写成load=VECS或VECS,和load平级的还有run,run定义输出段将会在哪里运行,语法run=VECS或run>VECS,当只出现一个run或load时表示地址相同

.text  :  > PROG  PAGE 0   /* 代码    */  /* #11 */

.cinit  :  > PROG  PAGE 0          /* #12 */

 

.bss  : > SARAM PAGE 1          /* #13*/

这个其实是.bss load = SARAM PAGE1

                   {

*.(bss)

                    }的简写。表示输入端和输出段同名

.stack  :  > B0B1  PAGE 1          /* #14 */

 

.extdata :  > ExtSRAM PAGE 1          /* #15 */ }

/**********************************************************************************************/

1 资源清单

如上文所述,CMD 文件包含两大内容,首先就是存储器的资源清单,或者说,系统中 (电路板上)可用的存储器资源。TI 规定,CMD文件的资源清单用关键字“MEMORY”作为标识,具体内容写在后面的大括号{ } 里面。如下面的形式:

MEMORY

{

PAGE 0:

xxx  : org = 0x1234 ,  length = 0x5678  /*This is my house.*/

PAGE 1:

aaa  : org = 0x1357 ,  length = 0x2468  /*My home here.*/

}

其中,MEMORY,PAGE n,org,length,包括冒号、等于号、花括号,都是关键字符,必不可少。PAGE n表示把可用的资源空间再划分成几个大块,最多允许分256块,从PAGE0到PAGE 255。很多关键字,还允许有别的写法,比 如“org”可以写为“o” ,“length”可以写为“len” 。这些规定和其他细节,可以去查阅TI 的pdf 文档。

2 资源的分配

首 先,SECTIONS,PAGE,包括花括号、冒号,都是关键字符。注意:SECTIONS字符是复数形式。在花括号内,每一行最左侧的“.vectors” 、“.text” 、“.cinit” 、“.bss” 、“.stack”这些名称,包括小数点,都是TI 默认的关键字符,只有“.extdata”是用户自己定义的名称。另外,“VECS”、“PROG” 、“SARAM” 、“B0B1” 、“ExtSRAM”必须是在MEMORY 里声明过的资源名称。
段分为两类:已初始化段 (Initialized Sections)和未初始化段(Uninitialized Sections)。以下是常用的一些段(不全):
“.vectors” , 表示“中断向量段”
“.text” , 编译后生成的二进制指令代码段
“.cinit”段,“对全局变量和静态变量初始化的常数” 。
“.bss” ,“保存全局变量和静态变量”,它属于“未初始化的”段,
“.stack”,堆栈,它属于“未初始化的”段,定位在数据空间。
“.extdata”,用户自定义的段, 属于“未初始化的”

注意:
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

比如text代码一般应该放在flash内,而bss的变量应该放在ram内。
在这里插入图片描述
在这里插入图片描述

//###########################################################################
// 文件:  F28035.cmd
// 说明:  F28035连接命令文件
//###########################################################################
/* 
定义F28035内存块的起始地址及长度
PAGE 0 为代码段
PAGE 1 为数据段
注意:
F2803x的内存块对于PAGE 0和PAGE 1是共用的。
同一个内存块不能同时定义为PAGE 0和PAGE 1。会造成程序的混乱。
L0内存块是被镜像的:可以在高地址内存或都低地址内存被访问。
在这里只使用低地址内存。当需要一片很大的的内存块时,SARAM内存块
或者FLASH段可以连接在一起。
*/
MEMORY
{
PAGE 0:    /* 程序内存块 */
   RAML0       : origin = 0x008000, length = 0x000800     /* 片上 RAM block L0 */
   RAML1       : origin = 0x008800, length = 0x000400     /* 片上 RAM block L1 */
   OTP         : origin = 0x3D7800, length = 0x000400     /* 片上 OTP */
   FLASHH      : origin = 0x3E8000, length = 0x002000     /* 片上 FLASH */
   FLASHG      : origin = 0x3EA000, length = 0x002000     /* 片上 FLASH */
   FLASHF      : origin = 0x3EC000, length = 0x002000     /* 片上 FLASH */
   FLASHE      : origin = 0x3EE000, length = 0x002000     /* 片上 FLASH */
   FLASHD      : origin = 0x3F0000, length = 0x002000     /* 片上 FLASH */
   FLASHC      : origin = 0x3F2000, length = 0x002000     /* 片上 FLASH */
   FLASHA      : origin = 0x3F6000, length = 0x001F80     /* 片上 FLASH */
   CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     
   /* FLASHA的一部分.  Program with all 0x0000 when CSM is in use. */
   BEGIN       : origin = 0x3F7FF6, length = 0x000002
   /* FLASHA的一部分.  使用了启动引导FLASH模式 */
   CSM_PWL_P0  : origin = 0x3F7FF8, length = 0x000008     
   /* FLASHA的一部分.  CSM password locations in FLASHA */
/*
说明
CSM_RSVD是Code Security Module_reserved的意思,
是指当使用代码 安全模块时,origin = 0x3F7F80, length = 0x000076
这个内存块是受保留的reserved。不能放程序代码或者数据块。且必须初始化为0x0000.
CSM_PWL是password locations的意思,即存放密码的地方
BEGIN是程序启动的开始地址。
*/
   IQTABLES    : origin = 0x3FE000, length = 0x000B50     /* 在引导ROM中的IQ数学表  */
   IQTABLES2   : origin = 0x3FEB50, length = 0x00008C     /* 在引导ROM中的IQ数学表  */
   IQTABLES3   : origin = 0x3FEBDC, length = 0x0000AA     /* 在引导ROM中的IQ数学表  */

   ROM         : origin = 0x3FF27C, length = 0x000D44     /* 启动引导 ROM */
   RESET       : origin = 0x3FFFC0, length = 0x000002     
   /* 启动引导 ROM的一部分 复位地址BROM矢量  */
   VECTORS     : origin = 0x3FFFC2, length = 0x00003E
   /* 启动引导 ROM的一部分  BROM矢量*/

PAGE 1 :   /* 数据内存块 */
   BOOT_RSVD   : origin = 0x000000, length = 0x000050 
       /* M0的一部分, 预留给启动引导 ROM时的栈空间 */
   RAMM0       : origin = 0x000050, length = 0x0003B0     /* 片上 RAM  M0 */
   RAMM1       : origin = 0x000400, length = 0x000400     /* 片上 RAM M1 */
   RAML2       : origin = 0x008C00, length = 0x000400     /* 片上 RAM L2 */
   RAML3       : origin = 0x009000, length = 0x001000     /* 片上 RAM L3 */
   FLASHB      : origin = 0x3F4000, length = 0x002000     /* 片上 FLASH */
}
/* 
将各个段分配到内存块.
注意:  codestart段在 DSP28_CodeStartBranch.asm中被定义,用于引导FLASH时,重定向代码。
ramfuncs段内的函数会从FLASH被转移到RAM中运行。
*/
SECTIONS
{
   .cinit    : > FLASHA   PAGE = 0  /* 初始化的全局变量和static变量表*/
   .pinit    : > FLASHA   PAGE = 0  /* 全局对象的构造函数表  C++范畴*/
   .text     : > FLASHA   PAGE = 0  /* 可执行代码和常数段 */
   codestart : > BEGIN    PAGE = 0  /* 代码启动段 */
   ramfuncs  : LOAD = FLASHD, /* 将定义到段ramfuncs上的代码,载入到FLASHD */
       RUN = RAML0,  /* 定义到ramfuncs上的代码,复制到RAML0上运行 */
       LOAD_START(_RamfuncsLoadStart), /* 所要加载程序在Flash里的初始地址 */
       LOAD_END(_RamfuncsLoadEnd), /* 所要加载程序在Flash里的结束地址 */
       RUN_START(_RamfuncsRunStart),     /* 程序运行的起始地址 */
       PAGE = 0
   csmpasswds: > CSM_PWL_P0  PAGE = 0    /* 密码段 */
   csm_rsvd  : > CSM_RSVD    PAGE = 0/* 使用代码安全模块时,需要预留的段  */

   /* 未初始化数据段: */
   .stack    : > RAMM0       PAGE = 1    /* 栈空间*/
   .ebss     : > RAML2 | RAML3  PAGE = 1
   /* 长调用的全局或static变量,初始化和未初始化变量*/
   .esysmem  : > RAML2 | RAML3  PAGE = 1

   /* 已初始化的段 */
   .econst   : > FLASHA      PAGE = 0   
   /* 字符串常量和far const定义的全局和静态变量(static const)*/
   .switch   : > FLASHA      PAGE = 0
   /* 存放switch语句产生的常数表格*/
   /* 分配 IQ 数学表区域  : */
   IQmath    : > FLASHA      PAGE = 0            /* Math Code */
   IQmathTables   : > IQTABLES,   PAGE = 0, TYPE = NOLOAD  /* 不载入*/
/*
.reset是由编译器使用的。它包含了C代码的开始地址_c_int00。
使用启动引导ROM的这部分和CPU向量表是不需要的。默认的类型被设置为dsect
*/
   .reset    : > RESET,      PAGE = 0, TYPE = DSECT 
   /* DSECT 说明这一块地址并不会真的加载数据,只是链接一下symbol。*/
   vectors   : > VECTORS     PAGE = 0, TYPE = DSECT
}
/*说明
编译器生成的包含代码和数据的多个部分,称为段。这个段被分为两个不同的组:初始化了的和没被初始化的。
初始化的部分是由所有的代码,常量和初始化表组成的。下面列出了由编译器产生的初始化段。
                            初始化段
段名      内容                                           限制
.cinit  初始化的全局变量和static变量表                     代码
.const  初始化的全局const变量和static const变量和字符串常量 不超过64K长度
.econst 长调用的常量                                      数据中的任何地方
.pinit  全局对象的构造函数表                               代码
.switch switch语句产生的表                                代码或者数据
.text   可执行代码和常数                                  代码
没初始化的段是由未初始化的变量,堆栈和malloc产生的内存。下表列出了由编译器产生的没初始化段。
                            没初始化段
段名          内容                      限制
.bss        全局变量和static变量         不超过64K长度
.ebss       长调用的全局变量和static变量   数据中的任何地方
.stack      栈空间                      不超过64K长度
.sysmem     malloc函数产生的内存         不超过64K长度
.esysmem    far_malloc函数产生的内存      数据中的任何地方

已初始化的段:.text,.cinit,.const,.econst,.pinit和.switch..
.text:所有可以执行的代码和常量
.cinit:全局变量和static变量的C初始化记录,
包含未用const声明的外部(extern)或静态(static)数据表
.const:包含字符串常量和const定义的全局和static变量
.econst:包含字符串常量和初始化的全局变量和static变量(由far const)
的初始化和说明,与.const不同的是.const分配范围被限制在低64K 
16位数据区,而.econst的分配范围是4M 22位数据区
.pinit:全局构造器(C++)程序列表,注意是全局的构造器。
.switch:包含大switch段声明的列表。Jump tables for large switch statements。
非初始化的段:.bss,.ebss,.stack,.sysmem,和esysmem.
.bss: 为全局变量和局部变量保留的空间,在程序上电时.cinit空间中的数据复制出来并存储在.bss空间中。
.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,
cinit空间中的数据复制出来并存储在.ebss中,与.ebss不同的是.bss分配范围被限制在低64K 16位数据区,
而.ebss的分配范围是4M 22位数据区
.stack:为系统堆栈保留的空间,用于和函数传递变量或为局部变量分配空间。
.sysmem:为动态存储分配保留的空间。如果有宏函数,此空间被宏函数占用,如果没有的话,此空间保留为0
.esysmem:为动态存储分配保留的空间。如果有far函数,此空间被相应的占用,如果没有的化,此空间保留为0.
ramfuncs: LOAD = FLASHD,表示ramfuncs段的装载在PAGA0的FLASHD中。
RUN = RAML0,表示ramfuncs段的运行地址在PAGE0的RAML0中
LOAD_START(_RamfuncsLoadStart),
令编译器创建了一个变量RamfuncsLoadStart,该变量指向段
ramfuncs的装载地址的首地址。 
LOAD_END(_RamfuncsLoadEnd),
令编译器创建了一个变量RamfuncsLoadEnd,该变量指向段ramfuncs的装载地址的末地址。
RUN_START(_RamfuncsRunStart),
令编译器创建了一个变量RamfuncsRunStart,该变量指向段ramfuncs的运行地址的首地址。
解释一下什么叫长调用,指的是程序指令的寻指范围。
上面说了绝对调用的寻指范围是16位数据区,长调用的寻指范围是22位数据区 。
*/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

傻童:CPU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值