DSP的CMD文件详解(整理版)(精)

合集下载

DSP_CMD文件中的各个段解释

DSP_CMD文件中的各个段解释

CMD文件里有两个基本的段:初始化段和非初始化段。

初始化段包含代码和常数等必须在DSP上电之后有效的数。

故初始化块必须保存在如片内FLASH等非易失性存储器中,非初始化段中含有在程序运行过程中才像变量内写数据进去,所以非初始化段必须链接到易失性存储器中如RAM。

已初始化的段:.text,.cinit,.const,.econst,.pinit和.switch...text:所有可以执行的代码和常量.cinit:全局变量和静态变量的C初始化记录,包含未用const声明的外部(extern)或静态(static)数据表.const:包含字符串常量和初始化的全局变量和静态变量(由const)的初始化和说明.econst:包含字符串常量和初始化的全局变量和静态变量(由far const)的初始化和说明,与.const不同的是.const分配范围被限制在低64K 16位数据区,而.econst的分配范围是4M 22位数据区.pinit:全局构造器(C++)程序列表.switch:包含switch声明的列表非初始化的段:.bss,.ebss,.stack,.sysmem,和esysmem.(更好的理解就是,这些段就是存储空间而已).bss: 为全局变量和局部变量保留的空间,在程序上电时.cinit空间中的数据复制出来并存储在.bss空间中。

.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.ebss中,与.bss不同的是.bss分配范围被限制在低64K 16位数据区,而.ebss的分配范围是4M 22位数据区.stack:为系统堆栈保留的空间,用于和函数传递变量或为局部变量分配空间。

.sysmem:为动态存储分配保留的空间。

如果有宏函数,此空间被宏函数占用,如果没有的话,此空间保留为0 .esysmem:为动态存储分配保留的空间。

如果有far函数,此空间被相应的占用,如果没有的化,此空间保留为0.编译器生成的包含代码和数据的多个部分,称为段。

DSP的CMD文件详解(整理版)

DSP的CMD文件详解(整理版)

DSP的CMD文件详解CMD是用来分配ROM和RAM空间用的,告诉链接程序怎样计算地址和分配空间。

所以不同的芯片就有不同大小的ROM和RAM,存放用户程序的地方也不尽相同。

所以要根据芯片进行修改,分为 MEMORY 和SECTIONS两个部分。

MEMORY{PAGE 0 ..........PAGE 1.........}SECTIONS{.vectors ..................reset .................................}MEMORY是用来指定芯片的ROM和RAM的大小和划分出几个区间。

PAGE 0对应ROM, PAGE 1对应RAM。

PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。

SECTIONS:(在程序里添加下面的段名,如.vectors。

用来指定该段名以下,另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。

){.vectors : { } > VECS PAGE 0.reset : { } > VECS PAGE 0..................................}eg: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 }{.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}由三部分组成:①输入/输出定义:这一部分,可以通过ccs的“BuildOption........”菜单设置: .obj(链接的目标文件)、.lib(链接的库文件)、.map(生成的交叉索引文件)、.out(生成的可执行代码)。

CMD命令文件详解

CMD命令文件详解

CMD 命令文件解析CMD 文件的专业名称叫做链接器配置文件,用以存放链接器的配置信息,简称命令文件。

其中比较关键的就是MEMORY、SECTIONS两个伪指令的使用。

MEMORY和SECTIONS 的相关语句必须使用大写字符。

MEMORY是用以配置目标存储器的,而SECTIONS是用以指定段的存放位置的。

1 存储空间的配置DSP存储器分为三个独立选择的空间:程序空间、数据空间和I/O空间,其中程序存储器存放待执行的指令和执行中所用的系数(常数),可使用片内或片外的RAM、ROM、EPROM 等构成;数据存储器存放指令执行中产生的数据,可使用片内或片外的RAM和ROM来构成。

I/O存储器存放与映像外围接口相关的数据,也可以作为附加的数据存储空间来使用。

下表是TMS320F28335的存储空间分布:TMS320F28335的存储空间分布:2 BootRomBootRom 是位于存储器地址0x3F E000 ~ 0x3F FFFF处的8K * 16位存储区域。

并利用M0区域的0x0002 ~ 0x004E作为其Boot程序的堆栈和ebss区。

其内存映射如下:3 Cmd 文件的分配方法TI公司新的汇编器和链接器创建的目标文件采用一种COFF(通用目标文件格式),该目标文件格式更利于模块化编程,为管理代码段和目标系统存储器提供了强有力和灵活的编程方法。

用户可以通过编写链接命令文件(cmd文件)将链接信息放在一个文件中,以便在多次使用同样的链接信息时调用。

在命令文件中使用两个十分有用的伪指令MEMORY 和SECTIONS,来指定实际应用中的存储器结构和进行地址的映射。

M EMORY用来指定目标存储器结构,MEMORY下可以通过PAGE选项配置地址空间。

链接器把每一页都当作一个独立的存储空间,通常情况下,PAGE0 代表程序存储器用来存放程序,PAGE1 代表数据存储器,用来存放数据。

由编译器生成的可重定位的代码和数据块叫做“SECTIONS”(段),SECTIONS 用来控制段的构成与地址分配。

DSP的CMD文件写法综述

