Embedded HandbookApps
All sections › 0. About the handbook
STM32F407, ESP32 · level intermediate · 5 min read
Open in the interactive handbook

0г. Topic routes: a device on an RTOS — architecture and observability

Route B (0.4) teaches FreeRTOS brick by brick: heaps, tasks, queues, interrupts, races and mutexes. Once you have the bricks, the next question comes up — how to build a device out of them that does not fall apart after a month: how tasks learn about events, who measures time, how to structure the program so that it can be read, and how to see what is really happening inside.

Route Zh: a device on an RTOS answers this in nine steps — from a state machine without an OS to a scheduler on two cores. The rules are the same as for the beginner's route (0а.1): one step — one section, and from the section you take away the "What to take away" column.

Prerequisites: route B, steps 4–8 — sections 25, 26, 27, 28 and 30. Without them route Zh is hard going: it uses tasks, queues and mutexes as ready-made words.

Terms used in the documentation

Term Meaning
firmware architecture what parts the firmware is built from and how they talk to each other
event-driven design building on events: parts wait for events instead of polling each other
deadline miss the task did not finish by its due moment

0г.1 How to follow route Zh

The route goes in three blocks. Steps 1–4 are how tasks talk and how they measure time: a state machine and an event queue, events and notifications, software timers, stream buffers. Step 5 is architecture: active objects assemble all of this into a device. Steps 6–9 are observability and reliability: kernel configuration, a task watchdog, tracing and two cores.

The route level is intermediate → advanced: there is one advanced step — tracing (33б); the other eight are intermediate.


0г.2 Route Zh: a device on an RTOS

Route level: intermediate → advanced. Nine steps: task communication and time, event-driven architecture, observing a running system.

Step Section What to take away What to skip for now
1 23а a state machine: the transition table first, then the code; an event queue from the interrupt to the loop; when you do need an OS after all 23а.5 a non-blocking driver
2 31 an event group, a synchronization point, a task notification — and which of them to choose 31.5 inputs and outputs by mask
3 29 a software timer and the daemon task; what is allowed in a callback and what is not; a link watchdog on a timer 29.8 the daemon as an on-demand executor
4 32 the stream buffer and the message buffer; the rule of one writer and one reader 32.6 inter-core communication — at step 9
5 32а an active object: a task, its own queue and a state machine; a device made of three objects; queue length and overflow 32а.4 comparison with the old way
6 33 basic kernel parameters, memory and statistics, tickless mode 33.4 advanced settings
7 33а a watchdog for several tasks: a watchdog task and two hardware watchdogs; false triggers and long legitimate work 33а.6 a snapshot before the reset
8 33б tracing: kernel macros, recording into a ring buffer, a diagram on the computer; inversion, jitter and starvation in the trace 33б.6 the cost of the tracer
9 152 FreeRTOS on two cores: the tick and task pinning, a race on two cores and three ways to cure it 152.4 esp_timer

Route Zh: nine steps in a zigzag — a state machine and an event queue, events and notifications, software timers, buffers, active objects, configuration, a task watchdog, tracing, two cores — and four forks; the block colour is the level of the hardest section in it

The order rests on one thing: an active object (5) is a state machine (1) in its own task that waits for events (2), measures time with timers (3) and receives data through a queue or a buffer (4). Observability comes after architecture: the task watchdog (7) and the trace (8) have something to show when the tasks are structured the same way.


0г.3 What you need on the desk


0г.4 Where next: forks after route Zh


0г.5 Pitfalls

Taking an OS for the sake of a single task. First an honest comparison with a device without an OS (23а.7): a state machine and an event queue solve a lot without a scheduler.

Two writers to one stream buffer. The stream buffer and the message buffer follow the rule of one writer and one reader (32.3).

Waiting in a timer callback. Callbacks are executed by a single daemon task; what is allowed in them and what is not — 29.4.

A watchdog fed by a single task. A live task feeds the watchdog while its neighbour hangs; a watchdog for several tasks checks the check-in of each one (33а.1–33а.2).

Looking for priority inversion by eye. Inversion, jitter and starvation are visible in the trace (33б.5), not in terminal output.


0г.6 Summary


Next: section 1 "The microcontroller as such" — what lies inside the die: the core, memory, peripherals — and why without this everything that follows would have to be taken on faith.

Open in the interactive handbook