Production firmware runs dozens of concurrent tasks: reading sensors, driving actuators, handling communication, managing power, and responding to user input, all with deterministic timing. A bare-metal super loop can handle a few of these, but it breaks down when tasks have conflicting timing requirements. This course teaches you to build concurrent firmware correctly using a Real-Time Operating System (RTOS). Each lesson builds a working RTOS application on hardware you already own from earlier courses. #RTOS #FreeRTOS #EmbeddedSystems
Why RTOS?
Beyond Super-Loops
Bare-metal main loops work until they do not. When you need sensor reads every 10ms, display updates every 50ms, and serial logging every 100ms, all without blocking each other, you need an RTOS. This course teaches you when and why.
Synchronization Done Right
Priority inversion, deadlocks, race conditions, and starvation. These are not textbook concepts; they are bugs that ship in real products. Lesson 4 gives you the mental models and practical patterns to avoid them.
Debug the Invisible
RTOS bugs are timing bugs. You cannot find them with printf. Lesson 7 teaches you to use Tracealyzer and SystemView to visualize task execution, find priority inversions, and measure jitter. This lesson alone is worth bookmarking.
Portable Skills
FreeRTOS runs on STM32, ESP32, RP2040, and hundreds of other platforms. Zephyr adds Linux-like abstractions with devicetree. These skills transfer across every embedded job.
Course Structure
Each lesson follows a consistent cycle:
The Concurrency Problem
A real scenario where bare-metal falls short. Multiple tasks that must coexist with timing guarantees.
RTOS Theory
The kernel mechanism that solves this problem: how it works internally, its guarantees, and its costs.
FreeRTOS Implementation
Build the solution on real hardware. Write tasks, configure the kernel, and handle edge cases.
Test and Break It
Deliberately create failure conditions (deadlock, priority inversion, stack overflow) to understand the theory viscerally.
Design Patterns
Reusable patterns for production firmware. When to use each primitive, and when simpler solutions are better.
Lessons
Lesson 1: Real-Time Systems Concepts
Real-Time Systems Concepts. Define hard, soft, and firm real-time. Measure jitter in bare-metal loops vs RTOS tasks. Understand worst-case execution time, scheduling theory, and rate-monotonic analysis. Build a jitter measurement rig.
Build: Jitter measurement rig. Hardware: STM32 Blue Pill or ESP32 (from prior courses), LED.
Lesson 2: Tasks, Scheduling, and Context Switching
Tasks, Scheduling, and Context Switching. Explore task states, priority-based preemptive scheduling, time slicing, and the task control block. Understand stack allocation and context switch overhead. Build a priority-based traffic light controller.
Build: Traffic light controller. Parts: 3 LEDs (red, yellow, green), 2 push buttons.
Lesson 3: Queues and Inter-Task Communication
Queues and Inter-Task Communication. Implement message queues, stream buffers, and event groups for passing data between tasks. Producer-consumer patterns, queue sizing, and blocking vs non-blocking sends. Build a sensor data pipeline with filtering.
Build: Sensor data pipeline. Parts: Potentiometer, SSD1306 OLED (reuse from prior courses).
Lesson 4: Semaphores, Mutexes, and Synchronization
Semaphores, Mutexes, and Synchronization. Master binary and counting semaphores, mutexes with priority inheritance, and deadlock avoidance strategies. Build a multi-sensor I2C coordinator with mutex-protected bus access.
Build: Multi-sensor I2C coordinator. Parts: BME280 + one other I2C sensor (reuse from prior courses).
Lesson 5: Memory Management and Safety
Memory Management and Safety. Compare FreeRTOS heap allocation schemes (heap_1 through heap_5). Implement static allocation, memory pools, and stack watermarking. Explore MPU-based memory protection. Build a memory-safe command processor.
Build: Memory-safe command processor. Parts: Reuse existing.
Lesson 6: Software Timers and Interrupt Management
Software Timers and Interrupt Management. Configure software timers, deferred interrupt processing, and ISR-safe API calls. Understand critical sections, interrupt nesting, and the timer service task. Build a debounced multi-button input system.
Build: Debounced multi-button input system. Parts: 4 push buttons, LEDs.
Lesson 7: Debugging and Profiling RTOS Applications
Debugging and Profiling RTOS Applications. Use Tracealyzer or SystemView to visualize task execution in real-time. Measure CPU load, detect stack overflows, find priority inversions, and profile queue throughput. Receive intentionally buggy RTOS firmware and diagnose every issue.
Build: RTOS bug hunt (deadlock, priority inversion, stack overflow). Parts: Reuse existing.
Lesson 8: Zephyr RTOS Introduction
Zephyr RTOS Introduction. Set up the Zephyr build system with west. Learn devicetree, Kconfig, and Zephyr’s threading model. Port the traffic light controller from Lesson 2 to Zephyr and compare the two RTOS approaches.
Build: Traffic light controller on Zephyr. Parts: Same as Lesson 2.
Hardware
No new purchases needed. This course uses hardware from the ATmega328P, STM32, or ESP32 courses:
Part
Source
Used In
STM32 Blue Pill + ST-Link (or ESP32 DevKitC)
STM32 or ESP32 course
All lessons
LEDs (red, yellow, green) + resistors
ATmega328P course
Lessons 1, 2, 6, 8
Push buttons + 10K resistors
ATmega328P course
Lessons 2, 6, 8
Potentiometer
STM32 course
Lesson 3
SSD1306 OLED display
ATmega328P or STM32 course
Lesson 3
BME280 sensor
ATmega328P or STM32 course
Lesson 4
If you have completed any of the previous embedded courses, you already have everything.
Skill Progression
Skill
Lessons 1-2
Lessons 3-4
Lessons 5-6
Lessons 7-8
Kernel
Scheduler, task states, preemption
Queues, semaphores, mutexes
Heap schemes, timers, ISR integration
Trace tools, Zephyr kernel
Patterns
Task decomposition, priority assignment
Producer-consumer, resource sharing
Static allocation, deferred processing
Profiling, cross-RTOS portability
Debugging
Jitter measurement
Queue overflow detection
Stack watermarking, MPU faults
Tracealyzer, SystemView
Failure Modes
Missed deadlines, starvation
Deadlock, priority inversion
Heap fragmentation, stack overflow
All combined in bug hunt
Prerequisites
Complete at least one prior embedded course
You should be comfortable with:
Embedded C programming (registers, interrupts, peripheral drivers)
At least one microcontroller platform (STM32 recommended, ESP32 also works)
FreeRTOS basics from STM32 lesson 8 (this course goes much deeper)
Basic understanding of operating system concepts (processes, threads, scheduling)
Getting Started
Use your STM32 Blue Pill or ESP32 DevKitC from a previous course. Both run FreeRTOS.
Gather LEDs, buttons, and sensors from your existing parts kit. No new purchases needed.
Install Tracealyzer (free trial) or SEGGER SystemView (free) for lesson 7. Optional for earlier lessons.
Start with Lesson 1. The jitter measurement rig gives you an immediate, visceral understanding of why RTOS matters.
Break things deliberately. Each lesson includes a section where you intentionally create failure conditions. This is where the deepest learning happens.