DSP的CMD文件写法综述
.reset : { } > VECS PAGE 0
..........
}
它分成两个基本的部分:
(1)被初始化的Section(包含数据表和可执行代码)
.text:它包含所有的可执行代码和常数,必须放在程序页
.cinit:它包含初始化的变量和常量表,要求放在程序页
2、Section块用来控制段的构成与地址分配。对于不同的系统配置,Section的分配方式也不相同,链接器通过Section来控制地址的分配,所以Section的分配成了配置.cmd文件的重要环节。
SECTIONS
{
.vectors : { } > VECS PAGE 0
.system:动态存储器分配保留空间,这个空间用于malloc函数,如果不使用malloc函数,这个段的大小就是0。要求放在低地址的数据页。
.esystem:动态存储器分配保留空间,这个空间用于外部malloc函数,如果不使用外部malloc函数,这个段的大小就是0。可也放在数据页的任何地方
.text : { } > PROG PAGE 0 //代码
.cinit : { } > PROG PAGE 0
.bss : { } > SARAM PAGE 1 //块B2
.const : { } > SARAM PAGE 1 //块B2
}
SECTIONS
{
.reset : { } > VECS PAGE 0 //复位中断向量
.vectors : { } > VECS PAGE 0 //中断向量表
.pvecs : { } > PVECS PAGE 0 //外围模块中断向量表

DSP2812的标准CMD文件

DSP2812的标准CMD文件

DSP2812的标准CMD文件MEMORY{PAGE0:/*Program Memory*/ZONE0:origin=0x002000,length=0x002000/*XINTF zone0*/ZONE1:origin=0x004000,length=0x002000/*XINTF zone1*/RAML0:origin=0x008000,length=0x001000/*on-chip RAM block L0*/ZONE2:origin=0x080000,length=0x080000/*XINTF zone2*/ZONE6:origin=0x100000,length=0x080000/*XINTF zone6*/OTP:origin=0x3D7800,length=0x000800/*on-chip OTP*/FLASHJ:origin=0x3D8000,length=0x002000/*on-chip FLASH*/FLASHI:origin=0x3DA000,length=0x002000/*on-chip FLASH*/FLASHH:origin=0x3DC000,length=0x004000/*on-chip FLASH*/FLASHG:origin=0x3E0000,length=0x004000/*on-chip FLASH*/FLASHF:origin=0x3E4000,length=0x004000/*on-chip FLASH*/FLASHE:origin=0x3E8000,length=0x004000/*on-chip FLASH*/FLASHD:origin=0x3EC000,length=0x004000/*on-chip FLASH*/FLASHC:origin=0x3F0000,length=0x004000/*on-chip FLASH*/FLASHA:origin=0x3F6000,length=0x002000/*on-chip FLASH*/BEGIN:origin=0x3F8000,length=0x000002/*Part of ed for"boot to H0"bootloader mode.*/PRAMH0:origin=0x3F8002,length=0x001FFE/*0xFF E/*portion of H0we've mapped to PAGE0*//*ZONE7:origin=0x3FC000,length=0x003FC0/ *XINTF zone7available if MP/MCn=1*/ROM:origin=0x3FF000,length=0x000FC0/*boot ROM available if MP/MCn=0*/RESET:origin=0x3FFFC0,length=0x000002/*part of boot ROM(MP/MCn=0)or XINTF zone7(MP/MCn=1)* /VECTORS:origin=0x3FFFC2,length=0x00003E/ *part of boot ROM(MP/MCn=0)or XINTF zone7(MP/MCn=1)*/PAGE1:/*Data Memory*/RAMM0:origin=0x000000,length=0x000400/*on-chip RAM block M0*/RAMM1:origin=0x000400,length=0x000400/*on-chip RAM block M1*/DEV_EMU:origin=0x000880,length=0x000180/ *device emulation registers*/FLASH_REGS:origin=0x000A80,length=0x000060/*F LASH registers*/CSM:origin=0x000AE0,length=0x000010/*code security module registers*/XINTF:origin=0x000B20,length=0x000020/*external interface registers*/CPU_TIMER0:origin=0x000C00,length=0x000008/*C PU Timer0registers(CPU Timer1and Timer2are reserved for BIOS)*/ PIE_CTRL:origin=0x000CE0,length=0x000020/* PIE control registers*/PIE_VECT:origin=0x000D00,length=0x000100/* PIE vector table*/ECAN_A:origin=0x006000,length=0x000100/*eCAN registers*/ECAN_AMBOX:origin=0x006100,length=0x000100/*e CAN mailboxes*/SYSTEM:origin=0x007010,length=0x000020/*System control registers*/SPI_A:origin=0x007040,length=0x000010/*SPI registers*/SCI_A:origin=0x007050,length=0x000010/*SCI-A registers*/XINTRUPT:origin=0x007070,length=0x000010/* external interrupt registers*/GPIOMUX:origin=0x0070C0,length=0x000020/ *GPIO mux registers*/GPIODAT:origin=0x0070E0,length=0x000020/ *GPIO data registers*/ADC:origin=0x007100,length=0x000020/*ADC registers*/EV_A:origin=0x007400,length=0x000040/*Event Manager A registers*/EV_B:origin=0x007500,length=0x000040/*Event Manager B registers*/SCI_B:origin=0x007750,length=0x000010/*SCI-B registers*/MCBSP_A:origin=0x007800,length=0x000040/ *McBSP registers*/RAML1:origin=0x009000,length=0x001000/*on-chip RAM block L1*/FLASHB:origin=0x3F4000,length=0x002000/*on-chip FLASH*/CSM_PWL:origin=0x3F7FF8,length=0x000008/ *CSM password locations in FLASHA*/DRAMH0:origin=0x3f9000,length=0x001000/*portion of H0we've mapped to PAGE1*/}SECTIONS{/***Compiler Required Sections***/.text:>PRAMH0,PAGE=0.cinit:>PRAMH0,PAGE=0.stack:>RAMM1,PAGE=1.bss:>RAMM0,PAGE=1.ebss:>RAMM0,PAGE=1.const:>RAMM0,PAGE=1.econst:>RAMM0,PAGE=1.sysmem:>RAMM1,PAGE=1.reset:>RESET,PAGE=0,TY PE=DSECT/*we are not using the.reset section*//***User Defined Sections***/codestart:>BEGIN,PAGE=0/*Used by file DSP28_CodeStartBranch. asm*//***Peripheral Frame0Register Structures***/DevEmuRegsFile:>DEV_EMU,PAGE=1FlashRegsFile:>FLASH_REGS,PAGE=1CsmRegsFile:>CSM,PAGE=1XintfRegsFile:>XINTF,PAGE=1CpuTimer0RegsFile:>CPU_TIMER0,PAGE=1PieCtrlRegsFile:>PIE_CTRL,PAGE=1PieVectTable:>PIE_VECT,PAGE=1/***Peripheral Frame1Register Structures***/SysCtrlRegsFile:>SYSTEM,PAGE=1SpiaRegsFile:>SPI_A,PAGE=1SciaRegsFile:>SCI_A,PAGE=1XIntruptRegsFile:>XINTRUPT,PAGE=1GpioMuxRegsFile:>GPIOMUX,PAGE=1GpioDataRegsFile:>GPIODAT PAGE=1AdcRegsFile:>ADC,PAGE=1 EvaRegsFile:>EV_A,PAGE=1 EvbRegsFile:>EV_B,PAGE=1 ScibRegsFile:>SCI_B,PAGE=1McbspaRegsFile:>MCBSP_A,PAGE=1/***Peripheral Frame2Register Structures***/ECanaRegsFile:>ECAN_A,PAGE=1ECanaMboxesFile:>ECAN_AMBOX PAGE=1/***Code Security Password Locations***/CsmPwlFile:>CSM_PWL,PAGE=1}。

DSP关于CMD文件报告

DSP关于CMD文件报告

DSP关于CMD文件报告姓名:班级:通信二班学号:一、简介:本报告基于“《DSP原理及应用》实验指导书”第29页的CMD文件,简要介绍其中涉及的CMD文件的知识、该CMD文件各个语句的含义,并给出了注释。

二、原理:1.链接命令文件以后缀.cmd结尾,简称CMD文件。

CMD文件的作用就像货物摆放记录一样,为程序代码和数据分配存储空间。

CMD文件的两大主要功能是通过MEMORY伪指令来指示存储空间和通过SECTION伪指令来分配段到存储空间。

其中PAGE0表示程序空间,PAGE1表示数据空间。

要读懂CMD文件要结合附录中的图1来看。

2.本程序中通过MEMORY伪指令分配了四个属性为只读的程序空间:PROG,BOOT,RESET,VECTORS;四个属性为既可读又可写的数据空间:M0RAM,M1RAM,L0L1RAM,H0RAM。

3..reset :> RESET, PAGE =0语句中,.reset是段名,“:>”是load,装载载的意思,RESET是空间名称,PAGE=0表示该空间是程序空间。

整句话的意思是将段.reset所对应的的程序装载到名为RESET的程序空间中。

SECTIONS中的语句都可套用这种格式理解。

三、CMD文件注释:-l rts2800_ml.lib-stack 400h-heap 400hMEMORY//MEMORY伪指令来指示存储空间{PAGE 0 : PROG(R) : origin = 0x3E8000, length = 0x10000/*空间名为PROG的只读程序空间,起始地址为0x3E8000,终止地址是0x3F8000,空间长度是0x10000,位于图1的片内flash处*/PAGE 0 : BOOT(R) : origin = 0x3FF000, length = 0xFC0 /*空间名为BOOT的只读程序空间,起始地址为0x3FF000,终止地址是0x3FFFC0,空间长度是0xFC0,位于图1的Boot Rom处*/PAGE 0 : RESET(R) : origin = 0x3FFFC0, length = 0x2 /*空间名为RESET的只读程序空间,起始地址为0x3FFFC0,终止地址是0x3FFFC2,空间长度是0x2,,位于图1的Boot Rom处*/PAGE 0 : VECTORS(R) : origin = 0x3FFFC2, length = 0x3E/*空间名为VECTORS的只读程序空间,起始地址为0x3FFFC2,终止地址是0x400000,空间长度是0x3E,位于图1的Boot Rom处*/PAGE 1 : M0RAM(RW) : origin = 0x000000, length = 0x400/*空间名为M0RAM的既可读又可写数据空间,起始地址为0x000000,终止地址是0x000400,空间长度是0x400,共1K,位于图1的M0 SRAM处*/PAGE 1 : M1RAM(RW) : origin = 0x000400, length = 0x400/*空间名为M1RAM的既可读又可写数据空间,起始地址为0x000400,终止地址是0x000800,空间长度是0x400,共1K,位于图1的M1 SRAM处*/PAGE 1 : L0L1RAM(RW) : origin = 0x008000, length = 0x2000/*空间名为L0L1RAM的既可读又可写数据空间,起始地址为0x008000,终止地址是0x00A000,空间长度是0x2000,共8K,位于图1的L0 SRAM和L1 SRAM处*/PAGE 1 : H0RAM(RW) : origin = 0x3F8000, length = 0x2000/*空间名为H0RAM的既可读又可写数据空间,起始地址为0x3F8000,终止地址是0x3FA000,空间长度是0x2000,共8K,位于图1的H0 SRAM处*/}SECTIONS//SECTIONS伪指令来将段分配到存储空间中去{/* 22-bit program sections */.reset : > RESET, PAGE = 0/*将复位指令存放于程序空间的RESET空间中*/vectors : > VECTORS, PAGE = 0/*将向量存放于程序空间的VECTORS空间中*/.pinit : > PROG, PAGE = 0 /*将生成的全局构造器(C++)程序列表存放于程序空间的PROG空间中*/.cinit : > PROG, PAGE = 0/*将对全局和静态变量初始化的常数存放于程序空间的PROG空间中*/.text : > PROG, PAGE = 0/*编译C语言中的语句时,生成的汇编指令存放于程序空间的PROG空间中*//* 16-Bit data sections */.const : > L0L1RAM, PAGE = 1/*将初始化和说明的字符串常量和静态变量(由const 声明)存放于数据空间的L0L1RAM数据空间中*/.bss : > L0L1RAM, PAGE = 1/*为全局变量和局部变量保留的空间,即在程序上电时,cinit空间中的数据复制出来并储存在L0L1RAM数据空间中*/.stack : > M1RAM, PAGE = 1/*为系统堆栈保留的空间,即当用到函数传递和局部变量时,数据会存放在M1RAM数据空间中*/.sysmem : > M0RAM, PAGE = 1 /*如果有宏函数,则与宏函数有关的动态数据会存放到M0RAM数据空间中*//* 32-bit data sections */.ebss : > H0RAM, PAGE = 1/*为使用大寄存器模式时的全局变量和静态变量预留的空间,即在程序上电时,.cinit空间中的数据会复制出来并存储在H0RAM数据空间中*/.econst : > H0RAM, PAGE = 1/*将初始化和说明的字符串常量和静态变量(由far const 声明)存放于数据空间的H0RAM数据空间中*/.esysmem : > H0RAM, PAGE = 1/*如果有far函数,则与far函数有关的动态数据会存放到H0RAM数据空间中*/}结束语:在初次接触CMD文件的时候,我感到很迷茫。

DSP的CMD文件详解(整理版)(精)

DSP的CMD文件详解(整理版)(精)

D S P的C M D文件详解(整理版)(精)-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIANDSP 的CMD 文件详解(整理版CMD 是用来分配ROM 和RAM 空间用的, 告诉链接程序怎样计算地址和分配空间。

所以不同的芯片就有不同大小的ROM 和RAM ,存放用户程序的地方也不尽相同。

所以要根据芯片进行修改,分为 MEMORY 和SECTIONS 两个部分。

MEMORY{PAGE 0 ..........PAGE 1.........}SECTIONS{.vectors ..................reset .................................}MEMORY 是用来指定芯片的ROM 和RAM 的大小和划分出几个区间。

PAGE 0对应ROM , PAGE 1对应RAM 。

PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。

SECTIONS :(在程序里添加下面的段名,如.vectors 。

用来指定该段名以下,另一个段名以上的程序(属于PAGE0 或数据(属于PAGE1 放到“>”符号后的空间名字所在的地方。

{.vectors : { } > VECS PAGE 0.reset : { } > VECS PAGE 0 ..................................}eg: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 = 00100hB1 :origin = 00300h, length = 00100hB2 :origin = 00060h, length = 00020hSARAM :origin = 08000h, length = 00800h}{.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}由三部分组成:① 输入/输出定义:这一部分,可以通过ccs 的“Build Option........”菜单设置: .obj(链接的目标文件、.lib(链接的库文件、.map(生成的交叉索引文件、.out(生成的可执行代码。

TMS320F2812的CMD文件配置详解

TMS320F2812的CMD文件配置详解

TMS320F2812的CMD文件配置详解1存储空间的配置dsp交流网dsp学习第一论坛dsp技术应用与推广平台dsp开发服务平台\TMS320F2812的DSP内存分为三个独立选择的空间——程序空间、数据空间和I/O空间。

程序存储器存储要执行的指令和执行中使用的系数(常数),可以由片内或片外ram、ROM或EPROM组成;数据存储器存储指令执行期间生成的数据,这些数据可以在芯片内或芯片外使用的ram和rom来构成;i/o存储器存放与映象外围接口相关的数据,也可以作为附加的数据存储空间使用。

表1是tms320f2812的存储空间分布。

#p5r)e7[*e!s2cmd文件的分配方法TI新的汇编程序和链接器创建的目标文件采用coff(通用目标文件格式),这更有利于模块化编程,并为管理代码段和目标系统内存提供了强大而灵活的编程方法。

用户可以编写一个链接命令文件(.CMD文件),将链接信息放在一个文件中,以便在多次使用同一链接信息时调用它。

在命令文件中,使用了两条非常有用的伪指令“内存”和“内存”部分来指定实际应用中的内存结构和地址映射。

内存用于指定目标内存结构。

在内存下,可以通过页面选项配置地址空间。

链接器将每个页面视为独立的存储空间。

通常,Page0表示用于存储程序的程序内存,page1表示用于存储数据的数据内存。

编译器生成的可重定位代码和数据块称为被初始化的“sections”(包括数据表和可执行代码).text它包括所有的可执行代码和常数,必须放在程序页;.cinit它包括初始化的变量和常量表,要求放在程序页;.econst在使用大内存模式时使用,包括字符串、声明和显式初始化的全局和静态变量,这些变量可以放在数据页的任何位置。

DSP交流开关,包括用于转换声明的表格集,可以放在低地址的程序页或数据页上。

h2_u$?;d9e$l:o5k(2)未被初始化的“sections”(为程序运行中创建和存放的变量在存储器中保留空间)9d3a.\\'x7e)m;a'c.BSS,为全局变量和静态变量保留空间。

关TIDSP的CMD文件的解答(精)

关TIDSP的CMD文件的解答(精)

关TI DSP 的CMD文件的解答
问:
疑问一:每个程序是否对应唯一的cmd,如果是那末ovly是否在一个程序中不能改变
疑问二:当ovly为一时,片内RAM有一部分是同时映射到数据和程序空间的,那末是否应该在CMD文件中指定,换句话说,是否相同的物理空间可以同时作为数据和程序空间,还是必须把这部分公用RAM 分开,哪段作为程序空间,哪块作为数据空间
答:
1:每个程序不一定是唯一的CMD,主要依据程序大小、数据空间、分配方式和硬件结构决定。

ovly通常在程序中是不能改变的,这是因为这个位决定了硬件接口是访问外部存储器还是内部存储器,在程序中改变可能会导致系统崩溃;当然也不是绝对的,比如外部接的flash,先从flash中执行引导程序,把要执行的程序拷贝到内部RAM中,再切换到内部去执行,这种方式也是很常用的。

2:在ovly=1时的程序空间和地址空间的分配依据每种器件有所不同,详细地可以看DSP的数据手册, memory map中会有详细的说明。

DSP入门之--CMD文件配置详解

DSP入门之--CMD文件配置详解

DSP入门之--CM D文件配置详解1 C MD文件的分配方法TI公司新的汇编器和链接器创建的目标文件采用一种COFF(通用目标文件格式),该目标文件格式更利于模块化编程,为管理代码段和目标系统存储器提供了强有力和灵活的编程方法。

用户可以通过编写链接命令文件(.cmd文件)将链接信息放在一个文件中,以便在多次使用同样的链接信息时调用。

在命令文件中使用两个十分有用的伪指令ME MORY和SECTIONS,来指定实际应用中的存储器结构和进行地址的映射。

Memo ry用来指定目标存储器结构,Memo ry下可以通过PAGE选项配置地址空间,链接器把每一页都当作一个独立的存储空间。

通常情况下,PA GE0代表程序存储器用来存放程序,PA GE1代表数据存储器,用来存放数据。

由编译器生成的可重定位的代码和数据块叫做“SECTIONS”(段),SECTIONS用来控制段的构成与地址分配。

对于不同的系统配置,“SECTION”的分配方式也不相同,链接器通过“SECTIONS”来控制地址的分配,所以“SECTIONS”的分配就成了配置.cmd文件的重要环节。

以下是对“SE CTIONS”的定义及分配的详细介绍。

(1)被初始化的“SECTI ONS”(包括数据表和可执行代码).te xt它包括所有的可执行代码和常数,必须放在程序页;.cinit 它包括初始化的变量和常量表,要求放在程序页;.pinit它包括全局构造器(C++)初始化的变量和常量表,要求放在程序页;.const它包括字符串、声明、以及被明确初始化过的全局和静态变量,要求放在低地址的数据页;.econst它是在使用大存储器模式时使用的,包括字符串、声明、以及被明确初始化过的全局变量和静态变量,可以放在数据页的任何地方。

.switch它包括为转换声明设置的表格,可以放在程序页也可以放在低地址的数据页。

(2)未被初始化的“SECTIONS”(为程序运行中创建和存放的变量在存储器中保留空间).bss它为全局变量和静态变量保留空间。

DSP的CMD文件详解

DSP的CMD文件详解

DSP的CMD文件详解路帅,郭勇(中国航空工业集团公司西安航空计算技术研究所,陕西西安710065)摘要:随着微电子技术的不断发展,DSP芯片的性能价格比不断提高,可以预见DSP芯片将渗透到各个领域,得到更加广泛的应用。

在DSP应用开发中,开发人员容易对CMD文件理解不到位,CMD文件包含系统的存储器资源声明和资源分配情况声明两部分,文章对其写法和需要注意的地方进行了详细说明。

关键词:链接配置文件;存储器资源;用户声明资源中图分类号:TP311文献标识码:A文章编号:1673-1131(2019)01-0105-020引言数字信号处理器(Digital Signal Processor,DSP)以高速数字信号处理为目标进行芯片设计,采用改进的哈佛结构,内部具有硬件乘法器,应用流水线技术,具有良好的并行性和专门用于数字信号处理的指令等特点[1]。

DSP芯片以其强大的运算能力在通信、电子、图像处理等各个领域得到了广泛的应用[2]。

随着DSP系统的越来越复杂,在开发中我们往往要对CMD文件进行一些相应的改变,错误的配置会使最终应用开发出现意想不到的问题,本文就对CMD文件内容进行了介绍,并介绍了相应语法和一些需要注意的地方,值得开发人员借鉴。

1CMD文件整体介绍CMD文件是链接器配置文件(Linker Command File),后缀名是.cmd。

CMD主要作用是存放链接器的配置信息。

编写CMD文件就是开发物理存储器的管理、分配和使用情况。

CMD文件主要包含两方面的内容:(1)系统的存储器资源声明。

依次声明DSP芯片自带存储器、外扩的存储器空间。

(2)存储器资源分配情况声明。

以下以2812为例详细详解CMD文件,目的使大家可以读懂CMD,修改CMD并按照自己的想法进行设计。

2用户声明系统的存储器资源TI的DSP系列的CMD文件使用“MEMORY”关键词标识系统的存储器资源清单,紧随其后的大括号包含了具体的声明内容。

DSP28335—CMD文件资料解读汇报(映射关系)

DSP28335—CMD文件资料解读汇报(映射关系)

DSP28335—CMD解读(1)在DSP28335工程文件里(不用BIOS产生CMD文件),手写CMD文件一般有两个,在RAM里调试时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和28335_RAM_lnk.cmd,烧写到flash里时用的两个CMD 文件分别为DSP2833x_Headers_nonBIOS.cmd和F28335.cmd,其中DSP2833x_Headers_nonBIOS.cmd文件可以在所有工程文件用,主要作用是把外设寄存器产生的数据段映射到对应的存储空间,可以跟DSP2833x_GlobalVariableDefs.c文件对照一下看看。

下面通过一个简单例子,比如向CpuTimer0Regs. TIM.all写数据,来解读一下CMD文件是如何把寄存器里的值准确映射到所在存储器的位置的。

先在DSP2833x_GlobalVariableDefs.c文件里找到以下几行代码:#ifdef __cplusplus#pragma DATA_SECTION("CpuTimer0RegsFile")#else#pragma DATA_SECTION(CpuTimer0Regs,"CpuTimer0RegsFile");#endifvolatile struct CPUTIMER_REGS CpuTimer0Regs;由上可知CpuTimer0Regs是一个结构体变量名(其定义在DSP2833x_CpuTimers.c文件里),通过预处理命令#pragma 为这个结构体定义了一个名称为CpuTimer0RegsFile的数据段。

接着在DSP2833x_Headers_nonBIOS.cmd文件里找到如下代码:SECTIONS{PieVectTableFile : > PIE_VECT, PAGE = 1DevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1AdcMirrorFile : > ADC_MIRROR, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1......}红字体代码的作用就是,通过SECTIONS伪指令把CpuTimer0RegsFile数据段装载到名称为CPU_TIMER0的存储空间。

TMS320f2812地址映射以及CMD文件详解

TMS320f2812地址映射以及CMD文件详解

S
CIRXEMU; // Recieve emulation buffer register
union SCIRXBUF_REG SCIRXBUF; // Recieve data buffer
Uint16
rsvd1; // reserved
Uint16
SCITXBUF; // Transmit data buffer
extern volatile struct SCI_REGS SciaRegs;
extern volatile struct SCI_REGS ScibRegs; 大家可以看到,这里定义了两个结构体,一个是 SciaRegs ,一个是 ScibRegs,因为 DSP 内部有两个串行通信, A 和 B,这两个都是结构体,而类型就是前面的 SCI_REGS 的,这个结构体类型是这样定义的:
EVA : origin = 0x007400, length = 0x000040
EVB : origin = 0x007500, length = 0x000040
SCIB : origin = 0x007750, length = 0x000010
MCBSPA : origin = 0x007800, length = 0x000040
#pragma CODE_SECTION(funcA,“codeA ”); char funcA(int i); //对函数 funcA 的声明 上面中,funcA 函数一定是外部声明或者定义的函数,CODE_SECTION 为 funcA 在一个名为 codeA 的块中指 定空间。如果你有一个代码对象并想将其链接到不同于.txt 的空间时,该语法就非常有用。而 codeA 在.cmd 文件中指定了物理地址。 #pragma DATA_SECTION(bufferB,“my_sect”); char bufferB [512]; // 对 bufferB 的定义放在 pragma 的后面 DATA_SECTION 为 bufferB 在一个名为 my_sect 的块中指定空间。如果你有一个数据对象并想将其链接到不同 于.bss 的空间时,该语法就非常有用. 数据块 bufferB 被定位于 my_sect 段中,my_sect 段在 .cmd 文件中规定 了物理地址。 看完上面的一段解释,估计您会对#pragma 有了很好的了解了吧 。我们使用的结构体是数据而不是函 数,所以我们使用 DATA_SECTION。其实就是把 SciaRegs 和 ScibRegs 分别在块 SciaRegsFile 和 ScibRegsFile 中 指定空间,而块 SciaRegsFile 和 ScibRegsFile 在.cmd 文件中指定了物理地址。这样一来,是不是结构体 SciaRegs 和 ScibRegs 的起始地址就知道了?答案是肯定的。我们在看分析.cmd 文件。.cmd 文件的源代码如下:

dsp的cmd文件详解

dsp的cmd文件详解

CMD文件的原理一、前言开发TI 公司的DSP 芯片,肯定要编写或者修改CMD 文件,这是在单片机开发中没有碰到过的新事物,也是学习DSP的难点。

面对里面种类繁多、名称各异、来历不明、作用不清、功能千差万别的存储器、区域和变量、寄存器,初学者往往都会一头雾水。

甚至很多人已经把项目成功地完成了,对CMD文件仍然是一知半解。

笔者也经历了极度困惑的过程,曾经大量地看书,下载资料,分析所能搜集到的CMD源文件。

可惜的是,无论是TI 公司的原始文档,还是网上的资料,或者BBS的帖子,都没有透彻地说明CMD 文件的原理和使用,只说―然‖ ,要靠自己去体会―所以然‖ ,去―悟‖ 。

终于有一天,我悟到了,也许只是―一些‖ 。

现在,我把自己的―一些‖写下来。

我将细致而通俗地说明CMD 文件的原理,给您―鱼‖ ,更给您―渔‖ ,一步步地引导象我当初一样的初学者。

我将以TI 的2407 为对象展开说明,对于TI 公司其他型号、其他系列的DSP,道理是完全相同的。

用时下学术界最最最流行的语式,叫做―基于2407‖——这个词起源于英文的―based on‖ ,或―something based‖ ,被我们大量地引用,以至于令人反胃了——我们美妙、绚烂的语言,现在只剩下―基于‖了。

笔者水平有限,但保证会用心去写,您会看到很多别处没有的思路和信息,相信会基本打通初学者的任督二脉。

本文适用于那些有单片机的开发基础、刚开始学习DSP 的初学者。

如果你还不知道程序空间,数据空间这些名词,可能就比较困难了。

二、CMD文件的起源在DSP系统中,存在大量的、各式各样的存储器,CMD文件所描述的,就是开发工程师对物理存储器的管理、分配和使用情况。

有必要先复习一下存储器的知识。

目前的物理存储器,种类繁多,原理、功能、参数、速度各不相同,有PROM、EPROM、EEPROM、FLASH、NAND FLASH、NOR FLASH等(ROM 类),还有SRAM、DRAM、SDRAM、DDR、DDR2、FIFO 等(RAM 类)。

DSP28335—CMD文件解读(映射关系)

DSP28335—CMD文件解读(映射关系)

DSP28335—CMD解读(1)在DSP28335工程文件里(不用BIOS产生CMD文件),手写CMD文件一般有两个,在RAM里调试时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和28335_RAM_lnk.cmd,烧写到flash里时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和F28335.cmd,其中DSP2833x_Headers_nonBIOS.cmd文件可以在所有工程文件中通用,主要作用是把外设寄存器产生的数据段映射到对应的存储空间,可以跟DSP2833x_GlobalVariableDefs.c文件对照一下看看。

下面通过一个简单例子,比如向CpuTimer0Regs. TIM.all写数据,来解读一下CMD文件是如何把寄存器里的值准确映射到所在存储器的位置的。

先在DSP2833x_GlobalVariableDefs.c文件里找到以下几行代码:#ifdef __cplusplus#pragma DATA_SECTION("CpuTimer0RegsFile")#else#pragma DATA_SECTION(CpuTimer0Regs,"CpuTimer0RegsFile");#endifvolatile struct CPUTIMER_REGS CpuTimer0Regs;由上可知CpuTimer0Regs是一个结构体变量名(其定义在DSP2833x_CpuTimers.c文件里),通过预处理命令#pragma 为这个结构体定义了一个名称为CpuTimer0RegsFile的数据段。

接着在DSP2833x_Headers_nonBIOS.cmd文件里找到如下代码:SECTIONS{PieVectTableFile : > PIE_VECT, PAGE = 1DevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1AdcMirrorFile : > ADC_MIRROR, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1......}红字体代码的作用就是,通过SECTIONS伪指令把CpuTimer0RegsFile数据段装载到名称为CPU_TIMER0的存储空间。

DSP2812_CMD文件详解

DSP2812_CMD文件详解

MEMORY //存储器实际物理地址映射{PAGE 0 : //程序存储器空间OTP : origin = 0x3D7800, length = 0x000800 //2k//0x3D7800-0x3D7FFF PRAMH0 : origin = 0x3f8000, length = 0x001000 //4k//0x3F8000-0x3F8FFF FLASHJ : origin = 0x3D8000, length = 0x002000 //8k//0x3D8000-0x3D9FFF FLASHI : origin = 0x3DA000, length = 0x002000 //8k//0x3DA000-0x3DBFFF FLASHH : origin = 0x3DC000, length = 0x004000 //16k//0x3DC000-0x3DFFFF FLASHG : origin = 0x3E0000, length = 0x004000 //16k//0x3E0000-0x3E3FFF FLASHF : origin = 0x3E4000, length = 0x004000 //16k//0x3E4000-0x3E7FFF FLASHE : origin = 0x3E8000, length = 0x004000 //16k//0x3E8000-0x3EBFFF FLASHD : origin = 0x3EC000, length = 0x004000 //16k//0x3EC000-0x3EFFFF /* FLASHC : origin = 0x3F0000, length = 0x004000*/ //16k//0x3F0000-0x3F3FFF FLASHB : origin = 0x3F4000, length = 0x002000 //8k//0x3F4000-0x3F5FFF FLASHA : origin = 0x3F6000, length = 0x001FF6 //8182//0x3F6000-0x3F7FF5 BEGIN : origin = 0x3F7FF6, length = 0x000002 //2//0x3F7FF6-0x3F7FF7 PASSWDS : origin = 0x3F7FF8, length = 0x000008 //8//0x3F7FF8-0x3F7FFF ROM : origin = 0x3FF000, length = 0x000FC0 //4032//0x3FF000-0x3FFFBF RESET : origin = 0x3FFFC0, length = 0x000002 //2//0x3FFFC0-0x3FFFC1 VECTORS : origin = 0x3FFFC2, length = 0x00003E //62//0x3FFFC2-0x3FFFFF /* SARAM */RAML0 : origin = 0x008000, length = 0x001000 //4k//0x008000-0x008FFFRAML1 : origin = 0x009000, length = 0x001000 //4k//0x009000-0x009FFFPAGE 1 : //数据存储器空间/* SARAM */RAMM0 : origin = 0x000000, length = 0x000400 //1k//0x000000-0x0003FF RAMM1 : origin = 0x000400, length = 0x000400 //1k//0x000400-0x0007FF/* Peripheral Frame 0: */DEV_EMU : origin = 0x000880, length = 0x000180 //384//0x000880-0x0009FF FLASH_REGS : origin = 0x000A80, length = 0x000060 //96//0x000A80-0x000ADF CSM : origin = 0x000AE0, length = 0x000010 //16//0x000AE0-0x000AEF XINTF : origin = 0x000B20, length = 0x000020 //32//0x000B20-0x000B3F CPU_TIMER0 : origin = 0x000C00, length = 0x000008 //8//0x000C00-0x000C07CPU_TIMER1 : origin = 0x000C08, length = 0x000008 //8//0x000C08-0x000C0F CPU_TIMER2 : origin = 0x000C10, length = 0x000008 //8//0x000C10-0x000C17PIE_CTRL : origin = 0x000CE0, length = 0x000020 //32//0x000CE0-0x000CFF PIE_VECT : origin = 0x000D00, length = 0x000100 //256//0x000D00-0x000DFF/* Peripheral Frame 1: */ECAN_A : origin = 0x006000, length = 0x000100 //256//0x006000-0x0060FFECAN_AMBOX : origin = 0x006100, length = 0x000100 //256//0x006100-0x0061FF/* Peripheral Frame 2: */SYSTEM : origin = 0x007010, length = 0x000020 //32//0x007010-0x00702F SPI_A : origin = 0x007040, length = 0x000010 //16//0x007040-0x00704F SCI_A : origin = 0x007050, length = 0x000010 //16//0x007050-0x00705F XINTRUPT : origin = 0x007070, length = 0x000010 //16//0x007070-0x00707F GPIOMUX : origin = 0x0070C0, length = 0x000020 //32//0x0070C0-0x0070DF GPIODAT : origin = 0x0070E0, length = 0x000020 //32//0x0070E0-0x0070FF ADC : origin = 0x007100, length = 0x000020 //32//0x007100-0x00711F EV_A : origin = 0x007400, length = 0x000040 //64//0x007400-0x00743F EV_B : origin = 0x007500, length = 0x000040 //64//0x007500-0x00753F SPI_B : origin = 0x007740, length = 0x000010 //16//0x007740-0x00774F SCI_B : origin = 0x007750, length = 0x000010 //16//0x007750-0x00775F MCBSP_A : origin = 0x007800, length = 0x000040 //64//0x007800-0x00783F/* CSM Password Locations */CSM_PWL : origin = 0x3F7FF8, length = 0x000008 //8//0x3F7FF8-0x3F7FFF/* SARAM */DRAMH0 : origin = 0x3f9000, length = 0x000e00 //3584//0x3F9000-0x3F9DFF /* FLASH ON-CHIP */FLASHC : origin = 0x3F0000, length = 0x004000 //16k//0x3F0000-0x3F3FFF /* OUT_RAM */MYRAM : origin = 0x100000, length = 0x010000 //64k//0x100000-0x10FFFF }SECTIONS{/* Allocate program areas: */.reset : > RESET, PAGE = 0 ,TYPE=DSECTcodestart : > BEGIN PAGE = 0vectors : > VECTORS PAGE = 0.cinit : > FLASHJ PAGE = 0.text : > FLASHJ PAGE = 0/* Allocate data areas:.stack : > RAMM0M1 PAGE = 1.bss : > RAML0L1 PAGE = 0.ebss : > RAML0L1 PAGE = 0.const : > RAML0L1 PAGE = 0.econst : > FLASHC PAGE = 1.sysmem : > RAML0L1 PAGE = 0*/.stack : > RAMM1 PAGE = 1.bss : > DRAMH0 PAGE = 1.ebss : > DRAMH0 PAGE = 1.const : > FLASHC PAGE = 1.econst : > FLASHC PAGE = 1.sysmem : > DRAMH0 PAGE = 1/******************************************************/fir16 : LOAD = FLASHA, PAGE = 0RUN = RAML1, PAGE = 0RUN_START(_FIR16_runstart),LOAD_START(_FIR16_loadstart),LOAD_END(_FIR16_loadend)secureRamFuncs : LOAD=FLASHJ, PAGE = 0RUN=RAML1, PAGE = 0RUN_START(_secureRamFuncs_runstart),LOAD_START(_secureRamFuncs_loadstart),LOAD_END(_secureRamFuncs_loadend)ramfuncs : LOAD = FLASHJ, PAGE = 0RUN = RAML1, PAGE = 0LOAD_START(_RamfuncsLoadStart),LOAD_END(_RamfuncsLoadEnd),RUN_START(_RamfuncsRunStart)ramconsts :> FLASHB, PAGE = 0xishu :> RAML0, PAGE = 0 ramconsts2 :> FLASHB, PAGE = 0xishu2 :> RAML0, PAGE = 0firldb : LOAD = 0x009200, PAGE = 0firfilt :>RAML0, PAGE = 0fir2ldb : LOAD = 0x009000, PAGE = 0fir2filt :>RAML0, PAGE = 0/*out-ram array*/PreFlt2 :>MYRAM, PAGE = 1PreFlt1 :>MYRAM, PAGE = 1PreFlt3 :>MYRAM, PAGE = 1AftFlt2 :>MYRAM, PAGE = 1AftFlt1 :>MYRAM, PAGE = 1 myarray5 :>MYRAM, PAGE = 1AftKal :>MYRAM, PAGE = 1/* myarray7 :>MYRAM, PAGE = 1*/dif :>MYRAM, PAGE = 1kalman :>MYRAM, PAGE = 1/* Allocate IQ math areas: */IQmath : > FLASHI PAGE = 0 /* Math Code */IQmathFastTables : > FLASHI PAGE = 0 /* Math Tables in fast memory */IQmathTables : > ROM PAGE = 0 /* Math Tables In ROM *//* Allocate Peripheral Frame 0 Register Structures: */DevEmuRegsFile : > DEV_EMU PAGE = 1FlashRegsFile : > FLASH_REGS PAGE = 1CsmRegsFile : > CSM PAGE = 1XintfRegsFile : > XINTF PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0 PAGE = 1CpuTimer1RegsFile : > CPU_TIMER1 PAGE = 1CpuTimer2RegsFile : > CPU_TIMER2 PAGE = 1PieCtrlRegsFile : > PIE_CTRL PAGE = 1PieV ectTable : > PIE_VECT PAGE = 1/* Allocate Peripheral Frame 2 Register Structures: */ECanaRegsFile : > ECAN_A PAGE = 1ECanaMboxesFile : > ECAN_AMBOX PAGE = 1/* Allocate Peripheral Frame 1 Register Structures: */SysCtrlRegsFile : > SYSTEM PAGE = 1SpiaRegsFile : > SPI_A PAGE = 1SciaRegsFile : > SCI_A PAGE = 1XIntruptRegsFile : > XINTRUPT PAGE = 1GpioMuxRegsFile : > GPIOMUX PAGE = 1GpioDataRegsFile : > GPIODAT PAGE = 1AdcRegsFile : > ADC PAGE = 1EvaRegsFile : > EV_A PAGE = 1EvbRegsFile : > EV_B PAGE = 1ScibRegsFile : > SCI_B PAGE = 1McbspaRegsFile : > MCBSP_A PAGE = 1/* CSM Password Locations */CsmPwlFile : > CSM_PWL PAGE = 1/**/}。

TI DSP中的CMD文件

TI DSP中的CMD文件

MEMORY
{
PAGE 0: /* PROGRAM MEMORY */
PM: ORIGIN=0h, LENGTH=08000h /* 32k on-chip flash memory */
SARAM_P:ORIGIN=08000h, LENGTH=0800h /* 2k saram in program space */
.bss: {所有.bss输入段名} load=加载地址 run =运行地址
.other: {所有.other输入段名} load=加载地址 run =运行地址
}
SECTIONS必须用大写字母,其后的大括号里是输出段的说明性语句,每一个输出段的说明都是从段名开始,段名之后是如何对输入段进行组织和给段分配存储器的参数说明。以.text段的属性语句为例,“{所有.text输入段名}”这段内容用来说明连接器输出段的.text段由哪些子目标文件的段组成。接下来的load和run,链接器为每个输出段都在目标存储器里分配两个地址:一个是加载地址,一个是运行地址。通常情况下两个地址是相同的,可以认为输出段只有一个地址,这时就可以不加“run =运行地址”这条语句了;但有时需要将两个地址分开,比如将程序加载到FLASH,然后放到RAM中高速运行,这就用到了运行地址和加载地址的分别配置了。
TI DSP中的CMD文件
来源: 刘礼亚的日志
CMD的专业名称叫链接器配置文件,是存放链接器的配置信息的,我们简称为命令文件。从其名称可以看出,该文件的作用是指明如何链接程序的。
那么我们知道,在编写TI DSP程序时,是可以将程序分为很多段,比如text、bss等,各段的作用均不相同。实际在片中运行时,所处的位置也不相同。比如text代码一般应该放在flash内,而bss的变量应该放在ram内。等等。但是对于不同的芯片,其各存储器的起止地址都是不一样的,而且,用户希望将某一段,尤其是自定义段,放在什么存储器的什么位置,这也是链接器不知道的。为了告诉链接器,即将使用的芯片其内部存储空间的分配和程序各段的具体存放位置,这就需要编写一个配置文件,即CMD文件了。

DSP28335—CMD文件解读(映射关系)

DSP28335—CMD文件解读(映射关系)

DSP28335—CMD解读(1)在DSP28335工程文件里(不用BIOS产生CMD文件),手写CMD文件一般有两个,在RAM里调试时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和28335_RAM_lnk.cmd,烧写到flash里时用的两个CMD文件分别为DSP2833x_Headers_nonBIOS.cmd和F28335.cmd,其中DSP2833x_Headers_nonBIOS.cmd文件可以在所有工程文件中通用,主要作用是把外设寄存器产生的数据段映射到对应的存储空间,可以跟DSP2833x_GlobalVariableDefs.c文件对照一下看看。

下面通过一个简单例子,比如向CpuTimer0Regs. TIM.all写数据,来解读一下CMD文件是如何把寄存器里的值准确映射到所在存储器的位置的。

先在DSP2833x_GlobalVariableDefs.c文件里找到以下几行代码:#ifdef __cplusplus#pragma DATA_SECTION("CpuTimer0RegsFile")#else#pragma DATA_SECTION(CpuTimer0Regs,"CpuTimer0RegsFile");#endifvolatile struct CPUTIMER_REGS CpuTimer0Regs;由上可知CpuTimer0Regs是一个结构体变量名(其定义在DSP2833x_CpuTimers.c文件里),通过预处理命令#pragma 为这个结构体定义了一个名称为CpuTimer0RegsFile的数据段。

接着在DSP2833x_Headers_nonBIOS.cmd文件里找到如下代码:SECTIONS{PieVectTableFile : > PIE_VECT, PAGE = 1DevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1AdcMirrorFile : > ADC_MIRROR, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1......}红字体代码的作用就是,通过SECTIONS伪指令把CpuTimer0RegsFile数据段装载到名称为CPU_TIMER0的存储空间。

DSP的CMD文件讲解(精)

DSP的CMD文件讲解(精)

DSP的CMD文件讲解:CMD主要是用来分配rom和ram空间用的,它告诉链接程序怎样计算地址和分配空间.所以不同的芯片就有不同大小的rom和ram.放用户程序的地方也不尽相同.所以要根据芯片进行修改.分两部分.MEMORY和SECTIONS.MEMORY{ PAGE 0 ..........PAGE 1.........}SECTIONS{.vectors ..................reset .................................}MEMORY是用来指定芯片的rom和ram的大小和划分出几个区间.PAGE 0 对应rom,PAGE 1对应ram。

PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度.SECTIONS:在程序里添加段名.XXXX(如.vectors.用来指定该段名以下,另一个段名以上的程序(属于PAGE0或数据(属于PAGE1放到“>”符号后的空间名字所在的地方。

下面给出一个简单的例子:MEMORY{PAGE 0: VECS: origin = 00000h, length = 00040h LOW: origin = 00040h, length = 03FC0h SARAM: origin = 04000h, length = 00800hB0: origin = 0FF00h, length = 00100hPAGE 1: B0: origin = 00200h, length = 00100hB1: origin = 00300h, length = 00100hB2: origin = 00060h, length = 00020h SARAM: origin = 08000h, length = 00800h}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}CMD文件由三部分组成:(1 输入输出定义;(2 MEMORY命令;(3 SECTION 命令。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DSP 的CMD 文件详解(整理版CMD 是用来分配ROM 和RAM 空间用的, 告诉链接程序怎样计算地址和分配空间。

所以不同的芯片就有不同大小的ROM 和RAM ,存放用户程序的地方也不尽相同。

所以要根据芯片进行修改,分为 MEMORY 和SECTIONS 两个部分。

MEMORY{PAGE 0 ..........PAGE 1.........}SECTIONS{.vectors ..................reset .................................}MEMORY 是用来指定芯片的ROM 和RAM 的大小和划分出几个区间。

PAGE 0对应ROM , PAGE 1对应RAM 。

PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。

SECTIONS :(在程序里添加下面的段名,如.vectors 。

用来指定该段名以下,另一个段名以上的程序(属于PAGE0 或数据(属于PAGE1 放到“>”符号后的空间名字所在的地方。

{.vectors : { } > VECS PAGE 0.reset : { } > VECS PAGE 0 ..................................}eg: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 = 00100hB1 :origin = 00300h, length = 00100hB2 :origin = 00060h, length = 00020hSARAM :origin = 08000h, length = 00800h}{.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}由三部分组成:①输入/输出定义:这一部分,可以通过ccs 的“Build Option........”菜单设置: .obj(链接的目标文件、.lib(链接的库文件、.map(生成的交叉索引文件、.out(生成的可执行代码。

② MEMORY 命令:描述系统实际的硬件资源③ SECTION 命令:描述“段”如何定位例子:.cmd 文件-c-o hello.out-m hello.map-stack 100-l rts2xx.libMEMORY{PAGE 0: VECT:origin=0x8000,length 0x040 PAGE 0: PROG:origin=0x8040,length 0x6000 PAGE 1: DATA:origin=0x8000,length 0x400 }SECTIONS{.vextors >VECT PAGE 0.text >PROG PAGE 0.bss >DATA PAGE 1.const >DATA PAGE 1}存储模型:c 程序的代码和数据如何定位系统定义:.cinit 存放程序中的变量初值和常量.const 存放程序中的字符常量、浮点常量和用const 声明的常量 .switch 存放程序中switch 语句的跳转地址表.text 存放程序代码.bss 为程序中的全局和静态变量保留存储空间.far 为程序中用far 声明的全局和静态变量保留空间.stack 为程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递、存储局部变量和保存中间结果.sysmem 用于程序中的malloc 、calloc 、和realoc 函数动态分配存储空间CMD 的专业名称叫链接器配置文件,是存放链接器的配置信息的,我们简称为命令文件,其中比较关键的就是MEMORY 和SECTIONS 两个伪指令的使用,常常令人困惑,系统出现的问题也经常与它们的不当使用有关。

CCS 是DSP 软件对DOS 系统继承的开发环境,CCS 的命令文件经过DOS 命令文件长时间的引申发展,已经变得非常简洁(不知道TI 文档有没有详细CMD 配置说明)。

我学CMD 是从DOS 里的东西开始的,所以也从DOS 环境下的CMD 说起:1、命令文件的组成命令文件的开头部分是要链接的各个子目标文件的名字,这样链接器就可以根据子目标文件名,将相应的目标文件链接成一个文件;接下来就是链接器的操作指令,这些指令用来配置链接器,接下来就是MEMORY 和SECTIONS 两个伪指令的相关语句,必须大写。

MEMORY ,用来配置目标存储器,SECTIONS 用来指定段的存放位置。

结合下面的典型DOS 环境的命令文件link.cmd 来做一下说明:file.obj //子目标文件名1file2.obj //子目标文件名2file3.obj //子目标文件名3- o prog.out //连接器操作指令, 用来指定输出文件- m prog.m //用来指定MAP 文件MEMORY{ 略 }SECTIONS{ 略 }otherlink.cmd本命令文件link.cmd 要调用的otherlink.cmd 等其他命令文件,则文件的名字要放到本命令文件最后一行,因为放开头的话, 链接器是不会从被调用的其他命令文件中返回到本命令文件。

2 、MEMORY 伪指令MEMORY 用来建立目标存储器的模型,SECTIONS 指令就可以根据这个模型来安排各个段的位置,MEMORY 指令可以定义目标系统的各种类型的存储器及容量。

MEMORY 的语法如下:MEMORY{PAGE 0 :name1[(attr] : origin = constant,length = constantname1n[(attr] : origin = constant,length = constant PAGE 1 : name2[(attr] : origin = constant,length = constantname2n[(attr] : origin = constant,length = constant PAGE n : namen[(attr] : origin = constant,length = constantnamenn[(attr] : origin = constant,length = constant }PAGE 关键词对独立的存储空间进行标记,页号n 的最大值为255,实际应用中一般分为两页,PAGE0程序存储器和PAGE1数据存储器。

name 存储区间的名字,不超过8个字符,不同的PAGE 上可以出现相同的名字(最好不用,免的搞混),一个PAGE 内不许有相同的name 。

attr 的属性标识,为R 表示可读;W 可写X 表示区间可以装入可执行代码;I 表示存储器可以进行初始话,什么属性代码也不写,表示存储区间具有上述的四种属性,基本上我们都选择这种写法。

origin:略。

length:略。

下面是经常用的2407的简单写法大家参考, 程序从0x060开始,要避开加密位,不从0x0044开始更可靠一点,此例中的同名的页可以只写第一个,其后省略,但写上至少安全一点:MEMORY{PAGE 0: VECS: origin = 0x0000, length 0x40PAGE 0: PROG: origin = 0x0060, length 0x6000PAGE 1: B0 : origin = 0x200, length 0x100PAGE 1: B1 : origin = 0x300, length 0x100PAGE 1: DATA: origin = 0x0860, length 0x0780}3、 SECTIONS 伪指令SECTIONS 指令的语法如下:SECTIONS{.text: {所有.text 输入段名} load=加载地址 run =运行地址 .data: {所有.data 输入段名} load=加载地址 run =运行地址 .bss: {所有.bss 输入段名} load=加载地址 run =运行地址.other: {所有.other 输入段名} load=加载地址 run =运行地址 }SECTIONS 必须用大写字母,其后的大括号里是输出段的说明性语句,每一个输出段的说明都是从段名开始,段名之后是如何对输入段进行组织和给段分配存储器的参数说明:以.text 段的属性语句为例,“{所有.text 输入段名}”这段内容用来说明连接器输出段的.text 段由哪些子目标文件的段组成,举例如下 SECTIONS{.text:{ file1.obj(.text file2(.text file3(.text,cinit}略}指明输出段.text 要链接file1.obj 的.text 和 file2的.text 还有file3的.text 和.cinit 。

在CCS 的SECTIONS 里通常只写一个中间没有内容的“{ }”就表示所有的目标文件的相应段。

接下来说明“load=加载地址 run =运行地址”链接器为每个输出段都在目标存储器里分配两个地址:一个是加载地址,一个是运行地址。

通常情况下两个地址是相同的,可以认为输出段只有一个地址,这时就可以不加“run =运行地址”这条语句了;但有时需要将两个地址分开,比如将程序加载到FLASH ,然后放到RAM 中高速运行,这就用到了运行地址和加载地址的分别配置了,如下例所示:.const :{略} load = PROG run = 0x0800,常量加载在程序存储区,配置为在RAM 里调用。

“load=加载地址”的几种写法需要说明一下,首先“load”关键字可以省略,“=”可以写成“>”, “加载地址”可以是:地址值、存储区间的名字、PAGE 关键词等,所以大家见到“.text:{ } > 0x0080”这样的语句可千万不要奇怪。

相关文档
最新文档