DSP

链接命令文件(*.cmd)和gel文件的介绍

2019-07-13 19:29发布

一个完整的DSP程序至少包含三个部分:程序代码、中断向量表、链接命令文件(或称链接配置文件)(*.cmd)。 链接配置文件确定了程序链接成最终可执行代码时的选项,其中有很多条目,实现不同方面的选项,其中最常用的也是必须的有两条:1.存贮器的分配;2.标明程序入口。如:   -e CodeStart MEMORY { page 0:    PRAM: org="0100h" len="0F00h"   } SECTIONS{ .text:>PRAM page 0   }   由于每个程序都需要一个链接配置文件,可以编写一个满足通常需要的链接配置文件。一个比较通用的链接配置文件:   -e CodeStart -m map.map    MEMORY { PAGE 0:    VECT: org=0080h len="0080h" PARAM:     org="100h" len="0F00h" PAGE 1:    DARAM: org="1000h" len="1000h" } SECTIONS { .text :> PARAM PAGE 0 .vectors :> VECT PAGE 0 stack :> DARAM PAGE 1 .bss :> DARAM PAGE 1 .data :> DARAM PAGE 1 }       MEMORY伪指令在命令文件中的书写方式为:以大写MEMORY开始,后面跟着由大括号括起来的一系列存储器范围说明。每一个存储器区间具有一个名称、起始地址以及存储器的长度。下面的实例为实用MEMORY伪指令的简单例子。在该例中,起始地址为数据存储器中的60H;B1块为256字节的RAM,起始地址为数据存储器中的200H;B0块为256字节的RAM,起始地址为数据存储器中的300H。 MEMORY {     PAGE0:     ROM:   origin=0h,length=1000h     PAGE1:     B2:    origin=60h,length=20h               B1:    origin=200h,length=100h               B0:    origin=300h,length=100h }   MEMORY伪指令的一般语法为: MEMORY {     PAGE0:name 1[(attr)]:origin=constant,length=constant     PAGE1:name n[(attr)]: origin="constant",length=constant } 其中,PAGE:对一个存储空间加以标记,每一个PAGE代表一个完全独立的地址空间。页号n最大可以为255(因为DSP最大寻址可以到64K),取决于目标存储器的配置。通常PAGE0为程序存储器,PAGE1为数据存储器。如果没有规定的PAGE,则链接器就当作PAGE0。 Name:对一个存储器区间名。可以包含8个字符。只是起到标记的作用。同一个PAGE内不能重名,不同PAGE可以。 Attr:这是一个任选项。为命名区规定1-4个属性。如果有选项,应写在括号内。当输出段定位到存储器时,可以利用属性加以限制。属性选项有如下四项: R:规定可以对存储器执行读操作。 W:规定可以对存储器执行写操作。 X:规定存储器可以装入可执行的程序代码。 I:规定可以对存储器进行初始化。 如果一项属性都没有选,则可以将输出段不受限制定位到任何一个存储器位置。就是任何一个没有规定的存储器都有四项属性。 Origin:规定一个存储区的起始地址。 Length:规定一个存储区的长度。   SECTION指令: 1、SECTIONS指令任务: (1)说明如何将输入段组合成输出段; (2)在可执行程序中定义输出段; (3)指定输出段在存储器中的存放位置; (4)允许重新命名输出段。 2、SECTIONS指令的一般语法如下: SECTIONS {   name:[property,property,property,……]   name:[property,property,property,……]   name:[property,property,property,……]   …… }     在链接器命令文件中,SECTIONS命令用大写字母,紧随其后并用大括号括起来的是关于输出段的说明语句。每一个输出段的说明都从段名开始,段名后是一行说明段的内容和如何给段分配存储单元的属性参数。一个段的属性参数包括: (1)  Load allocation,由它定义将输出段加载到存储器中的什么位置。语法为: Load=allocation(这里的allocation指的是地址) 或者> allocation 其中allocation是关于输出段地址的说明,即给输出段分配存储单元。具体写法有多种,例如: .text:load=0x1000    ;将输出段.text定位到一个特定的地址 .text:load>ROM    ;将输出段.text定位到命名为ROM的存储区 .text:   PAGE 0   ;将输出段定位到PAGE 0 (2)  Run allocation,由它定义输出段在存储器的什么开始运行。其语法为: run=allocation 或者 run>allocation 链接器为每个输出段在目标存储器中分配两个地址:一个是加载的地址,另一个是执行程序的地址。通常,这两个地址是相同的,可以认为每个输出段只有一个地址。有事要想吧程序的加载区和运行区分开,只要用SECTIONS命令让链接器对这个段定位两次就行了。一次是设置加载地址,另一次是设置运行地址。例如: .fir:load=ROM,run=RAM .data:load=ROM,align=32,run=RAM 3、为输出段指定地址 (1)  binding,将段定位到指定的地址。例如: .text:load=0x1000 (2)  memory,将段定位到由MEMORY伪指令定义的具有指定的名称(例如ROM)或属性的地址范围。例如: .text:load>ROM (3)  alignment,使用对准关键字,指定段的其实地址边界。例如: .text:align=0x80 (4)  blocking,使用块关键字指定段必须放置在2个地址边界之间,若段太大,将从一个地址边界开始。例如: .text:block(0x80) (5)  page,指定要使用的存储器页面。例如: .text:PAGE 0 4、MEMORY和SECTIONS指令的默认算法 如果没有利用MEMORY和SECTIONS命令,链接器就按缺省算法来定位输出段       ************************************************************************************************ ************************************************************************************************   GEL是通用扩展语言(General Extension Language)的英文缩写,GEL是一个大小写敏感但缺少类型检测的解释性语言,只有int类型,在语法上可看作是C语言的一个子集。GEL主要用来扩展CCS的功能,方便用户调试程序,但不是必需的。当我们希望上电后立刻开启或实现某些功能,那么可以在项目中装载GEL文件(由TI提供或用户自行编写)来实现这个目的。此外,项目添加TI公司提供的GEL文件后往往会在CCS的GEL菜单中出现相关的子菜单,用户可以使用它,主要用于程序的调试控制。GEL文件可以看成你所建项目的“秘书”,可以帮你打打杂,处理一些繁琐的事情。 下面是一段VC5509的通用GEL文件代码: StartUp()
{  
 GEL_MapOn();
 GEL_MapReset();  GEL_MapAdd(0x0000C0,0,0x00FF40,1,1); 
 GEL_MapAdd(0x010000,0,0x030000,1,1); 
 GEL_MapAdd(0x040000,0,0x3C0000,1,1); 
 GEL_MapAdd(0x400000,0,0x400000,1,1); 
 GEL_MapAdd(0x800000,0,0x400000,1,1); 
 
 GEL_MapAdd(0xC00000,0,0x400000,1,1); 
 
 GEL_MapAdd(0xFF0000,0,0x010000,1,0); 
 GEL_MapAdd(0x000000,1,0x000050,1,1); 
 GEL_MapAdd(0x000060,1,0x007FA0,1,1); 
 GEL_MapAdd(0x008000,1,0x018000,1,1); 
 GEL_MapAdd(0x020000,1,0x1E0000,1,1); 
 GEL_MapAdd(0x200000,1,0x200000,1,1); 
 GEL_MapAdd(0x400000,1,0x200000,1,1); 
 
 GEL_MapAdd(0x600000,1,0x200000,1,1); 
 
 
 GEL_MapAdd(0x0001,2,0x0002,1,1); 
 GEL_MapAdd(0x0400,2,0x0300,1,1); 
 GEL_MapAdd(0x07FE,2,0x0002,1,1); 
 GEL_MapAdd(0x0800,2,0x0014,1,1); 
 GEL_MapAdd(0x0C00,2,0x000C,1,1); 
 GEL_MapAdd(0x0C20,2,0x000C,1,1); 
 GEL_MapAdd(0x0C40,2,0x000C,1,1); 
 GEL_MapAdd(0x0C60,2,0x000C,1,1); 
 GEL_MapAdd(0x0C80,2,0x000C,1,1); 
 GEL_MapAdd(0x0CA0,2,0x000C,1,1); 
 GEL_MapAdd(0x0E00,2,0x0001,1,1); 
 GEL_MapAdd(0x0E03,2,0x0001,1,1); 
 GEL_MapAdd(0x1000,2,0x0004,1,1); 
 GEL_MapAdd(0x1800,2,0x000D,1,1); 
 GEL_MapAdd(0x1C00,2,0x0001,1,1); 
 GEL_MapAdd(0x1E00,2,0x0001,1,1); 
 GEL_MapAdd(0x2400,2,0x0004,1,1); 
 GEL_MapAdd(0x2800,2,0x001F,1,1); 
 GEL_MapAdd(0x2C00,2,0x001F,1,1); 
 GEL_MapAdd(0x3000,2,0x001F,1,1); 
 GEL_MapAdd(0x3400,2,0x0002,1,1); 
 GEL_MapAdd(0x3800,2,0x0005,1,1); 
 GEL_MapAdd(0x3C00,2,0x000D,1,1); 
 GEL_MapAdd(0x4000,2,0x0004,1,1); 
 GEL_MapAdd(0x4400,2,0x0006,1,1); 
 GEL_MapAdd(0x4800,2,0x001B,1,1); 
 GEL_MapAdd(0x4C00,2,0x001B,1,1); 
 GEL_MapAdd(0x5800,2,0x1000,1,1); 
 GEL_MapAdd(0x6800,2,0x0004,1,1); 
 GEL_MapAdd(0x6C00,2,0x0001,1,1); 
 GEL_MapAdd(0x7000,2,0x0002,1,1); 
 GEL_MapAdd(0x7400,2,0x0001,1,1);   GEL_TextOut("Gel StartUp Complete./n");
} OnTargetConnect()
{
 C5509_Init();
} menuitem "C5509_Configuration";
hotmenu CPU_Reset()
{
 GEL_Reset();  GEL_TextOut("CPU Reset Complete./n");
}   hotmenu C5509_Init()
{
 GEL_Reset();
 TMCR_Reset();  GEL_TextOut("C5509 Memory Map Initialization Complete./n");
}   hotmenu C5509_USB_Enable()
{
 GEL_MemoryFill(0x7000,2,1,0x0004);
 GEL_TextOut("C5509 USB Module enabled./n");
} menuitem "C5509 EBSR Config"; hotmenu Data_EMIF_En()
{
 GEL_MemoryFill(0x6C00,2,1,0x0200);
 GEL_TextOut("C5509 Ext. Bus set to Data EMIF./n");
} hotmenu Full_EMIF_En()
{
 GEL_MemoryFill(0x6C00,2,1,0x0201);
 GEL_TextOut("C5509 Ext. Bus set to Full EMIF./n");
} hotmenu NonMuxed_EHPI_En()
{
 GEL_MemoryFill(0x6C00,2,1,0x0202);
 GEL_TextOut("C5509 Ext. Bus set to Non Muxed EHPI./n");
} hotmenu MuxEHPI_En()
{
 GEL_MemoryFill(0x6C00,2,1,0x0203);
 GEL_TextOut("C5509 Ext. Bus set to Muxed EHPI./n");
} menuitem "C5509 EMIF CE0 Config"; hotmenu CE0_Async16_En()
{
 GEL_MemoryFill(0x0803,2,1,0x1FFF);
 GEL_TextOut("C5509 CE0 set to 16-bit Async mode./n");
} menuitem "C5509 EMIF CE1 Config"; hotmenu CE1_Async16_En()
{
 GEL_MemoryFill(0x0806,2,1,0x1FFF);
 GEL_TextOut("C5509 CE1 set to 16-bit Async mode./n");
} menuitem "C5509 EMIF CE2 Config"; hotmenu CE2_Async16_En()
{
 GEL_MemoryFill(0x0809,2,1,0x1FFF);
 GEL_TextOut("C5509 CE2 set to 16-bit Async mode./n");
} menuitem "C5509 EMIF CE3 Config"; hotmenu CE3_Async16_En()
{
 GEL_MemoryFill(0x080C,2,1,0x1FFF);
 GEL_TextOut("C5509 CE3 set to 16-bit Async mode./n");
}
TMCR_Reset()
{
 #define TMCR_MGS3 0x07FE
 #define TMCR_MM  0x07FF  *(short *)TMCR_MGS3@IO = 0x0510;
 *(short *)TMCR_MM@IO    = 0x0000;
}   可以看到:GEL文件主要用来对VC5509的程序空间、数据空间、I/O空间等进行初始化,同时配置CCS开发环境,建立子菜单供用户在调试程序时选择使用。CCS启动时,Startup()函数被执行。支持Connect/Disconnect的CCS启动时,Startup()函数中不包括访问目标处理器的代码,目标处理器由回调函数OnTargetConnect()来初始化。 注意:GEL文件在CCS启动后常驻内存,在仿真器和目标系统上电的时候起到初始DSP的作用。在上电后再改变GEL文件将不会对DSP产生影响。