目的:
简要介绍IAR下如何同时指定section的LMA(加载地址,ROM)和VMA(运行地址,RAM)。
操作说明:
修改 icf文件,新增 my_test_section 、my_test_section_init 布局。
1, 使用编译器自动生成的拷贝方法:
icf文件修改前后对比:

通过这种方式可手动指定section的存放地址(如这里的ROM_region_2)和 运行地址 (如这里的RAM2_region_2)
测试代码示例:
cpp
...
__attribute__(( section( "my_test_section"))) uint8_t test_arr[4] = {0x11, 0x22, 0x33, 0x44};
int main(void)
{
...
for(uint8_t i = 0; i < 4; i++)
{
INFO("0x%X\n", test_arr[i]);
}
...
}
2,使用手动拷贝:
icf文件修改前后对比:

cpp
...
__attribute__(( section( "my_test_section"))) uint8_t test_arr[4] = {0x11, 0x22, 0x33, 0x44};
#pragma section = "my_test_section"
#pragma section = "my_test_section_init"
int main(void)
{
...
// 从LMA拷贝到VMA
memcpy((uint8_t*)__section_begin("my_test_section"),
(uint8_t*)__section_begin("my_test_section_init"),
__section_size("my_test_section_init"));
for(uint8_t i = 0; i < 4; i++)
{
INFO("0x%X\n", test_arr[i]);
}
...
}
原理解释:

《EWARM_DevelopmentGuide.ENU.pdf》
从上可知,默认情况下,在链接阶段,一个section(如这里的my_test_section)会被分成两个section来进行初始化,原名称的section(如这里的my_test_section)按照之前设定的初始化方式进行初始化,新创建一个section,名称为原名称+_init后缀(如这里的my_test_section_init)用来存放初始值,放在ROM区域。
如上针对运行在RAM上保存在ROM上的section才有意义,对于存放和使用都在ROM没有意义(如const 类型数据)。
前面的示例就是显式的指定了section同名+_init 的 section的存储布局来指定在ROM上存放位置的方式。
参考:
《EWARM_DevelopmentGuide.ENU.pdf》