问题描述
我有一个指向存储空间void *pAddr
的全局基址指针。在某些方法中,我将该指针转换为很少的结构,以具有更好的访问内存的方法。
class MyClass {
private:
struct MapMem {
uint8_t dummy1;
uint64_t dummy12;
};
void* pAddr;
MapMem* representationPointer;
void myMethod();
}
voidmyMethod() {
representationPointer = static_cast<volatile MapMem*>(pAddr);
/* Doing something with representationPointer */
}
由于pAddr
是对我的驱动程序执行IO内存映射的mmap()调用的结果。
因为我只需要按8/16/32/64位访问寄存器,所以我需要使用volatile
。
我需要避免使用pAddr
或指向该地址的所有其他指针对所有内存访问进行优化。
- 我应该在哪里设置
volatile
关键字?
在所有指向pAddr
或仅指向pAddr
的结构/数据类型上?
解决方法
volatile
告诉编译器,而不是所生成的代码可能已更新了指向内容的其他内容。这就是为什么每当某些HW寄存器上指针的地址点(其内容可能由HW更新而不依赖于代码执行)时都需要volatile
的原因。
volatile struct MapMem *representationPointer = static_cast<struct MapMem *>(pAddr);
应该足够了。
,由于您的mmap
地址指向MMIO,因此应将其存储在指向volatile
的指针中。即
volatile void* pAddr;
然后,当您需要将此地址解释为指向MapMem
的指针时,应进行适当的强制转换。如果您尝试执行static_cast<MapMem*>(pAddr)
,则会出现编译错误:例如GCC会告诉您,演员阵容会丢掉预选赛。正确的是:您的结构仍然是MMIO空间中的结构,因此它应该是易变的。因此您的演员表应该像
auto representationPointer = static_cast<volatile MapMem*>(pAddr);
现在,您可以使用representationPointer
作为HW寄存器来处理结构字段了。