TI C2000 .cmd 文件笔记

4 阅读5分钟

.cmd 文件是 TI C2000 的链接器命令文件,作用是告诉编译器:

芯片有哪些内存;
代码放哪里;
变量放哪里;
栈放哪里;
哪些函数从 Flash 搬到 RAM 运行。

1. 经典 Flash 运行版 .cmd 示例

MEMORY
{
PAGE 0:    /* Program Memory,主要放代码 */
    RAML0     : origin = 0x008000, length = 0x000800
    RAML1     : origin = 0x008800, length = 0x000400

    FLASHC    : origin = 0x3F2000, length = 0x002000
    FLASHD    : origin = 0x3F0000, length = 0x002000
    BEGIN     : origin = 0x3F7FF6, length = 0x000002

    CSM_PWL   : origin = 0x3F7FF8, length = 0x000008
    RESET     : origin = 0x3FFFC0, length = 0x000002
    VECTORS   : origin = 0x3FFFC2, length = 0x00003E

PAGE 1:    /* Data Memory,主要放数据 */
    BOOT_RSVD : origin = 0x000000, length = 0x000050
    RAMM0     : origin = 0x000050, length = 0x0003B0
    RAMM1     : origin = 0x000400, length = 0x000400
    RAML2     : origin = 0x008C00, length = 0x000400
    RAML3     : origin = 0x009000, length = 0x001000
}

SECTIONS
{
    .cinit      : > FLASHC, PAGE = 0
    .pinit      : > FLASHC, PAGE = 0
    .text       : > FLASHC, PAGE = 0
    codestart   : > BEGIN,  PAGE = 0

    ramfuncs    : LOAD = FLASHD,
                  RUN  = RAML0,
                  LOAD_START(_RamfuncsLoadStart),
                  LOAD_SIZE(_RamfuncsLoadSize),
                  RUN_START(_RamfuncsRunStart),
                  PAGE = 0

    .stack      : > RAMM0, PAGE = 1
    .ebss       : > RAML2, PAGE = 1
    .bss        : > RAML2, PAGE = 1
    .sysmem     : > RAML3, PAGE = 1

    .econst     : > FLASHC, PAGE = 0
    .switch     : > FLASHC, PAGE = 0

    .reset      : > RESET,   PAGE = 0, TYPE = DSECT
    vectors     : > VECTORS, PAGE = 0, TYPE = DSECT
}

这个文件是学习用的经典结构,真实工程要以具体芯片型号对应的 .cmd 文件为准,喵。


2. .cmd 文件整体结构

部分作用速记
MEMORY定义芯片有哪些内存区域画地图
SECTIONS把代码、变量、栈分配到具体内存安排住处
PAGE 0程序空间常放代码
PAGE 1数据空间常放变量、栈、堆

3. MEMORY 部分解释

PAGE 0:程序空间

名称地址作用
RAML00x008000L0 RAM,可放需要在 RAM 中运行的代码
RAML10x008800L1 RAM,也可作为程序 RAM 使用
FLASHC0x3F2000Flash 区,常放主程序代码
FLASHD0x3F0000Flash 区,常放需要搬到 RAM 运行的函数
BEGIN0x3F7FF6Flash 启动入口
CSM_PWL0x3F7FF8代码安全密码区
RESET0x3FFFC0Reset 向量位置
VECTORS0x3FFFC2CPU 基础中断向量区

PAGE 1:数据空间

名称地址作用
BOOT_RSVD0x000000Boot 保留区,不给普通变量用
RAMM00x000050M0 RAM 的一部分,常放栈
RAMM10x000400M1 RAM,可放变量
RAML20x008C00L2 RAM,常放全局变量
RAML30x009000L3 RAM,常放堆或较大的数据

4. SECTIONS 部分解释

