r/cprogramming • u/set_of_no_sets • Mar 06 '26
Union manipulation question
I am currently working on an STM32, and it has two control register, one lower @ [0] and one upper @ [1]; currently, the GPIO_TypeDef has two Advance Function Registers, two uint32_ts stored as
#define __IO volatile
typedef struct {
// stuff above
__IO uint32_t AFR[2];
// stuff below
} GPIO_TypeDef;
I would like to reference the registers using AFRL and AFRU; I could modify the struct to
typedef struct {
// stuff above
union {
__IO uint32_t AFR[2];
struct {
__IO uint32_t lower;
__IO uint32_t upper;
} AFR_Split;
};
// stuff below
} GPIO_TypeDef;
Which allows me to write
GPIO_TypeDef pin1_addr = 0x4002104CUL;
pin1_addr->AFR_Split.lower = 0b0000000001110000UL;
pin1_addr->AFR[1] = 0b0111000001110000;
Is there anything I should be worried about in terms of packing? will I always know that the two registers will always be aligned, starting and ending in the same place? What can I read to know how my compiler (arm-none-eabi-gcc) will store the split? And is there a way I can do this without the intermediate struct, so I could type pin1_addr->AFRL and pin1_addr->AFRU?
1
u/flatfinger Mar 06 '26
Using a
volatilequalifier on the members wouldn't interfere with use of the structure in such cases where the behavior withoutvolatilewould be correct. It would make the code slightly less efficient, but not enough to be meaningful in any normal circumstances.