.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:程序空间
| 名称 | 地址 | 作用 |
|---|---|---|
RAML0 | 0x008000 | L0 RAM,可放需要在 RAM 中运行的代码 |
RAML1 | 0x008800 | L1 RAM,也可作为程序 RAM 使用 |
FLASHC | 0x3F2000 | Flash 区,常放主程序代码 |
FLASHD | 0x3F0000 | Flash 区,常放需要搬到 RAM 运行的函数 |
BEGIN | 0x3F7FF6 | Flash 启动入口 |
CSM_PWL | 0x3F7FF8 | 代码安全密码区 |
RESET | 0x3FFFC0 | Reset 向量位置 |
VECTORS | 0x3FFFC2 | CPU 基础中断向量区 |
PAGE 1:数据空间
| 名称 | 地址 | 作用 |
|---|---|---|
BOOT_RSVD | 0x000000 | Boot 保留区,不给普通变量用 |
RAMM0 | 0x000050 | M0 RAM 的一部分,常放栈 |
RAMM1 | 0x000400 | M1 RAM,可放变量 |
RAML2 | 0x008C00 | L2 RAM,常放全局变量 |
RAML3 | 0x009000 | L3 RAM,常放堆或较大的数据 |
4.SECTIONS部分解释
| 段名 | 放到哪里 | 作用 |
|---|---|---|
.cinit | FLASHC | C 语言初始化数据 |
.pinit | FLASHC | C++ 构造函数初始化表 |
.text | FLASHC | 主程序代码 |
codestart | BEGIN | Flash 启动入口跳转代码 |
ramfuncs | 加载在FLASHD,运行在RAML0 | 上电后从 Flash 拷贝到 RAM 执行 |
.stack | RAMM0 | 栈空间 |
.ebss | RAML2 | 未初始化全局变量、静态变量 |
.bss | RAML2 | 未初始化变量 |
.sysmem | RAML3 | 堆空间,malloc()用 |
.econst | FLASHC | 常量数据 |
.switch | FLASHC | switch-case跳转表 |
.reset | RESET | Reset 段,通常只占位 |
vectors | VECTORS | CPU 向量表,通常只占位 |
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 = 0Flash 启动入口。
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_START | Flash 中的起始地址 |
LOAD_SIZE | 需要拷贝的大小 |
RUN_START | RAM 中的运行地址 |
常用于:
Flash 初始化函数 高速中断函数 时间敏感函数速记:
ramfuncs = 烧在 Flash,运行前搬到 RAM.reset和vectors
.reset : > RESET, PAGE = 0, TYPE = DSECT vectors : > VECTORS, PAGE = 0, TYPE = DSECTTYPE = DSECT表示这个段只声明地址,不真正占用输出文件空间。
速记:
DSECT = 占位声明,不真正生成内容6. PAGE 0 / PAGE 1 注意事项
PAGE 0和PAGE 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 运行。