如何通过GCC链接器在.text段指定地址放置32位常量
解决方法:将32位常量定位到.text段指定地址
1. 修正链接脚本配置
不要把.systemid放在.text段起始位置,而是显式跳转到目标地址0x080017FC后再放置该段,同时确保后续代码不会和该地址重叠。修改后的链接脚本如下:
.text : { . = ALIGN(4); /* 先处理所有常规代码段 */ *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); /* 显式跳转到目标地址 */ . = 0x080017FC; /* 放置.systemid段,用KEEP防止被优化 */ KEEP(*(.systemid)) /* 确保后续代码从常量结束的下一个对齐地址开始 */ . = ALIGN(4); _etext = .; /* 定义代码段结束的全局符号 */ } >FLASH
2. 正确声明常量变量
使用独立的.systemid段即可,无需写成.text.systemid,链接脚本会自动将该段放到.text段的指定地址中。声明代码如下:
const uint32_t __attribute__((used, section(".systemid"))) SYSTEM_ID_U32 = 0x11223344;
used属性确保编译器不会因变量未被引用而优化掉它;section(".systemid")指定变量放入对应段,和链接脚本配置完全匹配。
3. 避免地址重叠的关键
- 确认
0x080017FC未被占用:编译时添加-Wl,-Map=output.map参数生成映射文件,检查该地址是否已被其他代码/数据分配; - 若目标地址位于现有代码段中间,需确保该地址到
_etext之间至少有4字节空间(对应32位常量),避免后续代码覆盖常量; - 结合MCU Flash的擦除块特性,确认目标地址处于合法的可写入区域。
之前方法无效的原因
- 你之前把
.systemid放在.text段起始位置,链接器会优先将其放在最前端,自然无法到达目标地址; - 使用
--section-start参数时,若.systemid是独立段,参数应写--section-start=.systemid=0x080017FC,但这种方式容易和.text段的默认地址范围冲突,不如链接脚本显式定位可靠。
内容的提问来源于stack exchange,提问作者bluscape
相关产品推荐
相关产品推荐

