通过连接器,把一个全局变量放在指定存储器期望的位置,大体有两种方法。第一种:可以指定全局变量放到绝对物理地址位置。使用__at放置符号,可以使用/不使用配置分散加载文件(这里会衍生2种方法)。第二种,指定全局变量在某一个范围,使用name section,配合分散加载文件使用。我这里就归纳为总共3种方法吧。
name section是啥? 我也不知道准确的翻译,大概意识就是定义一个段section,给这个段取一个name,合起来就是name section。
注意:下面都是针对ARM编译器5(AC5)描述,AC6可能有区别。
1)方法一:使用放置符号__at把变量放在指定存储器位置,不用分散加载文件
①在main.c中增加如下代码:
int gValue __attribute__((section(".ARM.__at_0x20004000"))) = 3; // Place at 0x20004000
或者:
int gValue __attribute__((at(0x20004000))) = 3; // Place at 0x20002000
②我们在map文件中可以看到:
2)方法二:使用放置符号__at把变量放在指定存储器位置,配合使用分散加载文件
这种情况,一定要注意,在分散加载文件中,放置".ARM.__at_0x20004000"所在执行域的地址范围包含了0x20004000地址。
①在main.c中增加如下代码:
int gValue __attribute__((section(".ARM.__at_0x20004000"))) = 3; // Place at 0x20004000
或者:
int gValue __attribute__((at(0x20004000))) = 3; // Place at 0x20002000
②修改分散加载文件
③我们在map文件中可以看到:
感觉这种方法,没有必要,方法二不修改分散加载文件,也能实现目的,何必还使用方法三修改分散加载文件呢。
3)方法三:使用name section把变量放在指定存储器位置,配合分散加载文件
这种方式可以指定变量在一个执行域的地址范围内,而不是指定在绝对物理地址。
①在main.c中增加代码:
int gSquared __attribute__((section("foo"))); // Place in section foo
②在分散加载文件中增加内容:
③查看map文件: