Search code examples
c++volatile

Is volatile needed only once or on each derived pointers from a MMIO mmap'd address pointer?


I have a global base pointer to a memory space void *pAddr. In some methods, I cast that pointer to few structures to have a better way to access the memory.

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 */
}

Since the pAddr is the result of a mmap() call to my driver doing an IO memory mapping.

Because I need to access the registers by 8/16/32/64bits exclusively, I need to use volatile. I need to avoid optimization to all the memory access using pAddr or all the other pointers pointing to that address.

  • Where should I set the volatile keyword?

On all the structures/data types that point to the pAddr or only to the pAddr?


Solution

  • Since your mmapped address points to MMIO, it should be stored in a pointer-to-volatile variable. I.e.,

    volatile void* pAddr;
    

    Then, when you need to interpret this address as a pointer to MapMem, you should do the appropriate cast. If you try doing static_cast<MapMem*>(pAddr), you'll get compilation error: e.g. GCC will tell you that the cast casts away qualifiers. And rightly so: your structure is still a structure in MMIO space, so it should be volatile. So your cast should look like

    auto representationPointer = static_cast<volatile MapMem*>(pAddr);
    

    Now you can use your representationPointer to work with the structure fields as HW registers.