Search code examples
assemblyarmatomicmulticorecortex-m

How to implement atomic operation(s) on multi-core Cortex-M0/M0+ (no SWP, no LDREX/STREX)?


Pre ARMv6 MPUs/MCUs have SWP instruction (e.g. good ole and still alive ARM7TDMI). In ARMv6 architecture LDREX/STREX pair has been introduced and SWP removed. However with one exception – ARMv6-M (Cortex-M0/M0+) has neither LDREX/STREX nor SWP. Strange.

So how to implement atomic operations/synchronization primitives on this platform? In the old-fashioned way using "enable interrupts"/"disable interrupts"? Or am I missing something? E.g. ChromiumOS uses the old-fashioned method.

Disabling interrupts will work on single-core MCUs, but what about multi-core MCUs? Will this method work e.g. on a RP2040 (dual-core Cortex-M0+, the heart of Raspberry Pi Pico)?


Solution

  • The unfortunate answer to this question is: you don't. Atomic read/modify/write operations are not possible on the ARM Cortex-M0/M0+. If you need such functionality, you'll have to rely on special purpose hardware.

    For example, the RP2040 provides special memory regions for atomic RMW operations on peripherals. It also provides a special spin lock peripheral for synchronisation between the two cores as well as hardware FIFOs for inter-core communication. All of this is needed as the Cortex-M0+ core does not provide any atomic memory operations on its own.