I'm working on learning to TDD embedded C by creating an LED driver for an AVR.
In James Grenning's book, he recommends injecting the PORT by passing a pointer to the register into the function.
I came across the following code in the AvrLibc documentation, How do I pass an IO port as a parameter to a function?, and am confused as to why the *port
parameter is declared as volatile.
void set_bits_func_correct (volatile uint8_t *port, uint8_t mask) { *port |= mask; }
Can anyone explain why they're passing it as volatile? As someone who's a beginner with C, I'm confused and would appreciate an explanation (if there is one).
Best Answer
It's passed as volatile so the compiler doesn't optimize away any accesses to said parameter. This is required because a compiler may see something like this:
Or perhaps
Assuming that the ending state is all that matters, that can be optimized to
And
Saving on instructions, memory accesses, and code space. However, since
port
actually accesses physical resources, these reads and writes actually are significant and the compiler should be instructed that the programmer knows best here and the compiler should not remove any reads or writes so that the program will perform the intended operations.