C Programming Basics
#define GPIO_BASE 0x40020000u
volatile uint32_t *const odr =
(volatile uint32_t *)(GPIO_BASE + 0x14);
*odr |= 1u << 5;A microcontroller output register is declared and used as above. Which of the following correctly describes this declaration?
- AThe value of *odr cannot be modified, while odr itself may be changed by interrupts, so it is read again every time it is used
- BBecause volatile is added, the read-modify-write of *odr |= 1u << 5 becomes a single operation that cannot be interrupted
- CThe address odr points to cannot be changed, and reads and writes through odr are not removed but performed exactly as many times as written
Show answer and explanation
Answer: C. The address odr points to cannot be changed, and reads and writes through odr are not removed but performed exactly as many times as written
const is to the right of *, so the pointer odr itself cannot be changed and always points to the same register address. The uint32_t it points to is volatile, so the compiler does not remove or merge reads and writes of *odr, and performs as many accesses as written. However, volatile does not make operations atomic, so an interrupt can occur between the read and the write of *odr |= …. When the same register is also manipulated by an interrupt handler, disable interrupts for the duration or use a dedicated bit-set register.
- A. This reads the targets of const and volatile the other way round. const applies to the pointer itself and volatile to what it points to.
- B. volatile only keeps accesses from being removed; it does not make the sequence from read to write atomic.
- C. Correct. The pointer itself is const, and the register it points to is volatile.