Arm Compiler Embedded 6中如何将常量算术表达式转为字符串用于section属性
问题:Arm Compiler for Embedded 6 适配指定RAM地址放置数据的编译期字符串化方案
我们团队正将项目从Arm Compiler for Embedded 5升级至Embedded 6。原代码通过__attribute__((at(RAM_START_ADDR + OFFSET)))在RAM指定位置放置数据:
#define RAM_START_ADDR <some constant> #define OFFSET <some other constant> ... volatile my_datatype_t __attribute__((at(RAM_START_ADDR + OFFSET))) var = ...;
但Embedded 6不再支持at属性,需改用__attribute__((section(".ARM.__at_<addr>"))),而该属性要求参数为数字字符串,无法直接使用常量算术表达式。ARM提供的指针方案:
volatile my_datatype_t * const var = (volatile my_datatype_t *) (RAM_START_ADDR + OFFSET);
会直接覆盖目标地址数据,而非为var分配空间。现咨询:能否在编译时将常量算术表达式求值并格式化为字符串,以适配section属性?
解决方案
可以利用C预处理器的字符串化操作符#和连接操作符##,结合编译期常量计算来实现。核心思路是先让预处理器算出地址值,再将其转化为字符串并拼接进section属性的参数中。
步骤1:实现编译期地址计算与字符串化
通过嵌套宏完成计算→数值转字符串→拼接section名称的完整流程:
#define RAM_START_ADDR 0x20000000 #define OFFSET 0x100 // 辅助宏:将数值转为字符串(嵌套避免预处理器直接展开宏名) #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) // 拼接目标section名称 #define AT_SECTION(addr) __attribute__((section(".ARM.__at_" STR(addr)))) // 最终使用方式 volatile my_datatype_t AT_SECTION(RAM_START_ADDR + OFFSET) var = ...;
原理说明
RAM_START_ADDR + OFFSET会被预处理器优先计算为具体数值(比如0x20000100);STR(addr)通过嵌套宏STR_HELPER将计算后的数值转为字符串"0x20000100";- 最终拼接出符合要求的section属性参数
.ARM.__at_0x20000100,完美适配Embedded 6的语法规则。
注意事项
- 必须保证
RAM_START_ADDR和OFFSET是编译期常量(宏定义数值、枚举常量等),预处理器无法处理运行时变量; - 地址无论以十六进制还是十进制定义,预处理器都会自动完成转换与拼接;
- 需提前确认链接脚本中未对目标地址区域做冲突分配,避免编译或链接阶段报错。
内容的提问来源于stack exchange,提问作者user23562328
相关产品推荐
相关产品推荐

