On the GPIOs of some ARM-based microcontrollers, you are given a register BSRR which you can write to to perform atomic changes in a ports output register.

For example, to set Port A Bit 5 to a 1 you simply do GPIOA->BSRR = (1<<5)

This alleviates the problem of atomicity so you do not have to perform a read-modify-write sequence. Without the BSRR you would have to do GPIOA->ODR |= (1<<5).

How does the BSRR register work under the hood? Does it clear itself so that the next time you want to set a bit there isn't the previous bit still lying around.

If i wanted to set bit 2 and later on set bit 6 i can do first GPIOA->BSRR = (1<<2) and then later on do GPIOA->BSRR = (1<<6) but won't bit 2 still be set from my previous call?

  • \$\begingroup\$ GPIO (and whatever IO) is not a part of ARM architecture, but a part of the specific microcontroller which might be built around ARM core. \$\endgroup\$ – Eugene Sh. Dec 5 '17 at 22:08
  • \$\begingroup\$ @EugeneSh. but all modern ARM cores have the BSRR register so it makes more sense to ask about the ARM \$\endgroup\$ – Taako Dec 5 '17 at 22:16
  • 2
    \$\begingroup\$ @Taako that's implementation defined. The STM32 GPIOs have a BSRR register, but NXP's LPC4350 range of cortex M4s don't. The ARM is just the CPU, the rest of the peripheral implementation is vendor defined. \$\endgroup\$ – Colin Dec 6 '17 at 9:13
  • \$\begingroup\$ @Colin__s I was not aware that the BSRR was only available in STM32. Thanks for the clarification! \$\endgroup\$ – Taako Dec 6 '17 at 17:42

There is a sort of read-modify-write but it is done in logic/hardware without any time between the read and the write. The statement in Verilog would be:

GPIOA <= GPIOA | cpu_write_data;

This generates logic where there is an OR gate before the register and the new data is OR-ed with the old data and stored in the register. The data bits which you write and which are SET (high) will create a 1 at those locations only. All bit which you write which are clear (low) will remain unchanged. If the bit was set it remains set, if the bit was clear it remains clear.


simulate this circuit – Schematic created using CircuitLab

Equivalent you can clear bits by using:

GPIOA <= GPIOA & ~cpu_write_data;

The data bits which you write and which are SET (high) will create a 0 at those locations only. All other bits remain unchanged.

It gets a bit more complex to have all these bit-set and bit-clear operations implemented in parallel on the same register but that is just a matter of more logic (multiplexers, address decoders etc.)

  • \$\begingroup\$ Makes a lot of sense! But does the register only assert logic 1 for once cycle so the bit set/reset doesn't stick around after it performs the action? \$\endgroup\$ – Taako Dec 5 '17 at 22:19
  • \$\begingroup\$ The circuit is an example. I reality you would have either an enable on the register or a gated clock or a feed-back MUX. In all cases those are only active during the one clock cycle that the CPU writes the data to that register. Thus outside that time the register remains unmodified. \$\endgroup\$ – Oldfart Dec 5 '17 at 22:22
  • \$\begingroup\$ cool, great explanation! \$\endgroup\$ – Taako Dec 5 '17 at 22:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.