1

我正在使用 C++ 为一块内存映射硬件开发一个驱动程序,并且我定义了一个代表这个设备的类。它看起来像这样:

class device
{
method1();
method2();

private:
device_register reg1;
device_register reg2;

}

该类有两个文件:device.cpp 和 device.h。成员变量代表设备本身的实际寄存器。现在我想在设备本身上定义更多不是实际寄存器的成员,但我不能在类中定义它们,因为如果我这样做,它们将在设备的内存映射位置定义,该位置可能包含其他设备/寄存器. 如果我将它们定义为公共的,这会破坏标准布局并且该类将不再起作用。

所以我所做的就是将它们定义为类定义之外的全局变量。问题是如果我定义了多个对象,它们都会共享这些全局变量,但我希望每个对象都有自己的,我该怎么做呢?

4

2 回答 2

3

也许您可以使用带有指向当前“设备”的指针的单独类


class device_glob {

private :
  device * mmaped_device;
  int other_attrib;
};

您可能可以在 ctor 中的映射位置分配设备。然后您需要将其集成到您用于获取当前设备的引用/指针的任何注册表系统中。

于 2021-08-06T20:27:23.387 回答
1

您应该为寄存器创建一个单独的 POD(普通旧数据)结构,因为即使不添加额外的数据成员,非 POD 类/结构也可能破坏您的内存映射。在 POD 类型中,第一个数据成员的偏移量保证为 0,这是您需要的。在非 POD 类型中,并不总是遵循此合同,例如,它可能会被 vtables 或 RTTI 破坏。诚然,您可以尽职尽责地避免只会更改第一个数据成员的偏移量的更改,但更强大的解决方案是坚持所有 POD 要求,以便标准要求您的编译器执行您想要的操作。

POD 类型的要求可以在此处的 cppreference 中找到,但一个简单的助记符是,除了本机类型成员之外什么都没有的结构将始终是 POD。

您还应该确保寄存器被标记为“volatile”,尽管我有一种预感,如果您已经有一个特殊的“device_register” typedef,它包含一个 volatile 说明符。在这种情况下,您不需要在自己的结构中额外添加一个。

例子:

struct MyPeripheralRegisters
{
volatile device_register reg1;
volatile device_register reg2;
};

class MyPeripheralDriver
{
private:
  MyPeripheralRegisters* hardware = MY_MEMORY_MAPPED_ADDR;
  int my_private_state;
public:
  void method1();
  void method2();
};

这种内存映射组件的模式通常用于嵌入式驱动程序库中,因此它具有最小惊讶原则。

于 2021-08-06T21:17:36.350 回答