How do I create a "spacer" in a C++ class memory structure? How do I create a "spacer" in a C++ class memory structure? c c

How do I create a "spacer" in a C++ class memory structure?


How about a C++-ish way?

namespace GPIO {static volatile uint32_t &MAP0_MODER = *reinterpret_cast<uint32_t*>(0x4000);static volatile uint32_t &MAP0_OTYPER = *reinterpret_cast<uint32_t*>(0x4004);}int main() {    GPIO::MAP0_MODER = 42;}

You get autocompletion because of the GPIO namespace, and there is no need for dummy padding. Even, it is more clear what's going on, as you can see the address of each register, you don't have to rely on the compiler's padding behavior at all.


Use multiple adjacent anonymous bitfields. So instead of:

    uint32_t :160;

for example, you'd have:

    uint32_t :32;    uint32_t :32;    uint32_t :32;    uint32_t :32;    uint32_t :32;

One for each register you want to be anonymous.

If you have large spaces to fill it may be clearer and less error prone to use macros to repeat the single 32 bit space. For example, given:

#define REPEAT_2(a) a a#define REPEAT_4(a) REPEAT_2(a) REPEAT_2(a)#define REPEAT_8(a) REPEAT_4(a) REPEAT_4(a)#define REPEAT_16(a) REPEAT_8(a) REPEAT_8(a)#define REPEAT_32(a) REPEAT_16(a) REPEAT_16(a)

Then a 1344 (42 * 32 bit) space can be added thus:

struct{    ...    REPEAT_32(uint32_t :32;)     REPEAT_8(uint32_t :32;)     REPEAT_2(uint32_t :32;)    ...};


In the embedded systems arena, you can model hardware either by using a structure or by defining pointers to the register addresses.

Modeling by structure is not recommended because the compiler is allowed to add padding between members for alignment purposes (although many compilers for embedded systems have a pragma for packing the structure).

Example:

uint16_t * const UART1 = (uint16_t *)(0x40000);const unsigned int UART_STATUS_OFFSET = 1U;const unsigned int UART_TRANSMIT_REGISTER = 2U;uint16_t * const UART1_STATUS_REGISTER = (UART1 + UART_STATUS_OFFSET);uint16_t * const UART1_TRANSMIT_REGISTER = (UART1 + UART_TRANSMIT_REGISTER);

You could also use the array notation:

uint16_t status = UART1[UART_STATUS_OFFSET];  

If you must use the structure, IMHO, the best method to skip addresses would be to define a member and not access it:

struct UART1{  uint16_t status;  uint16_t reserved1; // Transmit register  uint16_t receive_register;};

In one of our projects we have both constants and structs from different vendors (vendor 1 uses constants while vendor 2 uses structures).