我使用armclang, 想用 fw_blk_entry_t g_fw_blk_entry[FW_BLK_ENTRY_QNTY] attribute((section(".ARM._at" STR(FW_BLK_ENTRY_BASE)))); 这种方式来将一个变量声明到对应的内存地址上, 其中 FW_BLK_ENTRY_BASE 是一个宏, 但他不是一个直接数, 而是一个表达式. 如果我直接编译会得到Error: L6974E: AT section .ARM._at((((((0x04000000) + 0x1A4000)) + (64 - 1)) & (0xffffffc0))) does not have a base address. 请问怎么解决?
在使用 __attribute__((section(".ARM.__at_<address>")))
时,<address>
必须是一个编译时已知的常量值,而不能是一个复杂的表达式。你遇到的错误是因为编译器���法解析 FW_BLK_ENTRY_BASE
宏中的表达式并将其转换为一个具体的地址。
要解决这个问题,你可以尝试以下几种方法:
你可以在链接脚本中指定变量的地址,而不是在代码中使用 __attribute__((section(".ARM.__at_<address>")))
。首先,创建一个链接脚本(例如 custom.ld
),并在其中指定变量的地址:
SECTIONS
{
. = (((((0x04000000) + 0x1A4000)) + (64 - 1)) & (0xffffffc0));
.fw_blk_entry :
{
KEEP(*(.fw_blk_entry))
}
}
然后,在代码中使用 __attribute__((section(".fw_blk_entry")))
来将变量放置在这个段中:
#define FW_BLK_ENTRY_QNTY 10
typedef struct {
// your struct definition
} fw_blk_entry_t;
fw_blk_entry_t g_fw_blk_entry[FW_BLK_ENTRY_QNTY] __attribute__((section(".fw_blk_entry")));
最后,编译时指定使用自定义链接脚本:
armclang -T custom.ld -o output.elf your_source_file.c
如果你可以将 FW_BLK_ENTRY_BASE
计算为一个常量值,那么可以直接在代码中使用这个常量值。例如:
#define FW_BLK_ENTRY_BASE 0x041A3FC0 // 计算后的常量地址
#define FW_BLK_ENTRY_QNTY 10
typedef struct {
// your struct definition
} fw_blk_entry_t;
fw_blk_entry_t g_fw_blk_entry[FW_BLK_ENTRY_QNTY] __attribute__((section(".ARM.__at_" STR(FW_BLK_ENTRY_BASE))));
如果表达式可以在编译时计算,你可以使用预处理器来计算地址。例如:
#define BASE_ADDR 0x04000000
#define OFFSET 0x1A4000
#define ALIGNMENT 64
#define FW_BLK_ENTRY_BASE (((BASE_ADDR + OFFSET) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1))
#define FW_BLK_ENTRY_QNTY 10
typedef struct {
// your struct definition
} fw_blk_entry_t;
fw_blk_entry_t g_fw_blk_entry[FW_BLK_ENTRY_QNTY] __attribute__((section(".ARM.__at_" STR(FW_BLK_ENTRY_BASE))));
请注意,STR
宏需要定义为将数值转换为字符串的宏:
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
通过这些方法,你可以将变量放置在特定的内存地址上。选择哪种方法取