Memory-mapped IO registers in zig (2021)
scattered-thoughts.net
scattered-thoughts.net
What you need is volatile read/write or load/store intrinsics. When you have those, you can express what's actually possible on a hardware platform, and not inadvertently enable people to write nonsense in your language - no need to even have a footgun here, let alone leave it loaded on the table for a newbie to pick it up and blow their whole leg off.
Although it was eventually un-deprecated in C++ 23, one of the smaller useful accomplishments in C++ 20 was to deprecate the inappropriate use of composite operators on volatile, which is the sort of nonsense entertained by having a keyword instead of intrinsics. When the newbie in your team writes irq_flags |= new they think they're performing a single operation, after all |= isn't two operations, it's just one. You, hopefully, know that's untrue - the irq_flags were marked volatile, so that's decomposed into a separate load and store -- but are you sure you'll notice they screwed this up? Or will you only realise when customers report sometimes IRQ flags "go missing" under load?
Are volatile variables used for atomic memory access semantic ?
I wish!
More likely customers would report that it's "not working properly".
(I mean, not that it's their responsibility to know why it's not working properly).
Atomicity is sort of a different thing. You might need things like critical sections (disable interrupts) or memory fencing for the read-modify-write cycle.
Linus recently said something similar in a memory model discussion on LKML (long thread, only Linus's posts are really relevant here) https://lore.kernel.org/lkml/CAHk-=whmmeU_r_o+sPMcr7tPr-EU+H...
However, under the hood, Nim compiles to C. So these are macros that typecast to volatile, does the read (or write), then casts back to non-volatile.
(Small plug for my nim project that is somewhat related to OP: https://github.com/EmbeddedNim/svd2nim)
Seems to me that you want to keep the keyword but give a warning or suppressible error if it’s not accessed through volatileRead/Write intrinsics. (Hobby/hacking level development of embedded software if every other line was a volatileRead/Write call, but good to enforce in professional software development)
We're not trying here to prevent malevolent actors from causing trouble or trying to entirely prevent foot shooting here, only to require that weapons capable of targeting your own feet are kept separate from the ammunition in a locked cabinet, so that the newbie will ask, "Hey, I need to get in the locked cabinet so I can write a composite assignment on an MMIO register" and that's your chance to explain why this doesn't do what they expected and what they should write instead.