The MUTEX peripheral uses mutual exclusion to support locking a resource that is shared between different CPUs in the system. The shared resource can only be used by one of these cores during the duration that it is locked.

The MUTEX peripheral includes several mutex registers. Each mutex register contains one bit which indicates if it is in a locked or unlocked state. Reading or writing to a mutex register may impact its state.

When a mutex is read, the following conditions apply:
  • If the state is locked, the MUTEX[i] state is unchanged (remains in a locked state) and reading the register will return '1'.
  • If the state is unlocked, the MUTEX[i] state changes to the locked state and reading the register will return '0'.
When writing '0' to a mutex, the following occurs:
  • If the state is unlocked, the MUTEX[i] state is unchanged (remains in unlocked state) and the store is ignored.
  • If the state is locked, the MUTEX[i] state changes to the unlocked state.
Note: Faults are not managed by the peripheral. If a mutex is locked and a fault occurs, it is the responsibility of the fault handler to release the mutex. If a fault handler is not managing the mutex release, the mutex will stay locked.

The following figure illustrates the mutex state transitions.

Figure 1. MUTEX - state transitions

Page-1 Dynamic connector.476 Writing ‘0’ to MUTEX[i] Writing ‘0’ to MUTEX[i] Dynamic connector Reading ‘0’ from MUTEX[i] Reading ‘0’ from MUTEX[i] Dynamic connector.470 Sheet.7 Unlocked state Unlocked state Sheet.8 Locked state Locked state Sheet.17 «Waiting for mutex» «Waiting for mutex» Sheet.19 «Releasing mutex» «Releasing mutex» Sheet.22 «Got mutex» «Got mutex» Sheet.25 Reading ‘1’ from MUTEX[i] Reading ‘1’ from MUTEX[i]

The following code is an example of how a mutex can be used by two different CPUs:


  // CPU0 Polling the MUTEX[0] register
  while (NRF_MUTEX->MUTEX[0]){ // Read MUTEX[0]
                               // If a 0 is read, the mutex will lock
                               // If a 1 is read, polling will continue
  }
  // CPU0 working on shared data related to the mutex
   ...
  NRF_MUTEX->MUTEX[0] = 0;  // Release the mutex
  

  // CPU1 Polling the MUTEX[0] register
  while (NRF_MUTEX->MUTEX[0]){ // Read MUTEX[0]
                               // If a 0 is read, the mutex will lock
                               // If a 1 is read, polling will continue
  }
  // CPU1 working on shared data related to the mutex
   ...
  NRF_MUTEX->MUTEX[0] = 0;  // Release the mutex
  

Only one CPU can access the mutex at a time, meaning the mutex must be released before being accessed by the another CPU. If the load operation occurs at the same time, a bus arbitration mechanism will ensure only one CPU gets the mutex.

Registers

Instances

Instance Domain Base address TrustZone Split access Description
Map Att DMA

MUTEX : S
MUTEX : NS

APPLICATION

0x50030000
0x40030000

US S NA No

Mutual exclusive hardware support

APPMUTEX : S
APPMUTEX : NS

NETWORK

0x50030000
0x40030000

US S NA No

Mutex control

Register overview

Register Offset TZ Description
MUTEX[n] 0x400

Mutex register

MUTEX[n] (n=0..15)

Address offset: 0x400 + (n × 0x4)

Mutex register

Bit number 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
ID A
Reset 0x00000000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ID R/W Field Value ID Value Description
A

RW

MUTEX

Mutex register n

Unlocked

0

Mutex n is in unlocked state

Locked

1

Mutex n is in locked state