如何获取结构成员的地址

How to obtain addresses of structure members

我正在测试一个基于 Cortex-M0 的项目。固件是使用 Keil (v. 4.71.2) 和 ARM Linker (v. 5.03) 在 C 中开发的。我可以 read/write 访问我用来模拟故障的 RAM,我需要找出我需要修改的变量的地址。

现在我正在使用链接器映射文件,它对标量全局变量非常方便:

myvar        0x00005978   Data      4  file1.o(.constdata)

这里我知道在地址 0x00005978 写入 4 个字节会改变变量 myvar。但是,我不能对全局结构应用相同的方法:

mystruct     0x00020000   Data     400 file2.o(.data)

我有mystruct的起始地址,但是,我无法访问mystruct.module2.config.myvar。由于代码仍在开发中,因此 mystruct.module1 中添加了新字段并且 mystruct.module2 的地址发生了变化。

是否可以强制链接器输出结构中各个字段的地址?

作为解决方法,我声明了一个全局变量,其中包含我想要的地址:

uint32_t * const myvar_ptr = &mystruct.module2.config.myvar;

然后我就可以在linker map中找到myvar_ptr的地址,读取得到mystruct.module2.config.myvar的地址。但是这种方式浪费了4个字节的ROM来存储每个指针,而且ROM的大小是有严格限制的,所以我不能针对mystruct的每个域声明100个额外的指针。有没有更好的方法?

正如您在评论中指出的那样,结构对齐可能是一个问题。看起来 Keil 编译器确实支持 pack() #pragma 所以你可以控制结构成员的对齐方式。然后,您可以使用 .MAP 文件获取结构的起始地址,并使用定义结构的 C 包含文件来计算各个成员的偏移量。