DSP CMD文件

Pragma伪指令:https://blog.csdn.net/LGM_1874/article/details/107658223

CMD文件

链接命令文件(Linker Command Files),以后缀 .cmd 结尾,简称CMD文件。

功能:指示存储空间、分配段到存储空间

编写:采用 MEMMORYSECTIONS 两条伪指令;

将程序代码链接到 Flash 或 RAM 对应两种 CMD 文件。

COFF概念

通用目标文件格式(Common Object File Format),一种流行的二进制可执行文件格式

包括:

  • (.lib) 库文件
  • (.obj) 目标文件
  • (.out) 最终可执行文件

段概念

使用段的好处是鼓励模块化编程,提供更强大而又灵活的方法来管理代码和目标系统的存储空间。这里模块化编程的意思是指程序员可以自由决定愿意把哪.些代码归属到哪些段,然后加以不同的处理。比如,把已经初始化的数据放到一个段里,未初始化的数据放到另-一个段里,而不是混杂的放在一-起。

编译器处理段的过程

1.把每个源文件都编译成独立的目标文件(以后缀.obj结尾),每个目标文件都含有自己的段。
2.连接器把这些目标文件中相同段名的部分连接在一起,生成最终的可执行文件(以后缀.out结尾)。

已初始化的段

  • .text:      编译C语言中的语句时,生成的汇编指令代码存放于此。
  • .cinit:     存放用来对全局和静态变量初始化的常数。
  • .const:   包含字符串常量和初始化的全局变量和静态变量(由const声明)的初始化和说明。
  • .econst: 包含字符串常量和初始化的全局变量和静态变量(由far const声明)的初始化和说明
  • .pinit:     全局构造器(C++) 程序列表。
  • .switch:   存放switch语句产生的常数表格。

未初始化的段

  • .bss:为全局变量和局部变量保留的空间,在程序.上电时,.cinit空间中的数据复制出来并存储在.bss空间中。
  • .ebss:为使用大寄存器(._ml)模式时的全局变量和静态变量预留的空间,在程序上电时,.cinit空 间中的数据复制出来并存在.ebss中。
  • .stack:为系统堆栈保留的空间,主要用于和函数传递变量或为局部变量分配空间。
  • .system:.为动态存储分配保留的空间。如果有宏函数,此空间被宏函数占用,如果没有,此空间保留为0。
  • .esysmem:为动态存储分配保留的空间。如果有far函数,此空间被相应的占用,如果没有,此空间保留为0。

段的存储特性

段的存储特性
存储器类型 分配的存储空间
.text ROM / RAM(Flash) PAGE0
.cinit ROM / RAM(Flash) PAGE0
.const ROM / RAM(Flash) PAGE1
.econst ROM / RAM(Flash) PAGE1
.pinit ROM / RAM(Flash) PAGE0
.switch ROM / RAM(Flash) PAGE0 / PAGE1
.bss RAM PAGE1
.ebss RAM PAGE1
.stack RAM PAGE1
.system RAM PAGE1
.esystem RAM PAGE1
通过 # pragma CODE_SECTION 定义的段 ROM / RAM(Flash) PAGE0
通过 # pragma DATA_SECTION 定义的段 RAM PAGE1

CMD文件的编写

MEMORY 伪指令【建立存储器模型】

作用:指示存储空间

语法:

MEMEORY
{
    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-该空间可以被初始化。实际使用时常忽略此选项;
    origin:用来定义存储空间起始地址的关键字;
    length:用来定义存储空间长度的关键字
*/

例子:

MEMORY
{
PAGE 0 :
   /* BEGIN is used for the "boot to SARAM" bootloader mode   */

   BEGIN      : origin = 0x000000, length = 0x000002
   RAMM0      : origin = 0x000050, length = 0x0003B0
   RAML0L1    : origin = 0x008000, length = 0x000D00
   RESET      : origin = 0x3FFFC0, length = 0x000002
   IQTABLES   : origin = 0x3FE000, length = 0x000B50     /* IQ Math Tables in Boot ROM */
   IQTABLES2  : origin = 0x3FEB50, length = 0x00008C     /* IQ Math Tables in Boot ROM */
   IQTABLES3  : origin = 0x3FEBDC, length = 0x0000AA	 /* IQ Math Tables in Boot ROM */

   BOOTROM    : origin = 0x3FF27C, length = 0x000D44


PAGE 1 :

   BOOT_RSVD   : origin = 0x000002, length = 0x00004E     /* Part of M0, BOOT rom will use this for stack */
   RAMM1       : origin = 0x000480, length = 0x000380     /* on-chip RAM block M1 */
   RAML2       : origin = 0x008D00, length = 0x000300
   RAML3       : origin = 0x009000, length = 0x001000
}

SECTION 伪指令【安排段的位置】

作用:分配段到存储空间,指定段的实际硬件地址空间。

语法:

SECTIONS
{
    name 0 :> 存储空间名称,PAGE = 页数
    name n :> 存储空间名称,PAGE = 页数
}
/*
    name:编译器输出段的名称;
    存储空间名称:采用 MEMORY 伪指令指示的存储器空间名称;
    PAGE:前面存储器空间名称对应的存储器页。
*/

例子:

SECTIONS
{
   codestart        : > BEGIN,     PAGE = 0
   ramfuncs         : > RAMM0      PAGE = 0
   .text            : > RAML0L1,   PAGE = 0
   .cinit           : > RAMM0,     PAGE = 0
   .pinit           : > RAMM0,     PAGE = 0
   .switch          : > RAMM0,     PAGE = 0
   .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

   .stack           : > RAMM1,     PAGE = 1
   .ebss            : > RAML2,     PAGE = 1
   .econst          : > RAML2,     PAGE = 1
   .esysmem         : > RAML2,     PAGE = 1

   IQmath           : > RAML0L1,   PAGE = 0
   IQmathTables     : > IQTABLES,  PAGE = 0, TYPE = NOLOAD
}

猜你喜欢

转载自blog.csdn.net/LGM_1874/article/details/107655786
dsp