Panel For Example Panel For Example Panel For Example
Concurrency and Interrupts in Microcontrollers and Embedded Systems

Concurrency and Interrupts in Microcontrollers and Embedded Systems

August 27, 2025

This article is the first in a series exploring the concepts of concurrency and interrupts. In this introductory piece, we'll discuss basic definitions of these concepts and examine their relevance to writing code for microcontrollers.

What Is Concurrency?

Let's explain concurrency using a familiar example. When you go to bed, you typically want to wake up at a specific time. You have two objectives here: to sleep and rest, while also ensuring you don't oversleep.

One way to avoid missing your wake-up time would be to stay awake watching the clock, but this defeats the purpose of sleeping. To solve this, we use an alarm clock (either a device or a trusted person who's already awake) to wake us at the designated time, allowing us to focus on sleeping while still achieving our timing goal.

Concurrency describes scenarios where you manage two or more processes simultaneously but can physically handle only one at any given moment.

In our example, the two processes are sleeping and tracking time (to wake at the desired moment). It's physically impossible for one person to do both simultaneously.

Typically, we're only interested in specific events related to our processes. In the example above, the time-related event we care about is whether it's time to wake up. The standard approach to handling concurrency involves using another physical resource (alarm clock or person) to monitor for our event of interest, then alert (or interrupt) us when it occurs so we can respond.

Concurrency in Embedded and Cyber-Physical Systems

Embedded and cyber-physical systems frequently must handle concurrency.

A microwave oven provides a good example. The device needs to respond to button presses or detect when the door opens during food heating. Pressing pause/cancel or opening the door stops the heating process.

Microcontrollers—the computers you typically program as a system's "brain"—are designed with concurrency in mind.

Beyond the general-purpose CPU, they contain numerous specialized hardware devices (called peripherals) for interacting with the external world, enabling connections to buttons, displays, and other necessary hardware. These peripherals often include interrupt mechanisms, allowing the CPU to request they monitor specific events and interrupt the CPU when those events occur.

Overview of Interrupts and Concurrent Programming

Interrupts in microcontrollers function exactly like our sleep/alarm clock example.

You can program a peripheral to monitor an event (like a GPIO input changing from 0 to 1) and interrupt the CPU when it occurs. During normal operation, the CPU executes your main program. When the monitored event occurs, the peripheral signals the CPU. If configured correctly, the CPU will:

  • Pause the main program
  • Execute a special function called an Interrupt Service Routine (ISR) or interrupt handler
  • Return to continue the main program where it left off

You must write the ISR as part of your code. When programming in C, this means declaring and defining it in your source code so it becomes part of the microcontroller's executable.

However, you never call the ISR directly. All microcontroller development tools provide specific ways to inform the C compiler that a particular function is an ISR and which interrupt it handles. When configured properly, the CPU automatically jumps to that function when the specific interrupt occurs.

Interrupt Example in C Code

Because of how interrupts work, handling concurrency in programming can seem counterintuitive at first.

The following describes how C code with an ISR executes, providing a useful mental model for concurrent programming (assuming proper interrupt configuration):

  • The CPU executes code within the main function's while loop
  • The monitored event (change from 1 to 0) occurs on the interrupt-configured pin
  • The CPU pauses the while loop and executes the ISR
  • After ISR completion, the CPU resumes the main loop
  • When the event reoccurs, the same interrupt process repeats
  • Peripherals and GPIO Interrupts