You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keil/armclang/armlink环境下将变量放置到指定内存区域?

问题原因

你当前使用的Keil自动生成的分散加载文件中,RW_IRAM1的匹配规则排在RW_IRAM2之前,二者的匹配规则都是.ANY (+RW +ZI),你自定义的段名没有显式绑定到RW_IRAM2时,链接器会优先将段分配到靠前的RW_IRAM1区域,因此之前的写法不生效。

不需要完全放弃自动生成的分散加载文件,两种可行方案如下:


方案1:使用ARM编译器内置绝对地址段规则(无需修改IDE配置)

ARMCC/ARM Clang支持特殊的段名格式.ARM.__at_<目标地址>,链接器会自动将该段分配到对应地址所属的存储区域,只要地址在你配置的RW_IRAM2范围(0x20000000 ~ 0x2001FFFF)内,就会自动归入RW_IRAM2区域。

示例代码:

// 带初始值的RW类型变量,分配到RW_IRAM2
uint32_t ram2_rw_var __attribute__((section(".ARM.__at_0x20000000"))) = 0x1234;
// 零初始化的ZI类型变量,分配到RW_IRAM2
uint32_t ram2_zi_var __attribute__((section(".ARM.__at_0x20000004")));

可以用宏简化多变量定义的写法:

#define RAM2_ADDR(addr) __attribute__((section(".ARM.__at_"#addr)))
uint32_t var1 RAM2_ADDR(0x20000000);
uint32_t var2 RAM2_ADDR(0x20000004);
uint32_t var3 RAM2_ADDR(0x20000008);

方案2:指定自定义段基址,让链接器自动分配(无需手动管理地址偏移)

如果你不想手动维护变量地址偏移,可以给自定义段统一命名,再在IDE中指定段的起始地址:

  1. 代码中为需要放在RW_IRAM2的变量指定统一的自定义段名:
uint32_t in_ram2 __attribute__((section(".ram2")));
uint32_t another_ram2_var __attribute__((section(".ram2")));
  1. 打开Keil的Options for Target -> Linker -> Misc controls,添加如下参数:
--section-start=.ram2=0x20000000

链接器会把所有.ram2段的内容从0x20000000开始自动分配,不会和RW_IRAM2区域内的其他内容产生地址冲突。


内容的提问来源于stack exchange,提问作者Graeme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 06:45:05