As we are aware, embedded firmware is the software that powers a wide range of devices, from simple home appliances to complex industrial machinery. Often these electronics devices need to respond immediately to certain events. To achieve this, firmware leverages the concept of interrupts, which are signals that alert the microcontroller to an event or condition that requires immediate attention. Interrupts are a fundamental mechanism in embedded systems, enabling efficient and responsive control of hardware resources.
While our earlier blogs covered handling interrupts in different types of MCUs/MPUs, in this article we will understand different applications of interrupts is basic RTOS based firmware and cover one particular use case of interrupts – performing context switch.
Applications of interrupts in embedded firmware
Interrupts have a wide range of applications in embedded firmware, and their use can significantly enhance the efficiency and responsiveness of embedded systems. Some common applications of interrupts include:
- Peripheral Interaction: Interrupts are often used to handle events from peripheral devices, such as sensors, communication interfaces, or timers. This allows the microcontroller to respond quickly to changes in the external environment without having to constantly poll the peripherals.
- Timing and Synchronization: Interrupts can be used to trigger time-critical events, such as the execution of a control loop or the generation of a precise timing signal. This is particularly important in real-time systems where timing accuracy is crucial.
- Error Handling: Interrupts can be used to detect and respond to error conditions, such as hardware faults or communication errors. This allows the embedded system to take appropriate action and maintain a stable and reliable operation.
- Power Management: Interrupts can be used to wake up a microcontroller from a low-power sleep mode, allowing the system to conserve energy when it's not actively performing tasks.
- Context Switching: Interrupts allow the microcontroller to pause its current execution, handle the interrupt, and then seamlessly resume the original task. This capability is crucial for ensuring the real-time responsiveness and performance of embedded systems.
Context switching in RTOS based embedded systems
In the world of RTOS, context switching is a critical process that allows multiple tasks or threads to share the limited resources of a microcontroller. There might be many tasks or execution contexts running in the firmware each performing a particular functionality as designed. When a task voluntarily or involuntarily relinquishes control of the CPU, context switching is performed. In this case, the CPU saves the current state of the system executing this task, known as the 'context', typically in a stack and then loads the context of the next task and starts executing that task. The same is captured in the below picture.

Context switching in RTOS based embedded systems
By this mechanism, each of the tasks are provided with an impression that they own the CPU but in fact they are sharing the CPU in a time sliced model.
Efficient context switching is essential for maintaining the responsiveness and reliability of embedded systems. If the context switching process is not well-designed, it can lead to delays, data corruption, or even system crashes, which can have serious consequences in mission-critical applications. While there are different mechanisms to achieve this, one of the most common ways is to leverage a dedicated interrupt to perform context switching. Let us see how this is handled in FreeRTOS for Renesas RH850 MCU, though the concept remains same for different RTOSes and MCUs.
Overview of FreeRTOS RTOS
One of the most widely used real-time operating systems (RTOS) in the embedded firmware world is FreeRTOS. Currently owned by Amazon, FreeRTOS is a lightweight, open-source RTOS that provides a robust and scalable platform for developing embedded systems. It offers a range of features, including task management, inter-task communication, and, most importantly, seamless context switching.
Supporting 40+ processor architectures with a small memory footprint, fast execution times, and cutting-edge RTOS features and libraries including Symmetric Multiprocessing (SMP), it is offered under friendly MIT licensing.
Using interrupts for context switching in FreeRTOS
FreeRTOS leverages interrupt to facilitate efficient context switching between tasks. When an interrupt occurs, FreeRTOS saves the current task's context and switches to the appropriate interrupt service routine (ISR) to handle the event. After the ISR has completed, FreeRTOS restores the highest priority ready-to-run task's context and resumes its execution.
In case a task that is running wants to relinquish the CPU, it voluntarily calls a MACRO called portYIELD to switch. This macro typically triggers a software interrupt that calls an Interrupt Service Routine (ISR) function called vPortYield. In this function, the executing task’s context is stored in memory, the next task to be executed is identified based on the priority and loaded on the context and returned from the ISR. In this way, the context switches from a running task to the next ready-to-run task.
Context switching in Renesas RH850 microcontroller
To illustrate the use of interrupts for context switching, let's consider the Renesas RH850 microcontroller for GHS compiler, a popular choice for automotive embedded systems. The MACRO to trigger context switching is as follows:
#define portYIELD() __asm('trap 0')
As can be seen, it is essentially a software interrupt triggering TRAP 0. We have seen in the earlier blog on RH850 interrupt handling, the ISR for this exception sits at location 0x40. The ISR vPortYield is placed at the location with the following instructions:
.offset 0x0040 .extern _vPortYield jr _vPortYield
The context switching ISR is implemented as follows:
.text .align 4 .globl _vPortYield _vPortYield: add -0x0C,sp -- prepare stack to save necessary values st.w lp,8[sp] -- store LP to stack stsr 0,r31 st.w lp,4[sp] -- store EIPC to stack stsr 1,lp st.w lp,0[sp] -- store EIPSW to stack portSAVE_CONTEXT -- save the context of the current task. jarl _vTaskSwitchContext,lp -- call the scheduler. portRESTORE_CONTEXT -- Restore the context of whichever task the scheduler decided should run. ld.w 0[sp],lp -- restore EIPSW from stack ldsr lp,1 ld.w 4[sp],lp -- restore EIPC from stack ldsr lp,0 ld.w 8[sp],lp -- restore LP from stack add 0x0C,sp -- set SP to right position EIRET
Thus once it enters in to the _ vPortYield ISR, the RH850 automatically saves the current task's context via portSAVE_CONTEXT, identifies the next task to be scheduled using portRESTORE_CONTEXT. The incoming task “resumes its execution”, ensuring a seamless and efficient context switching process.
Conclusion
When the complexity of embedded systems is medium/high, using RTOS becomes necessary. Any RTOS mostly leverages software interrupts/exceptions as we have seen to perform context switching. While the location of storing the contexts, instructions used for that etc., may change the underlying premise remains the same.
To learn more about the handling of interrupts in embedded firmware and how they can enhance the efficiency and responsiveness of your embedded systems, I encourage you to explore our earlier blogs - Interrupt handling in embedded software, ARM Interrupt Controllers - The gateway to CPU's attention, Interrupt Handling in ARM Cortex M Core, Interrupt Handling in Renesas RH850 MCUs, and Interrupt Handling in PIC MCUs.