Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gpio: stm32: Use atomic set/reset in stm32_gpio_set()
The current implementation of stm32_gpio_set() uses the GPIO output data register to change the state of individual GPIOs. The generated assembler needs at least 3 instructions: load / modify / store. This opens a small race window, for example if a thread and an interrupt both try to change the state of the same GPIO bank. Use the GPIO bit set/reset register to perform the atomic change without locking. This also has the benefit of a more optimised implementation, which can be useful for GPIO-intensive work. Compare the new version: 08000c98 <stm32_gpio_set>: 8000c98: f001 010f and.w r1, r1, #15 8000c9c: 2301 movs r3, #1 8000c9e: b902 cbnz r2, 8000ca2 <stm32_gpio_set+0xa> 8000ca0: 3110 adds r1, #16 8000ca2: 408b lsls r3, r1 8000ca4: 6183 str r3, [r0, #24] 8000ca6: 2000 movs r0, #0 8000ca8: 4770 bx lr and the old one: 08000c98 <stm32_gpio_set>: 8000c98: 2301 movs r3, #1 8000c9a: f001 010f and.w r1, r1, #15 8000c9e: fa03 f101 lsl.w r1, r3, r1 8000ca2: 6943 ldr r3, [r0, #20] 8000ca4: b10a cbz r2, 8000caa <stm32_gpio_set+0x12> 8000ca6: 4319 orrs r1, r3 8000ca8: e001 b.n 8000cae <stm32_gpio_set+0x16> 8000caa: ea23 0101 bic.w r1, r3, r1 8000cae: 6141 str r1, [r0, #20] 8000cb0: 2000 movs r0, #0 8000cb2: 4770 bx lr Change-Id: Ie5800d1c345016028d1b9a099f5d74cac35f592a Signed-off-by: Florian Vaussard <[email protected]>
- Loading branch information