3 ms·
> Unfortunately, a lot of embedded low-level libraries deal with registers this way: *(volatile std::uint32_t*)reg_name = val; Who still writes code like
by AceJohnny2 8y ago
> Unfortunately, a lot of embedded low-level libraries deal with registers this way:
*(volatile std::uint32_t*)reg_name = val;
Who still writes code like this!? (maybe the ST folks responsible for the CubeMX BSP for STM32. Ugh...) Most places have finally moved on to using structs and bitfields. GCC and Clang support them well and consistently on the various architectures I've worked on (MIPS, some weird DSP, and a slew of ARM variations).
Some proper C code will define the 32-bit register like this (usually in a header provided by the hardware vendor, generated from the HDL):
typedef union some_reg {
uint32_t raw;
struct {
uint32_t bits1:4;
uint32_t bits2:3;
uint32_t rsvd:5;
uint32_t bits2:20;
}
} some_reg_t;
Then use it either like:
some_reg_t reg;
reg->raw = READ_REG(reg_addr);
reg->bits1 = 4;
WRITE_REG(reg_addr, reg->raw);
Or:
volatile some_reg_t *reg = (some_reg_t*)reg_addr;
reg->bits1 = 4;
The latter assumes the register address is mappable, and that programmers are aware that writing the field performs a Read-Modify-Write of the whole register. Programmers being fallible, it's a more risky approach that I don't see often, despite how concise it is.
- kbumsik 8y ago> Who still writes code like this!? Believe or not, a majority number of ARM MCU vendors does that with CMSIS headers in my experience (ST, TI, NXP, Nordic, EFM32...). To be more precise, the registers are accessed using mask and shift macros. I've work on many ARMs too but only Atmel's header files use struct bitfield you mentioned. But yeah, I've also seen that most of non-ARM vendors use struct bitfield.
- AceJohnny2 8y agoHm, is armcc still a thing? I don't remember what it guaranteed (or not) for bitfields. If it doesn't work consistently, that would explain that they're using masks and shifts. That, and because the C standard leaves it implementation-defined.
- monocasa 8y agoThe ARM ABI defines a lot of useful semantics for bitfields (particularly when combined with volatile), but GCC perennially regresses and breaks them so next to no one uses them.
- deleted 8y ago[deleted]
- Khoth 8y agoDoesn't the latter also risk the compiler deciding to emit a store of less than a whole word and the hardware then ignoring it or throwing a hissy fit in some unexpected way?