Search topics...
GPIOAtomic Operationsfoundational

Why should you use the BSRR register instead of directly writing to ODR for atomic pin manipulation?

0 upvotes
Practice with AISoon
Study the fundamentals first — GPIO topic page

The Output Data Register (ODR) represents the current output state of all 16 pins in a GPIO port as a 16-bit value. To change a single pin via ODR, firmware must perform a read-modify-write (RMW) sequence: read the entire register, modify the target bit using AND/OR masking, and write the result back. This three-step operation is not atomic — if an interrupt fires between the read and the write, and the ISR modifies a different pin in the same port through ODR, the ISR's change is silently overwritten when the interrupted code completes its write. This is a classic race condition that produces intermittent, hard-to-reproduce bugs.

The Bit Set/Reset Register (BSRR) eliminates this problem entirely. It is a 32-bit write-only register: the lower 16 bits set individual pins (writing 1 to bit N drives pin N high), and the upper 16 bits reset individual pins (writing 1 to bit N+16 drives pin N low). Writing 0 to any bit has no effect. Because a single write to BSRR atomically modifies only the specified pins without reading or affecting any other pins, no read-modify-write is needed, and there is no window for a race condition. The operation completes in a single bus cycle.

This makes BSRR the correct choice whenever GPIO pins are manipulated from multiple execution contexts — main loop, ISRs, or RTOS tasks. Even if you believe only one context touches a port, using BSRR is a defensive habit that costs nothing and prevents future bugs when code evolves. The HAL functions HAL_GPIO_WritePin() and HAL_GPIO_TogglePin() use BSRR internally for this reason. Note that toggling via BSRR still requires a read of ODR to determine the current state, so HAL_GPIO_TogglePin() is not fully atomic — if atomicity is critical for a toggle, disable interrupts briefly or use the dedicated toggle register (available on some newer STM32 families).

Source: GPIO Q&A