SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Saving and Restoring Task Context on Cortex-M
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

Saving and Restoring Task Context on Cortex-M

Graham Kruk
Last updated: October 5, 2023 9:20 am
Graham Kruk 7 Min Read
Share
SHARE

When working with preemptive multitasking on Cortex-M microcontrollers, it is often necessary to save and restore the context of a task when switching between tasks. The context includes the values of the CPU registers, stack pointer, and other key state information that must be preserved when transitioning between tasks.

Contents
What is Task Context?Saving Task ContextRestoring Task ContextContext Switching ExampleUsing PendSV for Context SwitchingWhat Code Runs During Context Switch?Minimizing Context Switch TimeContext Switching in Popular RTOSesConclusion

What is Task Context?

The task context consists of all the CPU, stack, and other hardware resources that are unique to a particular task. This includes:

  • General purpose CPU register values (R0-R12)
  • Stack pointer (SP)
  • Link register (LR)
  • Program counter (PC)
  • Priority mask registers
  • Control and status registers (xPSR, EPSR)
  • Stack memory for local variables

When a task is interrupted or paused to allow another task to run, the entire task context must be preserved. Then when the original task is resumed, the context is restored so it can pick up right where it left off.

Saving Task Context

On Cortex-M devices, the processor automatically handles most of the context saving when an interrupt or exception occurs. This includes pushing the general purpose registers, LR, PC, and xPSR onto the current stack.

To fully save a task’s context when manually switching tasks, the following steps should be taken in the scheduler or RTOS:

  1. Save remaining system registers not automatically saved by the processor (control, status, stack pointer, priority masks, etc.)
  2. Store stack pointer so the task’s stack can be restored later
  3. Update scheduler state to mark the task as inactive/waiting

The RTOS kernel will provide special functions or macros to make this easy. For example, saving the stack pointer can be done by reading the current value of the SP register and storing it in the task control block (TCB) structure for that task.

Restoring Task Context

Later, when the scheduler switches back to the original task, the context must be fully restored before the task resumes. This process happens in reverse:

  1. Mark the task as active/ready to run in scheduler state
  2. Load stack pointer from stored value in TCB
  3. Restore system registers not handled automatically by CPU

With the stack pointer restored, the general purpose registers, LR, PC, xPSR will automatically be popped off the stack by the processor when the first instruction of the task executes.

Context Switching Example

Here is some example pseudocode to demonstrate manually saving/restoring task context when switching between two hypothetical tasks Task1 and Task2: // Inside Scheduler // Save Context of Task1 Store SP of Task1 Mark Task1 as Inactive // Restore Context of Task2 Mark Task2 as Active Load SP of Task2 // Context restore triggers CPU to pop registers on first instruction // Task2 executes… // Eventually Task2 does something to make it wait // Scheduler executes again… // Save Context of Task2 Store SP of Task2 Mark Task2 as Inactive // Restore Context of Task1 Mark Task1 as Active Load SP of Task1 // Context restore triggers CPU to pop registers on first instruction // Task1 resumes…

Using PendSV for Context Switching

The Cortex-M processor includes the PendSV interrupt that can be used to trigger context switches in a RTOS. When PendSV executes, the system will automatically save the context of the current task.

The PendSV handler can then be used to store task states, select the next task to run, and restore its context by loading its stack pointer. Setting the PENDSVSET bit in the ICSR register pends the PendSV interrupt which starts the context switch process.

What Code Runs During Context Switch?

The context switch code depends on the specific RTOS being used. But in general, the following operations have to be performed:

  • Save remaining context of current task (system regs, stack ptr)
  • Update scheduler task states
  • Select next task to run
  • Restore context of next task (load stack ptr, system regs)
  • Modify stack to unlink current task
  • Modify stack to link next task

This often happens inside the PendSV interrupt handler when using that for context switching. The scheduler hooks into PendSV through a special registration function.

Minimizing Context Switch Time

To make a RTOS as efficient as possible, context switches must be kept as fast as possible. Here are some techniques used on Cortex-M devices:

  • Use a fixed-size stack for each task to allow faster context saves
  • Store stack pointers in CPU registers instead of memory
  • Use a separate stack pointer for handling interrupts
  • Nest interrupt priorities to avoid overhead
  • Store task states compactly using bitmasks
  • Optimize PendSV handler to minimize execution time

By carefully managing the context switching process, interrupt latency and the overall responsiveness of a RTOS system can be greatly improved on Cortex-M microcontrollers.

Context Switching in Popular RTOSes

Most popular RTOSes and real-time frameworks provide efficient context switching on Cortex-M devices. A few examples:

  • FreeRTOS: Uses PendSV for context switch, fixed stack size, stores TCB in CPU registers.
  • STM32Cube: Uses SVC handler with PendSV, maintains stack in MSP register.
  • Mbed: Switches context in PendSV, keeps stack pointer in psp register.
  • Zephyr: Each thread has separate kernel stack, uses fiber registers for context.
  • ChibiOS: Uses VTOR to optimize PendSV handler, stores contexts in RAM.

So context switching should be well optimized by using any major RTOS. Focus on configuring task stack sizes, priorities, and writing efficient code.

Conclusion

Managing task contexts is a key responsibility of the scheduler and RTOS kernel. By properly saving and restoring CPU registers, stack pointers, and other hardware resources during a context switch, multiple tasks can share the MCU as if each had the entire system to itself. Using features like PendSV and keeping switch overhead to a minimum helps enable effective multitasking on Cortex-M platforms.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Context Switching on the Cortex-M3
Next Article Cortex-M Exception Handling and Return Mechanism
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

Invalid ROM Table Errors with Cortex-M1 and ULINK2

Seeing "Invalid ROM Table" errors when trying to debug Cortex-M1…

7 Min Read

FreeRTOS Context Switch

A context switch is a fundamental part of multitasking real-time…

5 Min Read

Cortex-M3 Memory Access Constraints with Caches and Shared Memory

The Cortex-M3 processor has advanced memory access capabilities through the…

6 Min Read

Why is there rotate right but not rotate left instruction in cortex m3?

The Cortex-M3 processor implements the ARM Thumb-2 instruction set architecture,…

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

Sign in to your account