2 ms·
So maybe everyone but me knows this, but what's the behavior of bitfields on the bus? Like, if r.x is the bottom 6 bits of a 32-bit register, then does the comp
by tripletao 8y ago
So maybe everyone but me knows this, but what's the behavior of bitfields on the bus? Like, if r.x is the bottom 6 bits of a 32-bit register, then does the compiler generate an 8-bit access or a 32-bit access?
What if it's bits 13 through 18? An unaligned 16-bit access? Two 8-bit? A 32-bit? Where is this specified?
Depending how your peripheral is implemented, this absolutely can matter. Nothing stops you from building devices where the low byte of
*((uint32_t *)x)
doesn't work like
*((uint8_t *)x)
and people do. I always just code the 32-bit access and pull the bits out myself, because I know what will happen.
This is even before considering stuff like a GPIO output implemented with two write-only registers, where 0 leaves the bit unchanged and 1 sets/clears it. The result of layering a bitfield on that does not seem intuitive to me.
The article also says that you should build abstraction layers for your peripherals, instead of making all your code write to registers everywhere. That seems (a) pretty well-settled as true, and (b) entirely independent of whether you do the register accesses with bitfields or explicit shifts and masks.
- JoachimSchipper 8y agoYes, what bitfields do on the bus is very undefined. Admittedly, a compiler is free to implement a dereference of uint32_t by loading four separate bytes, too, hence the imprecise "very undefined" in the first line...
- tripletao 8y agoI just tried this with IAR for Cortex-M3. I didn't check thoroughly, but so far it looks like right-aligned bitfields of eight bits or less generate an LDRB (8-bit). All other bitfields generate an LDR (32-bit), even if they lie entirely within a byte. I see the makings of a fun trick to play on a colleague. I don't see anything I'd be too inclined to use in production code.
- orbifold 8y agoThis is a problem I encountered just recently, even if your bus might in principle support byte wise access to memory, it might be the case that one of the custom devices on that bus simply ignore that feature, leading to surprising and unpredictable results.