DSP6455的cmd文件
发布日期:2021-08-15 23:44:21 浏览次数:1 分类:技术文章

本文共 11747 字,大约阅读时间需要 39 分钟。

DSP6455的cmd文件

CMD 的专业名称叫链接器配置文件,存放链接器的配置信息,DSP编译器的编译结果是未定位的,DSP也没有操作系统来定位执行代码,DSP系统的配置需求也不尽相同,因此需要定义代码存储位置。CMD分配ROM和RAM空间,告诉链接程序怎样计算地址和分配空间。所以不同的芯片就有不同大小的ROM和RAM,存放用户程序的地方也不尽相同。所以要根据芯片进行修改。

DSP 芯片的片内存储器, 只要没有被 TI 占用, 用户都可以全权支配。 TI 设计了 "CMD文件"这种与用户的接口形式,用户通过编写 CMD 文件,来管理、分配系统中的所有物理存储器和地址空间。CMD 文件其实就是用户的"声明" ,包括两方面的内容:

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

2、用户如何分配这些存储器资源,即关于资源分配情况的声明。用户根据自己的需要,结合芯片的要求,把各种数据分配到适当种类、适当特点、适当长度的存储器区域,这是编写 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定义的段。

参考网上资料

由*.out文件经过hex6x.exe文件生成hex文件

首先你要有*.cmd文件和hex6x.exe和*.out文件。

其中out文件是上面一篇中提到的,在CCS里面编译成功的输出文件*.out。

*.cmd文件,里面的内容是这样的:

 debugSEEDVPM642boot.out

-a

-memwidth  8

-boot

-bootorg 0x90000400

-bootsection .boot_load 0x90000000

ROMS

{

FLASH:  org = 0x90000000, len = 0x80000, romwidth = 8, files = {SEEDVPM642boot_ahex.hex}

}

 其中SEEDVPM642boot.out就是上面提到的*.out文件。files = {SEEDVPM642boot_ahex.hex}就是你最终要得到的hex文件。

工程目录下的文件夹中.map文件里有section allocation map可以查看产生的"段"。查看 .map 文件中"output section"那一列,那些长度(length)非 0 的段,就是你的项目真正会产生的段;那些长度为 0 的段,基本都可以从 CMD 文件中删除。比较一下起始地址和最后的地址就能计算书长度。

打开计算机的开始-所有程序-附件-命令提示符,进入DOS环境,使用cd命令切换到hex6x.exe文件目录。在dos环境下执行hex6x.exe程序。若hex6x.exe、sample.cmd放置在e:sample下,sample.out位于e:sampledebug目录中,则在dos环境下输入

cd e:sample

hex6x.exe sample.cmd 回车

然后查看e:sample 即会有hex文件。

【建议:新建一个文件夹,把hex6x.exe文件、*.cmd文件拷贝进去,然后在新建文件夹的目录下,再建立一个debug文件夹,把out文件拷贝进去。这样比较清楚,一目了然!】

 来自 <>

转载于:https://www.cnblogs.com/pejoicen/p/4023359.html

转载地址:https://blog.csdn.net/weixin_30781631/article/details/98088906 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:VS2012中对C++注释高亮的改进
下一篇:【THUSC2017】【LOJ2981】如果奇迹有颜色 DP BM 打表 线性递推

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月24日 20时30分36秒