SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: What is PRIMASK?
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

What is PRIMASK?

Elijah Erickson
Last updated: September 9, 2023 9:09 am
Elijah Erickson 5 Min Read
Share
SHARE

PRIMASK stands for “Priority Mask” and is a register in ARM Cortex-M processors that is used to disable and enable interrupts globally. Setting PRIMASK to 1 will disable interrupts, while clearing PRIMASK to 0 will enable interrupts.

Contents
Purpose of PRIMASKHow PRIMASK WorksUsing PRIMASK in FirmwareRelationship to BASEPRIPRIMASK in Multicore SystemsConclusion

Purpose of PRIMASK

The main purpose of PRIMASK is to allow critical sections of code to run atomically without being interrupted. This prevents race conditions and guarantees predictable execution. PRIMASK allows developers to disable and enable interrupts very quickly with low overhead.

Some common uses cases for PRIMASK include:

  • Disabling interrupts during read-modify-write operations on shared data structures like queues or buffers.
  • Preventing preemption during multi-step operations like erasing flash memory.
  • Protecting access to shared hardware resources.
  • Implementing mutexes or critical sections.

How PRIMASK Works

PRIMASK is a single bit register that is accessed using special register access instructions in the ARM Thumb instruction set. There are two key instructions:

  • CPSID i – Set PRIMASK = 1 to disable interrupts.
  • CPSIE i – Clear PRIMASK = 0 to enable interrupts.

Setting PRIMASK to 1 prevents all exceptions with configurable priority from activating, including SysTick, PendSV, and external interrupts. However, exceptions like HardFault, NMI, and Reset will still trigger even with PRIMASK = 1.

The PRIMASK bit works together with the FIXED_PRI_THREADS setting in the CORTEX_A and CORTEX_R Application Program Status Register (APSR). This setting reserves the highest priority levels for operating system use. With PRIMASK = 1, even privileged threads are prevented from preempting the current thread.

Using PRIMASK in Firmware

Here is some example firmware code using PRIMASK to implement a critical section:


// Globally accessible data 
uint32_t sharedData;

void criticalFunc(void) {

  // Disable interrupts  
  __asm volatile ("cpsid i");

  // Access shared data
  sharedData++;

  // Enable interrupts
  __asm volatile ("cpsie i");

}

The inline assembly cpsid i and cpsie i instructions set and clear PRIMASK atomically. This guarantees the code between them will run to completion uninterrupted.

PRIMASK can also be used to implement mutexes:


// Mutex implementation
uint32_t mutex = 0; 

void lockMutex(void) {

  // Spin until mutex unlocked
  while (__LDREXW(&mutex) == 1) {};

  // Set mutex
  __DMB();
  mutex = 1;

}

void unlockMutex(void) {

  // Clear mutex
  __DMB();
  mutex = 0;

}

The LDREX and STREX instructions implement an atomic read-modify-write on the mutex variable. PRIMASK prevents preemption during the lock acquisition spin.

Relationship to BASEPRI

ARM Cortex-M processors also contain a BASEPRI register that allows selective priority based interrupt disabling. BASEPRI prevents exceptions below a configurable priority level, while PRIMASK disables all exceptions.

BASEPRI is generally preferred over PRIMASK:

  • BASEPRI disables only lower priority interrupts, PRIMASK disables all interrupts.
  • BASEPRI still allows useful interrupts like SysTick during critical sections.
  • BASEPRI requires less inline assembly and is easier to read and audit.

However, PRIMASK has lower overhead than BASEPRI, so can be useful in particularly latency sensitive code blocks. PRIMASK also disables all exceptions, including NMI, Reset, and HardFault, which BASEPRI does not.

PRIMASK in Multicore Systems

In multicore Cortex-M systems, PRIMASK is local to each core. So disabling interrupts on one core does not affect other cores. This allows flexibility in managing critical sections across cores.

Typically shared data structures will use spinlocks or mutexes to synchronize access between cores. The spinlock acquire and release routines are good candidates for using PRIMASK to prevent preemption on each core.

Conclusion

In summary, PRIMASK is a simple but powerful register for disabling interrupts globally in Cortex-M processors. It enables low overhead critical sections and atomic read-modify-write operations on shared data structures. While BASEPRI is generally preferred, PRIMASK has its uses in latency sensitive contexts and for disabling all exceptions.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article What is the difference between fault mask and Primask?
Next Article What are the features of STM32F407?
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

What architectural features of Cortex-M3 make it a low power device?

The Cortex-M3 processor from ARM is designed to be an…

7 Min Read

Relocate the Vector Table in Cortex-M0

The vector table is a key component in Cortex-M0 microcontrollers…

9 Min Read

What is the Application Program Status Register (APSR) in Arm Cortex-M?

The Application Program Status Register (APSR) in Arm Cortex-M is…

9 Min Read

The History of ARM’s Cortex-M Series

ARM's Cortex-M series of processor cores has become ubiquitous in…

6 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account