Email
← Projects

Bare-Metal RTOS on STM32

A preemptive real-time kernel written from the reset vector up, with context-switch latency measured on a logic analyzer.

Startup and drivers

I wrote the linker script, vector table, and reset handler for the STM32F446. The handler copies .data, zeroes .bss, and configures the clock tree. Setting flash wait states before raising the clock frequency is one of the ordering details that matters at startup.

The register-level drivers cover GPIO, UART with ring buffers, SysTick, I²C, and SPI. Logic-analyser captures let me compare bus activity with the expected transaction, including the start, address, ACK, and data phases of I²C.

Scheduling

The kernel uses task control blocks, per-task stacks, and PendSV context switching. SysTick drives time slicing, while a priority scheduler chooses the next task. A blocked task yields the CPU. Mutexes use priority inheritance to handle priority inversion.

Proof on wires

Each task toggles a distinct GPIO so I can inspect scheduling on the logic analyser. DWT->CYCCNT measures context-switch cost in cycles. Fault registers such as CFSR and HFSR help narrow down stack-frame and exception-return errors in GDB.