【问题标题】:address of member structure in map file?地图文件中成员结构的地址?
【发布时间】:2017-11-09 13:09:21
【问题描述】:

已经有关于这个话题的问题(特别是How to get address of some struct member in array of structures)。

我的问题如下: 当我们使用struct来描述一个硬件设备时,那么每个结构体成员都会对应硬件设备的一些寄存器——我们如何保证结构体的每个成员都正确映射到硬件的每个寄存器上呢?

编译器的 ABI 规定了成员的对齐方式,用户也可能犯一些错误 - 确保映射正确完成的唯一方法是在运行时检查。 映射文件(至少对于 GNU ld)没有提供关于结构成员位置的任何线索。

是否有办法在编译器或链接时知道每个结构成员所在的位置?

【问题讨论】:

  • 你是对的,这在便携方式中是不可能的。您将不得不依赖特定编译器的扩展和/或行为
  • 这是系统特定的。如果您将代码移动到完全不同类型的计算机上,硬件设备将不存在。
  • 绝对同意,这取决于(cpu,编译器)。但即使使用相同的 cpu 和相同的编译器,我想确保映射没有错误 - 我正在寻找一种可以通过 Map 文件向我显示结构成员的映射的方法。但似乎唯一的方法是让一段代码在运行时显示这些地址。
  • C 不是 C++ 不是 C,请选择您当前使用的语言
  • C 和 C++ 都可以使用 - 这取决于我正在从事的项目。通过结构描述硬件设备是我们项目中的常见做法。

标签: c++ c linker hardware ld


【解决方案1】:

您可以在 C++ 中将offsetof 与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 语言。

【讨论】:

  • 感谢您提示我检查,我不知道。
猜你喜欢
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多