映射文件中成员结构的地址?
address of member structure in map file?
已经有关于此主题的问题(特别是 How to get address of some struct member in array of structures)。
我的问题如下:
当我们使用struct
来描述一个硬件设备时,那么每个结构体成员都会对应硬件设备的一些寄存器——我们如何确定结构体的每个成员都正确映射到硬件的每个寄存器上?
编译器的 ABI 规定了成员的对齐方式,用户也可能会犯一些错误 - 确保映射正确完成的唯一方法是在 运行 时间进行检查。
映射文件(至少对于 GNU ld)没有提供任何关于结构成员放置的线索。
是否有办法在编译器或 link 时知道每个结构成员所在的位置?
您可以使用 offsetof
along with, in C++, static_assert
.
例如,完全任意
#include <cstddef>
struct iom { // off,len
uint32_t rx; // +0,4
uint32_t tx; // +4,4
uint64_t clk; // +8,8
uint16_t irq; // +16,2
};
static_assert(offsetof(iom,rx)==0);
static_assert(offsetof(iom,tx)==4);
static_assert(offsetof(iom,clk)==8);
static_assert(offsetof(iom,irq)==16);
如果 static_assert
失败,例如因为您的编译器将成员对齐到 64 位边界,您需要一种特定于编译器的方法来更改对齐和填充。例如,使用 gcc,
} __attribute__((packed));
在结构定义的末尾。
注意。我已经回答了 C++17。
C++11 或 14,或 C11 需要一条错误消息作为 static_assert
的第二个参数,尽管您可以将整个内容包装在一个宏中以便为您编写一个漂亮的字符串。
offsetof
宏也适用于 C。
已经有关于此主题的问题(特别是 How to get address of some struct member in array of structures)。
我的问题如下:
当我们使用struct
来描述一个硬件设备时,那么每个结构体成员都会对应硬件设备的一些寄存器——我们如何确定结构体的每个成员都正确映射到硬件的每个寄存器上?
编译器的 ABI 规定了成员的对齐方式,用户也可能会犯一些错误 - 确保映射正确完成的唯一方法是在 运行 时间进行检查。 映射文件(至少对于 GNU ld)没有提供任何关于结构成员放置的线索。
是否有办法在编译器或 link 时知道每个结构成员所在的位置?
您可以使用 offsetof
along with, in C++, static_assert
.
例如,完全任意
#include <cstddef>
struct iom { // off,len
uint32_t rx; // +0,4
uint32_t tx; // +4,4
uint64_t clk; // +8,8
uint16_t irq; // +16,2
};
static_assert(offsetof(iom,rx)==0);
static_assert(offsetof(iom,tx)==4);
static_assert(offsetof(iom,clk)==8);
static_assert(offsetof(iom,irq)==16);
如果 static_assert
失败,例如因为您的编译器将成员对齐到 64 位边界,您需要一种特定于编译器的方法来更改对齐和填充。例如,使用 gcc,
} __attribute__((packed));
在结构定义的末尾。
注意。我已经回答了 C++17。
C++11 或 14,或 C11 需要一条错误消息作为 static_assert
的第二个参数,尽管您可以将整个内容包装在一个宏中以便为您编写一个漂亮的字符串。
offsetof
宏也适用于 C。