我的团队将我们的项目从使用 Arm 编译器用于嵌入式 5 升级到嵌入式 6。在我们的代码中,我们将数据放置在 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 不再支持
__attribute__((at(<addr>)))
,相反,我们需要使用__attribute__((section(".ARM.__at_<addr>")))
。您可能已经注意到,我们正在处理的地址是一个算术表达式,__attribute__(section)
不支持该表达式,它需要一个数字字符串参数。 ARM 确实提供了一种解决方法,即
volatile my_datatype_t * const var = (volatile my_datatype_t *) (RAM_START_ADDR + OFFSET);
不同的是,当编译时,它不会为
var
分配空间,而是覆盖 RAM_START_ADDR + OFFSET
处的任何数据。还没有问 ARM 如何实现这一点,但我不相信除了他们已经提供的不起作用的解决方法之外我们还能得到任何东西。
有没有办法在编译时计算常量算术表达式并将其格式化为字符串?如果是这样,那么我们仍然可以使用
__attribute__((section))
并将数字字符串传递给它。
我做了很多研究,似乎没有一种方法可以定义宏,以便对表达式进行求值并且可以将值作为标记或字符串或任何其他内容进行访问。
你运气不好。这是一个预处理器,如果您想添加任何内容,则必须对所有可能的组合进行硬编码。这可以使用脚本生成,或者您可以尝试搜索像 boost 这样的现有项目。
// Add two numbers and output them in hex
#define ADDHEX_1_1() 2
#define ADDHEX_1_2() 3
// .... few billion lines later
#define ADDHEX_123_456() 234
#define CONCAT4(a, b, c, d) a##b##c##d
#define XCONCAT4(a, b, c, d) CONCAT4(a, b, c, d)
#define STRING(x) #x
#define XSTRING(x) STRING(x)
#define RAM_START_ADDR 123
#define OFFSET 456
#define AT XSTRING(XCONCAT4(ADDHEX_, RAM_START_ADDR, _, OFFSET)())
#include <stdio.h>
int main() {
puts(".ARM.__at_" AT);
}
您可以使用 Boost 预处理器库来实现这一点: