.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};codestartcodestart : BEGIN, PAGE 0Flash 启动入口。C2000 从 Flash 启动时Boot ROM 会跳到BEGIN然后再跳到 C 程序入口最后进入main()。速记codestart 上电后从 Flash 启动的第一跳ramfuncsramfuncs : LOAD FLASHD, RUN RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_SIZE(_RamfuncsLoadSize), RUN_START(_RamfuncsRunStart), PAGE 0这段最重要。意思是字段含义LOAD FLASHD程序烧录时放在 FlashDRUN RAML0运行时搬到 RAML0 执行LOAD_STARTFlash 中的起始地址LOAD_SIZE需要拷贝的大小RUN_STARTRAM 中的运行地址常用于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 启动入口BEGINPassword 区单独保留不能乱占8. 一句话速记MEMORY 定义内存地图 SECTIONS 决定代码和变量放哪里 PAGE 0 常放代码 PAGE 1 常放数据 同一块 RAM 不能重复分配 ramfuncs 是 Flash 加载、RAM 运行。