DSP6455中cmd文件
CMD 的专业名称叫链接器配置文件,存放链接器的配置信息,DSP编译器的编译结果是未定位的,DSP也没有操作系统来定位执行代码,DSP系统的配置需求也不尽相同,因此需要定义代码存储位置。CMD分配ROM和RAM空间,告诉链接程序怎样计算地址和分配空间。所以不同的芯片就有不同大小的ROM和RAM,存放用户程序的地方也不尽相同。所以要根据芯片进行修改。
DSP 芯片的片内存储器, 只要没有被 TI 占用, 用户都可以全权支配。 TI 设计了 "CMD文件"这种与用户的接口形式,用户通过编写 CMD 文件,来管理、分配系统中的所有物理存储器和地址空间。CMD 文件其实就是用户的"声明" ,包括两方面的内容:
1、用户声明的整个系统里的存储器资源。无论是 DSP 芯片自带的,还是用户外扩的,凡是可以使用的、需要用到的存储器和空间,用户都要一一声明出来:有哪些存储器,它们的位置和大小。如果有些资源根本用不到,可以视为不存在,不必列出来;列出来也无所谓。
2、用户如何分配这些存储器资源,即关于资源分配情况的声明。用户根据自己的需要,结合芯片的要求,把各种数据分配到适当种类、适当特点、适当长度的存储器区域,这是编写 CMD 文件的重点。
工程目录下的文件夹中.map文件里有section allocation map可以查看产生的"段"。查看 .map 文件中"output section"那一列,那些长度(length)非 0 的段,就是你的项目真正会产生的段;那些长度为 0 的段,基本都可以从 CMD 文件中删除。
Note:注释可以用/*……*/但是不能用//
命令文件的组成
命令文件的开头部分是要链接的各个子目标文件的名字,这样链接器就可以根据子目标文件名,将相应的目标文件链接成一个文件;接下来就是链接器的操作指令,这些指令用来配置链接器,接下来就是MEMORY和SECTIONS两个伪指令的相关语句,必须大写。
MEMORY
用来指定芯片的ROM和RAM的大小和划分出几个区间。PAGE 0对应ROM, PAGE 1对应RAM。PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。(描述系统硬件资源)
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
}
PAGE 0 : VECS(区间名字): origin(起始地址) = 800000h , length (长度)=40h //区间名自定义
如:应用字段名".vectors"的程序或数据将被放到vecs,vecs是page0即是rom空间00H至40H的地方
SECTIONS
在程序里添加下面的段名,如.vectors。用来指定该段名以下,另一个段名以上的程序或数据放到">"符号后的空间名字所在的地方。(描述"段"如何定位)
SECTIONS
{
.vectors : { } > VECS PAGE 0 /* Interrupt vector table */
.reset : { } > VECS PAGE 0 /* Reset code */
............
}
.vectors,.reset都是段名。加不加"."随你便,即.vectors表示名为 ".vectors"的段。
{}表示段的全部,{}> VECS PAGE 0表示将段的全部放入名为 VECS PAGE 0的内存区。
SECTIONS伪指令。其格式为:
SECTIONS
{
.text: {所有.text输入段名} load=加载地址 run =运行地址
.data: {所有.data输入段名} load=加载地址 run =运行地址
.bss: {所有.bss输入段名} load=加载地址 run =运行地址
.other: {所有.other输入段名} load=加载地址 run =运行地址
}
SECTIONS必须用大写字母,其后的大括号里是输出段的说明性语句,每一个输出段的说明都是从段名开始,段名之后是如何对输入段进行组织和给段分配存储器的参数说明。以.text段的属性语句为例,"{所有.text输入段名}"这段内容用来说明连接器输出段的.text段由哪些子目标文件的段组成。
运行地址和加载地址
接下来的load和run,链接器为每个输出段都在目标存储器里分配两个地址:一个是加载地址,一个是运行地址。通常情况下两个地址是相同的,可以认为输出段只有一个地址,这时就可以不加"run =运行地址"这条语句了;但有时需要将两个地址分开,比如将程序加载到FLASH,然后放到RAM中高速运行,这就用到了运行地址和加载地址的分别配置了。
load和run有一些简化写法,首先"load"关键字可以省略,"="可以写成">", "加载地址"可以是:地址值、存储区间的名字、PAGE关键词等,所以大家见到".text:{ } > 0×0080"这样的语句可千万不要奇怪。"run =运行地址"中的" = "可以用">"其它的简化写法就没有了。
在连接目标代码时,会提到运行地址和加载地址。这两者有什么区别呢?
加载时地址就是程序放置的地址,运行地址就是程序定位的绝对地址,也即在编译连接时定位的地址。如果程序是在flash里运行,则运行地址和加载地址是相同的。如果程序是在ram里运行,但程序是存储在flash里,则运行地址指向ram,而加载地址是指向flash。代码一般是烧写在NAND里面,比如S3C2440 如果开机从NAND启动 其开始的4K代码会被COPY到2440内部的4KRAM 用于对关键硬件的初始化 这时候内部RAM被映射为0x0地址。如果从NOR启动,因为NOR支持片上运行,代码可以直接在NOR上运行 此时NOR便被映射成0x0,S3C2440 内部的4KRAM便被映射到了0x40000000处。
输入输出定义
输入/输出定义:这一部分,可以通过ccs的"Build Option........"菜单设置
- .obj 链接的目标文件
- .lib 链接的库文件
- .map 生成的交叉索引文件
- .out 生成的可执行代码
编译器处理段得过程为:每个源文件都编译成独立的目标文件(.obj),每个目标文件含有自己的段;连接器把这些目标文件中相同段名得部分连接在一起,生成最终的可执行文件(.out)。
c6455.cmd文件内容
/****************************************************************************/
/* C6455.cmd */
/* Copyright (c) 2010 Texas Instruments Incorporated */
/* Author: Rafael de Souza */
/* */
/* Description: This file is a sample linker command file that can be */
/* used for linking programs built with the C compiler and */
/* running the resulting .out file on an C6455 */
/* device. Use it as a guideline. You will want to */
/* change the memory layout to match your specific C6xxx */
/* target system. You may want to change the allocation */
/* scheme according to the size of your program. */
/* */
/**************************************************************************/
-l rts64plus.lib
MEMORY
{
VECS: o = 0x00800000 l = 0x00000200
BOOT: o = 0x00800200 l = 0x00000200
L2RAM: o = 0x00800400 l = 0x001FFC00 /* 2MB L2 Internal SRAM */
L1PRAM: o = 0x00E00000 l = 0x00008000 /* 32kB L1 Program SRAM/CACHE */
L1DRAM: o = 0x00F00000 l = 0x00008000 /* 32kB L1 Data SRAM/CACHE */
EMIFA_CE2: o = 0xA0000000 l = 0x00800000 /* 8MB EMIFA CE2 */
EMIFA_CE3: o = 0xB0000000 l = 0x00800000 /* 8MB EMIFA CE2 */
EMIFA_CE4: o = 0xC0000000 l = 0x00800000 /* 8MB EMIFA CE2 */
EMIFA_CE5: o = 0xD0000000 l = 0x00800000 /* 8MB EMIFA CE2 */
DDR2_CE0: o = 0xE0000000 l = 0x20000000 /* 512MB EMIFB CE0 */
}
这是TI官方的分配方式。
SECTIONS
{
"vectors" > VECS
"bootload" > BOOT
.csl_vect > L2RAM
.text > L2RAM //包含可执行的汇编指令代码。如果不声明,代码就归属.text段;
.stack > L2RAM //存放C语言的栈
.bss > L2RAM //定义变量存放空间;
.cio > L2RAM //printf等输入输出函数使用的缓冲区所在块
.const > L2RAM //存放c程序中的字符常量、浮点常量和用const声明的常量;
.data > L2RAM //一般包括常数数据。如用来对变量初始化的数据或一个正弦表格等;
.switch > L2RAM //存放switch语句产生的常数表格。
.sysmem > L2RAM //存放C语言的堆heap;
.far > L2RAM //为c程序中用far生命的全局和静态变量保留空间;
.args > L2RAM //Command argument for host-based loader; read-only (see the --arg_size option).
.ppinfo > L2RAM //Correlation tables for compiler-based profiling ( see the --gen_profile_info option).
.ppdata > L2RAM //Data tables for compiler-based profiling (see the --gen_profile_info option).
/* COFF sections */
.pinit > L2RAM // which contains the list of global constructors for C++ programs
.cinit > L2RAM //存放用来对全局和静态变量初始化的常数。
/* EABI sections (Application Binary Interface)*/
.binit > L2RAM
.init_array > L2RAM
.neardata > L2RAM
.fardata > L2RAM
.rodata > L2RAM
.c6xabi.exidx > L2RAM
.c6xabi.extab > L2RAM
}
TMS320C6000 Optimizing Compiler User‘s Guide中对SECTIONS的说明
SECTIONS
The compiler produces relocatable blocks of code and data called sections. The sections are allocated into memory in a variety of ways to conform to a variety of system configurations. For more information about sections and allocating them, see the introductory object file information in the TMS320C6000 Assembly Language Tools User‘s Guide.
There are two basic types of sections:
• Initialized sections contain data or executable code. Initialized sections are usually, but not always,read-only. The C/C++ compiler creates the following initialized sections:
– The .args
section contains the command argument for a host-based loader. This section is read-only. See the --arg_size option for details.
– For EABI(Embedded Application Binary Interface) only, the
.binit section contains boot time copy tables. This is a read-only section. For details on BINIT, see the TMS320C6000 Assembly Language Tools User‘s Guide for linker command file information.
– For COFF ABI(Application Binary Interface) only, the .cinit section contains tables for initializing variables and constants.
– The .pinit section for COFF ABI, or the .init_array section for EABI, contains the table for calling global constructor tables.
– For EABI only, the
.c6xabi.exidx
section contains the index table for exception handling. The .c6xabi.extab section contains stack unwinding instructions for exception handling. These sections are read-only. See the --exceptions option for details.
– The .name.load section contains the compressed image of section name. This section is read-only. See the TMS320C6000 Assembly Language Tools User‘s Guide for information on copy tables.
– The .ppinfo section contains correlation tables and the .ppdata section contains data tables for compiler-based profiling. See the --gen_profile_info option for details.
– The .const section contains string literals, floating-point constants, and data defined with the C/C++ qualifiers far and const (provided the constant is not also defined as volatile). This is a read-only section. String literals are placed in the .const:.string subsection to enable greater link-time placement control.
– For EABI only, the
.fardata section reserves space for non-const, initialized far global and static variables.
– For EABI only, the .neardata section reserves space for non-const, initialized near global and static variables.
– For EABI only, the .rodata section reserves space for const near global and static variables.
– The .switch section contains jump tables for large switch statements.
– The .text section contains all the executable code and compiler-generated constants. This section is usually read-only.
• Uninitialized sections reserve space in memory (usually RAM). A program can use this space at run time to create and store variables. The compiler creates the following uninitialized sections:
– The .bss section reserves space for global and static variables. For COFF, when you specify the --rom_model linker option, at program startup, the C boot routine copies data out of the .cinit section (which can be in ROM) and stores it in the .bss section. The compiler defines the global symbol $bss and assigns $bss the value of the starting address of the .bss section.
– For EABI only, the .bss section reserves space for uninitialized global and static variables.
Uninitialized variables that are also unused are usually created as common symbols (unless you specify --common=off) instead of being placed in .bss so that they can be excluded from the resulting application.
– The .far section reserves space for global and static variables that are declared far.
– The .stack section reserves memory for the system stack.
– The .sysmem section reserves space for dynamic memory allocation. The reserved space is used by dynamic memory allocation routines, such as malloc, calloc, realloc, or new. If a C/C++ program does not use these functions, the compiler does not create the .sysmem section.
Use Only Code in Program Memory
NOTE: With the exception of code sections, the initialized and uninitialized sections cannot be allocated into internal program memory.
The assembler creates the default sections .text, .bss, and .data. You can instruct the compiler to create additional sections by using the CODE_SECTION and DATA_SECTION pragmas (see Section 6.9.3 and Section 6.9.6).
1、段分两大类:已初始化段和未初始化段。
1)已初始化段含有真实的指令和数据,存放在程序存储空间。程序存储空间在DSP片内是FLASH。调试代码时,下载代码到片外的程序存储空间——此时多为RAM。
.text:包含可执行的汇编指令代码。如果不声明,代码就归属.text段;
.data:一般包括常数数据。如用来对变量初始化的数据或一个正弦表格等;
.sect:用户可自行定义已初始化段;
.asect:作用类似于.sect,但多了绝对地址定位功能。
.cinit:存放用来对全局和静态变量初始化的常数。
.switch:存放switch语句产生的常数表格。
(1)被初始化的Section(包含数据表和可执行代码)
.text: 它包含所有的可执行代码和常数,必须放在程序页
.cinit: 它包含初始化的变量和常量表,要求放在程序页
.pinit: 它包括全局构造器(C++)初始化的变量表,要求放在程序页
.const: 它包括字符串、声明、以及被明确初始化过的全局和静态变量,要求放在低地址数据页。
.econst: 是在使用大存储器模式时使用的,包括字符串、声明、以及被明确初始化过的全局变量和静态变量,可以在数据页的任何地方。
.switch:它包括为转换声明设置的表格,可以放在程序页,也可以放在低地址的数据页。
2)未初始化的段只是保留变量的地址空间,未初始化的段存放在数据存储空间中,数据存储空间多为RAM存储单元。
.bss:定义变量存放空间;
.usect:用户可自行定义未初始化段;
.stack:存放C语言的栈;
.sysmen:存放C语言的堆;
.const:简单而言,是用来存放一些特殊的常数和字符等。
(2)未被初始化的Section(为程序运行中创建和存放的变量在存储器中保留空间)
.bss:它为全局变量和静态变量保留空间.在程序开始运行时,C导入路径把数据从.cinit节复制出去然后存在.bss节中.要求放在低地址的数据页.
.ebbs:它是在远访问(C)和大存储器模式下使用,它为全局变量和静态变量保留空间.在程序开始运行时,C导入路径把数据从.cinit段复制出去然后存在.ebss节中。可以存放在数据页的任何地方。
.stack:为C系统堆栈保留空间,这部分存储器为用来将声明传给函数及为局部变量留出空间。要求放在低地址的数据页。
.system:动态存储器分配保留空间,这个空间用于malloc函数,如果不使用malloc函数,这个段的大小就是0。要求放在低地址的数据页。
.esystem:动态存储器分配保留空间,这个空间用于外部malloc函数,如果不使用外部malloc函数,这个段的大小就是0。可也放在数据页的任何地方
CMD文件中,page0代表程序空间,page1代表数据空间。
page0:.text,.cinit,通过#pragma CODE_SECTION定义的段;
page1:.switch,.const,.bss,.stack,.sysmen,通过#pragma DATA_SECTION定义的段。