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 |
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
- Steps 1–8. A Discovery F407 with FreeRTOS from route B; on it, a task watchdog with IWDG and WWDG (33а.3).
- Step 8. A channel for uploading the trace to the computer (33б.4).
- Step 9. A board with an ESP32: two cores on one die (152.1).
0г.4 Where next: forks after route Zh
- 34а — Zephyr: a different operating system for someone who knows FreeRTOS.
- 35в — a failure in the field: a state snapshot that survives a reset.
- 35г — a log on the device instead of
printf. - 21а — RTT: output through the debugger without extra pins.
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
- Route Zh is nine steps after route B: a state machine and an event queue (23а), events and notifications (31), software timers (29), buffers (32), active objects (32а), configuration (33), a task watchdog (33а), tracing (33б), two cores (152).
- The level is intermediate → advanced; the advanced step is 33б.
- Three blocks: task communication and time (1–4), event-driven architecture (5), observability and reliability (6–9).
- After the route there are four forks: 34а, 35в, 35г, 21а.
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.