如何在IAR链接脚本中定义镜像总大小或结束地址的符号?
在IAR C中构建时定义符号获取镜像大小的正确方法
一、size()/end()函数的正确参数用法
IAR映射文件里的P1/P2是链接器自动生成的区域简写,不是链接脚本(.icf)中识别的正式区域名称,这是你报错的核心原因。
你需要找到工程使用的链接脚本(.icf文件),路径可通过工程设置:Project > Options > Linker > Config查看。打开该文件后,找到对应只读区域的define region定义,比如默认脚本里通常会有类似这样的声明:
define region ROM_Region = mem:[from 0x08000000 to 0x080FFFFF]; define region RAM_Region = mem:[from 0x20000000 to 0x2001FFFF];
使用这个正式的区域名称作为size()或end()的参数,且不需要加引号,正确写法如下:
// 导出ROM区域的总大小 define exported symbol MY_IMAGE_SIZE = size(ROM_Region); // 导出ROM区域的结束地址 define exported symbol MY_ROM_END_ADDR = end(ROM_Region);
二、无需修改默认链接脚本的替代方案
如果不想改动默认链接脚本,也可以直接通过内置段名称的总和来计算镜像大小,比如只读代码+初始化数据的总大小:
define exported symbol MY_IMAGE_SIZE = size(__CODE_segment) + size(__RODATA_segment) + size(__DATA_segment);
常用的IAR内置段名称参考:
__CODE_segment:存放程序代码的段__RODATA_segment:只读数据段(比如字符串常量)__DATA_segment:初始化数据段(加载时从ROM复制到RAM)__ZERO_INIT_segment:未初始化数据段(仅在RAM中分配空间)
三、C代码中调用导出的符号
在C代码里通过extern声明后即可直接使用这些导出的符号:
extern const unsigned int MY_IMAGE_SIZE; extern const unsigned int MY_ROM_END_ADDR; void show_image_info(void) { printf("镜像总大小:%u 字节\n", MY_IMAGE_SIZE); printf("ROM结束地址:0x%X\n", MY_ROM_END_ADDR); }
四、常见错误排查
Error[Lc010]: "P1" is not a region name:P1是映射文件的简写别名,不是链接脚本的正式区域名,必须用.icf中define region后的标识符。Error[Lc007]: expected an identifier:不要给区域/段名称加引号,直接使用标识符即可。
内容的提问来源于stack exchange,提问作者ddbug
相关产品推荐
相关产品推荐

