FREE COURSE / REAL PRACTICE
Microcontrollers & CMSIS
Connect C++ to startup, memory-mapped registers, interrupts, fixed-point arithmetic and CMSIS microcontroller interfaces.
What you’ll work toward
Explain firmware resource and timing contracts and use the available native or emulated exercises to test them.
Read an explanation, inspect the diagrams and work through the available checks, debugging exercises and builds. Feedback and prerequisite links guide the next step.
Before you start
This course builds on these skills:
Individual lessons can add prerequisites. The course map shows your actual readiness.
A look inside the first lesson
From reset to main: vector tables, startup code, linker scripts
#include <cstdint>
#include <cstdio>
extern "C" unsigned __stack_top; // defined by the linker script
extern "C" void Reset_Handler(); // defined in startup.cpp
int main() {
auto sp = reinterpret_cast<std::uintptr_t>(&__stack_top);
auto reset = reinterpret_cast<std::uintptr_t>(&Reset_Handler);
std::printf("initial SP = 0x%08lx\n", (unsigned long)sp);
std::printf("Reset_Handler = 0x%08lx (Thumb bit %lu)\n", (unsigned long)reset, (unsigned long)(reset & 1));
}Your course outline
Follow the lessons in curriculum order. Open a unit to preview the ideas you’ll work with.
Microcontrollers: the bare machine
- LESSON 01.01
From reset to main: vector tables, startup code, linker scripts
What a Cortex-M does between power-on and main: the vector table, the reset handler's chores (FPU, .data, .bss, constructors), linker scripts with VMA/LMA and their symbols, and the board's memory map.
Open lesson - LESSON 01.02
Memory-mapped I/O and volatile
Talk to hardware through memory-mapped registers: what volatile guarantees (and doesn't), register structs, read-modify-write and write-1-to-clear registers, why bitfields and hardware don't mix, and a polling UART driver.
Open lesson - LESSON 01.03
Typed registers: zero-cost MMIO in modern C++
Wrap memory-mapped registers in templates — Reg<address, access>, Field<reg, offset, width, type> — so wrong accesses don't compile and right ones cost exactly the ldr/bfi/str you'd write by hand.
Open lesson - LESSON 01.04
Freestanding C++: no OS, no heap, small budgets
Write C++ for a microcontroller: what the freestanding library gives you, static storage instead of the heap, -fno-exceptions and -fno-rtti and what they change in the code, constinit, and error handling with std::expected.
Open lesson
Microcontrollers: time, interrupts, data
- LESSON 02.01
Interrupts: SysTick, timers and the NVIC
The Cortex-M exception model in practice: vector table, NVIC enable/pending/priority, SysTick and timer interrupts, what the hardware stacks, why an ISR must clear its source, and sleeping with WFI — built into a tick clock with software timers.
Open lesson - LESSON 02.02
Critical sections and ISR-safe data
Sharing data between interrupt handlers and main code: torn reads, lost updates, PRIMASK guards that nest, what std::atomic compiles to on a Cortex-M4, and a lock-free queue between an ISR and the main loop.
Open lesson - LESSON 02.03
Interrupt-driven I/O
Drivers that don't busy-wait: an interrupt-driven UART transmitter fed from a ring buffer, starting and stopping the TX interrupt, backpressure, formatting without the heap, timer-driven work, event-driven state machines, and DMA as a concept.
Open lesson - LESSON 02.04
Fixed-point arithmetic and the M4 DSP instructions
Q15, Q31 and Q16.16: conversion and rounding, widening multiplies, saturation, the Cortex-M4's DSP instructions (ssat, qadd, smulbb, smlad, smlald), when the single-precision FPU is the better tool and why double is software, and FIR filters that don't overflow.
Open lesson
RTOS on the Cortex-M4 (FreeRTOS)
- LESSON 03.01
Tasks, scheduling and queues (FreeRTOS)
FreeRTOS on a Cortex-M4: task states, preemptive priority scheduling and time slicing, the idle task, vTaskDelay vs xTaskDelayUntil, stack budgets with high-water marks, queues (copy semantics and passing ownership by pointer), timeouts, task notifications, and static vs dynamic allocation.
Open lesson - LESSON 03.02
Priority inversion, mutexes and deadlock
Why a high-priority FreeRTOS task can wait on a medium one: unbounded priority inversion, Mars Pathfinder, binary semaphores vs mutexes, priority inheritance and its limits, priority ceilings, recursive mutexes, deadlock and lock ordering — and a shared-bus guard with a deadline monitor and an ownership trace.
Open lesson - LESSON 03.03
From interrupt to task (deferred processing)
Deferred interrupt processing under FreeRTOS on the Cortex-M4: waking tasks from ISRs with task notifications, queues and stream buffers, portYIELD_FROM_ISR and the latency it saves, ISR priorities versus configMAX_SYSCALL_INTERRUPT_PRIORITY (and the assert you get when it's wrong), what an ISR may call, counting overruns, and stopping an ISR-fed task cleanly.
Open lesson - LESSON 03.04
Fault detection and recovery under an RTOS
Keeping FreeRTOS firmware alive when a task gets stuck: hardware and software watchdogs, heartbeats with deadlines, restarting a task with fresh state, xTaskAbortDelay, timeouts on every wait, stack-overflow checks and configASSERT, fault records that survive a reset, and fail-safe states.
Open lesson
RTOS: software timers & event coordination
CMSIS: Cortex-M Core & RTOS2 on FreeRTOS
- LESSON 05.01
CMSIS-Core: device headers, NVIC & intrinsics
Use Arm CMSIS-Core on the Cortex-M4: device configuration, logical NVIC priorities, nested PRIMASK guards, barriers and saturating intrinsics.
Open lesson - LESSON 05.02
CMSIS-RTOS2 on FreeRTOS: threads, queues & API contracts
Run the CMSIS-RTOS2 API on the real FreeRTOS kernel: byte-sized thread stacks, priorities, copied messages, bounded waits, flags and adapter limits.
Open lesson