段名放到哪里作用
.cinitFLASHCC 语言初始化数据
.pinitFLASHCC++ 构造函数初始化表
.textFLASHC主程序代码
codestartBEGINFlash 启动入口跳转代码
ramfuncs加载在 FLASHD,运行在 RAML0上电后从 Flash 拷贝到 RAM 执行
.stackRAMM0栈空间
.ebssRAML2未初始化全局变量、静态变量
.bssRAML2未初始化变量
.sysmemRAML3堆空间,malloc()
.econstFLASHC常量数据
.switchFLASHCswitch-case 跳转表
.resetRESETReset 段,通常只占位
vectorsVECTORSCPU 向量表,通常只占位

5. 重点段说明

.text

.text : > FLASHC, PAGE = 0

主程序代码放在 FLASHC

例如:

main()
InitSysCtrl()
InitGpio()

这些函数大部分会进入 .text


.stack

.stack : > RAMM0, PAGE = 1

栈放在 RAMM0

栈主要用于:

函数调用
局部变量
返回地址
中断现场保护

.ebss / .bss

.ebss : > RAML2, PAGE = 1
.bss  : > RAML2, PAGE = 1

未初始化变量放在 RAML2。

例如:

int adc_value;
static int pwm_count;

这类变量一般会进入 .ebss.bss


.econst

.econst : > FLASHC, PAGE = 0

常量放在 Flash。

例如:

const float Kp = 0.5f;
const int table[10] = {1,2,3,4,5};

codestart

codestart : > BEGIN, PAGE = 0

Flash 启动入口。

C2000 从 Flash 启动时,Boot ROM 会跳到 BEGIN,然后再跳到 C 程序入口,最后进入 main()

速记:

codestart = 上电后从 Flash 启动的第一跳

ramfuncs

ramfuncs : LOAD = FLASHD,
           RUN  = RAML0,
           LOAD_START(_RamfuncsLoadStart),
           LOAD_SIZE(_RamfuncsLoadSize),
           RUN_START(_RamfuncsRunStart),
           PAGE = 0

这段最重要。

意思是:

字段含义
LOAD = FLASHD程序烧录时放在 FlashD
RUN = RAML0运行时搬到 RAML0 执行
LOAD_STARTFlash 中的起始地址
LOAD_SIZE需要拷贝的大小
RUN_STARTRAM 中的运行地址

常用于:

Flash 初始化函数
高速中断函数
时间敏感函数

速记:

ramfuncs = 烧在 Flash,运行前搬到 RAM

.resetvectors

.reset  : > RESET,   PAGE = 0, TYPE = DSECT
vectors : > VECTORS, PAGE = 0, TYPE = DSECT

TYPE = DSECT 表示这个段只声明地址,不真正占用输出文件空间。

速记:

DSECT = 占位声明,不真正生成内容

6. PAGE 0 / PAGE 1 注意事项

PAGE 0PAGE 1 不是两份 RAM。

同一块物理 RAM 不能这样重复使用:

PAGE 0:
    RAML0_CODE : origin = 0x008000, length = 0x000800

PAGE 1:
    RAML0_DATA : origin = 0x008000, length = 0x000800

因为它们实际都是:

0x008000 ~ 0x008800

这样代码和变量会互相覆盖。

正确做法:

做法是否可以
整块 RAM 给 PAGE 0 放代码可以
整块 RAM 给 PAGE 1 放数据可以
同一块 RAM 手动切成两段可以
PAGE 0 和 PAGE 1 使用同一整块 RAM不可以

7. 最常见分配规则

内容推荐位置
主程序代码Flash
常量Flash
初始化数据Flash
RAM
全局变量RAM
静态变量RAM
RAM
高速函数Flash 加载,RAM 运行
Flash 启动入口BEGIN
Password 区单独保留,不能乱占

8. 一句话速记

MEMORY 定义内存地图;
SECTIONS 决定代码和变量放哪里;
PAGE 0 常放代码;
PAGE 1 常放数据;
同一块 RAM 不能重复分配;
ramfuncs 是 Flash 加载、RAM 运行。