feat: add organization-per-series EDU catalog

This commit is contained in:
2026-07-19 16:38:49 +02:00
parent d18817dca5
commit 964ecba3e3
28 changed files with 1880 additions and 0 deletions
+389
View File
@@ -0,0 +1,389 @@
# FreeRTOS C — book-led card sequence
Status: FC01FC02 exist; FC03 is the next implementation; FC04FC15 are
planned. This series uses only the FreeRTOS C API. C++ wrappers belong to a
later, separate series.
## Primary source and ordering rule
The content map follows the official **FreeRTOS Kernel Book**:
- <https://github.com/FreeRTOS/FreeRTOS-Kernel-Book>
- <https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/toc.md>
The book supplies the concepts and API order. Each card adds the local
Hazard3/RV32I observation contract: stable checkpoints, source and ELF
identity, a debugging strategy and a timestamped runtime proof. We do not
copy the book examples verbatim; every program is a small deterministic
experiment suitable for replay.
```text
FreeRTOS Kernel Book
├── Ch. 3 Heap memory management → FC01, revisited in FC11
├── Ch. 4 Task management → FC02FC04
├── Ch. 5 Queue management → FC05
├── Ch. 6 Software timer management → FC06
├── Ch. 7 Interrupt management → FC07, FC13FC14
├── Ch. 8 Resource management → FC08
├── Ch. 9 Event groups → FC09
├── Ch. 10 Task notifications → FC10, FC13
├── Ch. 11 Low-power support → optional extension after FC15
├── Ch. 12 Developer support → FC12
└── Ch. 13 Troubleshooting → FC12 and every acceptance gate
```
FC11 deliberately revisits static allocation after the student has already
seen tasks, queues and timers. The book introduces it in Chapter 3; the later
placement lets one card compare real dynamic and static forms of several
kernel objects without teaching APIs that have not appeared yet.
## A1A8 viewpoint policy
A1A8 is a set of questions, not a requirement to draw eight decorative
diagrams. A view is enabled only when it adds a distinct proof.
```text
A1 CONTEXT system boundary and responsibility
A2 STRUCTURE C structs, handles, kernel objects and ownership
A3 DISPATCH callback, ISR or other binding boundary
A4 APPLICATION concrete task/object topology and invariants
A5 FLOW ordered execution and checkpoints
A6 STATE task/object state and lifetime
A7 RUNTIME addresses, TCB, stack, registers, tick and ELF evidence
A8 PATTERNS named reusable design decision, only when real
```
Every enabled diagram is interactive. A CODE step opens a stable source or
artifact reference without running the target. A RUN step replays from clean
RAM to a verified checkpoint. Moving the cursor alone never mutates the
simulator.
## Curated sequence
```text
FreeRTOS C — 15 cards
├── FC01 · Heap schemes and heap_4 block mechanics
├── FC02 · First task, typed context, TCB and task stack
├── FC03 · Tick, priorities, preemption and time slicing
├── FC04 · Delay, blocking, task states and deletion
├── FC05 · Queues, blocking and byte-copy semantics
├── FC06 · Software timers and the daemon task
├── FC07 · Interrupt-safe API and semaphore handoff
├── FC08 · Critical sections, mutexes and priority inheritance
├── FC09 · Event groups and multi-event synchronization
├── FC10 · Direct-to-task notifications
├── FC11 · Static allocation and bounded kernel storage
├── FC12 · Assertions, hooks, stack checks and runtime diagnostics
├── FC13 · UART interrupt-to-task pipeline
├── FC14 · GPIO, hardware timer and deferred work
└── FC15 · Integrated deterministic FreeRTOS C application
```
## FC01 — Heap schemes and heap_4 block mechanics
**Book basis:** 3.13.4: `heap_1``heap_5`, heap utilities, allocation
failure and static allocation introduction.
- Raw API: `pvPortMalloc`, `vPortFree`, `xPortGetFreeHeapSize`,
`xPortGetMinimumEverFreeHeapSize`, `vPortGetHeapStats`.
- Main task: compare allocator policies, then walk allocation, split, free
and coalescing in `heap_4`.
- Blocks: A1 allocator boundary; A2 block/list layout; A5 allocation flow;
A6 free/allocated block state; A7 heap addresses and statistics.
- Exercise: predict the free-list shape for a new allocate/free order.
- Hazard3/GDB proof: block headers, aligned sizes and coalesced neighbors
agree with the final heap statistics.
- Main pitfall: treating the minimum-ever-free value as current free space or
assuming all heap implementations support free/coalescing.
## FC02 — First task, typed context, TCB and task stack
**Book basis:** 4.24.6 and the creation/parameter parts of Examples 4.14.2.
- Raw API: `xTaskCreate`, `vTaskStartScheduler`, `vTaskDelete`,
`uxTaskGetStackHighWaterMark`.
- Main task: two equal-priority workers compute `sum(1..20000)` through
`void *pvParameters`; a lower-priority supervisor verifies both results.
- Enabled views: A1, A2, A3, A5, A6 and A7.
- Exercise: add a third typed context without introducing global task data.
- Hazard3/GDB proof: callback-entry `a0`, context, opaque handle/TCB, task
stack and A→B→A execution trace are distinct and consistent.
- Main pitfall: confusing `&handle`, the handle value, TCB, context and stack.
Detailed plan: [FC02 — A1A8 raw C task](freertos-c-fc02-a1-a8.md).
## FC03 — Tick, priorities, preemption and time slicing
**Book basis:** 4.5, 4.6, 4.9 and 4.12, especially prioritized preemptive
scheduling, runtime priority changes and time slicing.
- Raw API/config: `uxTaskPriorityGet`, `vTaskPrioritySet`,
`xTaskGetTickCount`, `configUSE_PREEMPTION`, `configUSE_TIME_SLICING`.
- Main task: two equal-priority peers establish A→B→A; one peer raises a
dormant probe from priority 0 to 3, which must preempt before the peer's
next committed write; a priority-1 verifier runs only after higher-priority
work ends.
- Blocks: A1 tick/scheduler boundary; A2 task/priority/trace data; A4
experiment topology; A5 two-part scheduling flow; A6 Ready/Running lanes;
A7 timer interrupt, current TCB, PC/SP and trace evidence.
- Exercise: run a bounded expected-noncompletion observation with time slicing
disabled, then explain why a CPU-bound peer can starve its equal-priority
neighbor.
- Hazard3/GDB proof: nondecreasing ticks, A→B→A, immediate high-priority
takeover and delayed low-priority verifier.
- Main pitfall: interpreting priority as fairness or treating a tick as a
guarantee that every Ready task ran.
Detailed plan: [FC03 — scheduler experiment](freertos-c-fc03-a1-a8.md).
## FC04 — Delay, blocking, task states and deletion
**Book basis:** 4.74.10 and Examples 4.44.8.
- Raw API: `vTaskDelay`, `vTaskDelayUntil`, `eTaskGetState`,
`vTaskSuspend`, `vTaskResume`, `vTaskDelete`.
- Main task: periodic and non-periodic tasks cross Ready, Running, Blocked,
Suspended and Deleted states on a controlled tick timeline.
- Blocks: A2 state-bearing contexts/handles; A5 delay and resume sequence;
A6 canonical task-state machine; A7 wake tick, PC/SP, TCB and idle cleanup.
- Exercise: replace relative delay with `vTaskDelayUntil` and quantify drift.
- Hazard3/GDB proof: actual wake ticks and public `eTaskState` observations
match the selected state-machine edges.
- Main pitfall: busy waiting instead of blocking, or assuming `vTaskDelete`
immediately erases every forensic trace.
## FC05 — Queues, blocking and byte-copy semantics
**Book basis:** Chapter 5, with emphasis on 5.25.5 and Examples 5.15.2.
- Raw API: `xQueueCreate`, `xQueueSendToBack`, `xQueueSendToFront`,
`xQueueReceive`, `uxQueueMessagesWaiting`, `xQueuePeek`.
- Main task: two producers send typed messages by value to one consumer; a
full and an empty queue deliberately block the correct task.
- Blocks: A1 producer/kernel/consumer boundary; A2 queue item/ring/storage;
A4 producer-consumer topology; A5 send/copy/block/wake/receive; A6 queue
and task states; A7 source address versus copied queue slot and destination.
- Exercise: compare a value queue with a queue of pointers and write the
ownership contract for the latter.
- Hazard3/GDB proof: changing the producer buffer after send does not change
the queued value; waiting counts and task transitions are correct.
- Main pitfall: assuming queues hold references, or queuing a pointer without
an explicit lifetime owner.
## FC06 — Software timers and the daemon task
**Book basis:** Chapter 6 and Examples 6.16.3.
- Raw API: `xTimerCreate`, `xTimerStart`, `xTimerChangePeriod`,
`xTimerReset`, `pvTimerGetTimerID`.
- Main task: one-shot and auto-reload timers share a callback but use distinct
IDs; task code resets one timer and changes the other's period.
- Blocks: A1 application/timer service/kernel boundary; A2 timer objects,
IDs and command queue; A3 callback dispatch; A5 command→daemon→callback;
A6 dormant/active/expired states; A7 daemon task, callback PC and tick.
- Exercise: derive the callback order for a changed period and verify it.
- Hazard3/GDB proof: callback context is the timer daemon task, not the task
that issued `xTimerStart`.
- Main pitfall: blocking inside a timer callback or assuming timer commands
execute synchronously in the caller.
## FC07 — Interrupt-safe API and semaphore handoff
**Book basis:** Chapter 7, especially 7.27.5 and queue/ISR considerations.
- Raw API: `xSemaphoreCreateBinary`, `xSemaphoreCreateCounting`,
`xSemaphoreGiveFromISR`, `xSemaphoreTake`, `portYIELD_FROM_ISR`.
- Main task: a deterministic simulated interrupt gives a semaphore, sets
`xHigherPriorityTaskWoken`, and transfers execution to a waiting task.
- Blocks: A1 ISR/task/kernel boundary; A2 semaphore and ISR evidence; A3
FromISR dispatch/yield contract; A5 interrupt→unblock→yield→task flow; A6
waiting/ready/running; A7 trap frame, `mcause`, PC/SP and awakened TCB.
- Exercise: replace binary with counting semantics and explain event loss or
accumulation.
- Hazard3/GDB proof: ISR uses only FromISR API, does not block, and a required
yield selects the unblocked higher-priority task.
- Main pitfall: calling task-context API from an ISR or ignoring
`xHigherPriorityTaskWoken`.
## FC08 — Critical sections, mutexes and priority inheritance
**Book basis:** Chapter 8, including critical sections, scheduler suspension,
mutexes, priority inversion/inheritance, deadlock and gatekeeper tasks.
- Raw API: `taskENTER_CRITICAL`, `taskEXIT_CRITICAL`, `vTaskSuspendAll`,
`xTaskResumeAll`, `xSemaphoreCreateMutex`, `xSemaphoreTake/Give`.
- Main task: low/medium/high tasks first expose bounded priority inversion,
then prove inherited priority while a mutex protects a shared resource.
- Blocks: A2 mutex owner/waiters/resource; A4 three-task topology; A5
inversion and inheritance flow; A6 mutex/task states; A7 effective versus
base priority and owner TCB; A8 mutex versus gatekeeper decisions.
- Exercise: construct a lock-order table that removes a demonstrated
two-mutex deadlock.
- Hazard3/GDB proof: low task's effective priority rises while high waits and
returns after release; the shared invariant remains intact.
- Main pitfall: using a binary semaphore where priority inheritance is
required, or holding a mutex across an unbounded operation.
## FC09 — Event groups and multi-event synchronization
**Book basis:** Chapter 9.
- Raw API: `xEventGroupCreate`, `xEventGroupSetBits`,
`xEventGroupWaitBits`, `xEventGroupSync`.
- Main task: two workers publish independent readiness bits; a coordinator
waits for ALL bits, then all participants cross a reusable barrier.
- Blocks: A2 bit ownership and event object; A4 participant topology; A5
set/wait/unblock/barrier; A6 bit mask and blocked-task state; A7 EventBits_t,
wait masks and TCB wake evidence; A8 barrier pattern.
- Exercise: compare ANY versus ALL and clear-on-exit semantics on the same
event trace.
- Hazard3/GDB proof: the coordinator cannot pass before the complete mask and
the barrier releases the intended set of tasks once.
- Main pitfall: reusing one bit for incompatible meanings or forgetting the
effects of automatic bit clearing.
## FC10 — Direct-to-task notifications
**Book basis:** Chapter 10, especially benefits/limits and 10.3.210.3.6.
- Raw API: `xTaskNotifyGive`, `ulTaskNotifyTake`, `xTaskNotify`,
`xTaskNotifyWait` and their explicit FromISR variants as a comparison.
- Main task: one receiver exercises counting, value overwrite and bit-set
notification modes without an intermediary queue/semaphore object.
- Blocks: A2 notification value in the target task; A3 sender→target binding;
A5 notify/block/wake/consume; A6 notification state/value; A7 target TCB,
value transitions and RAM comparison with queue/semaphore alternatives.
- Exercise: choose the correct notification action for three stated
protocols and justify what information can be lost.
- Hazard3/GDB proof: only the selected target wakes, and the observed value
transition matches the selected action.
- Main pitfall: treating a single notification slot as a general multi-reader
message queue.
## FC11 — Static allocation and bounded kernel storage
**Book basis:** 3.4 plus the static creation variants introduced throughout
Chapters 46.
- Raw API: `xTaskCreateStatic`, `xQueueCreateStatic`, `xTimerCreateStatic`,
`vApplicationGetIdleTaskMemory`, `vApplicationGetTimerTaskMemory`.
- Main task: rebuild a small task+queue+timer topology with explicit TCB,
stack and object buffers; compare it to the dynamic build.
- Blocks: A1 ownership boundary; A2 complete storage graph; A4 bounded
topology; A5 initialization order; A7 `.bss` addresses, map file and zero
heap growth.
- Exercise: calculate and declare all required storage for one additional
task and queue.
- Hazard3/GDB proof: kernel object addresses lie in declared static storage,
and free-heap values do not change during creation.
- Main pitfall: confusing a statically allocated task with a static C
function, or under-sizing stack/object buffers.
## FC12 — Assertions, hooks, stack checks and runtime diagnostics
**Book basis:** Chapters 1213.
- Raw API/config: `configASSERT`, malloc-failed and stack-overflow hooks,
`uxTaskGetStackHighWaterMark`, `uxTaskGetSystemState`, trace hooks.
- Main task: run controlled positive diagnostics plus isolated expected-fail
fixtures for an assertion, allocation failure and stack guard.
- Blocks: A1 diagnostic boundaries; A2 evidence record and hook contracts;
A5 fault→hook→frozen evidence; A6 healthy/failing terminal states; A7
stack watermark, task statistics, fault PC and build identity.
- Exercise: diagnose a supplied trace without changing the program first.
- Hazard3/GDB proof: every fixture stops in the intended hook with preserved
source/ELF/checkpoint identity and no false PASS.
- Main pitfall: optimizing hooks away, allocating/printing unsafely inside a
hook, or treating watermark as the exact current stack use.
## FC13 — UART interrupt-to-task pipeline
**Book basis:** 7.27.7 and the UART notification example in 10.3.7.
- Raw API: explicit UART ISR, `vTaskNotifyGiveFromISR` or
`xTaskNotifyFromISR`, `ulTaskNotifyTake`, `portYIELD_FROM_ISR`.
- Main task: RX ISR transfers bytes into a bounded ring; a task drains and
validates complete frames while TX ownership remains explicit.
- Blocks: A1 peripheral/ISR/task boundary; A2 MMIO/ring/task context; A3
ISR→notification binding; A5 byte→interrupt→ring→task→frame flow; A6 ring
and receiver states; A7 MMIO, indices, trap frame and task stack.
- Exercise: specify overflow policy and prove it with an overlong frame.
- Hazard3/GDB proof: ISR duration is bounded, no blocking API is used, ring
indices remain valid and the consumer wakes at the correct boundary.
- Main pitfall: doing parsing in the ISR or publishing an index before the
corresponding byte is visible.
## FC14 — GPIO, hardware timer and deferred work
**Book basis:** 6.4, 7.3 and 7.6, applied to GPIO/timer peripherals.
- Raw API: hardware timer ISR, `xTimerPendFunctionCallFromISR`, optional
notification/semaphore comparison, GPIO MMIO.
- Main task: a timer edge records minimal ISR evidence, defers a bounded
callback to the daemon task, and updates GPIO state under a stated timing
contract.
- Blocks: A1 hardware/ISR/daemon/task boundary; A2 event record; A3 deferred
callback binding; A5 edge→ISR→daemon queue→callback→GPIO; A6 pending and
applied states; A7 `mtime/mtimecmp`, trap frame, daemon task and MMIO.
- Exercise: select notification, semaphore or daemon deferral for three
different workloads.
- Hazard3/GDB proof: ISR and deferred callback have different stacks/PCs,
exactly one GPIO transition is associated with each accepted event.
- Main pitfall: confusing a hardware timer interrupt with a FreeRTOS software
timer callback or overloading the daemon task.
## FC15 — Integrated deterministic FreeRTOS C application
**Book basis:** synthesis of Chapters 313.
- Raw API: tasks, queues, notification, event group, mutex, software timer,
FromISR handoff and diagnostics, selected only where justified.
- Main task: acquire deterministic UART/GPIO/timer events, process one
algorithmic workload, publish results and supervise health under bounded
memory.
- Blocks: all A1A8 views may be enabled because architecture, topology,
dispatch, flow, state, runtime and patterns are all distinct here.
- Exercise: change one application policy while preserving the published
concurrency and memory contracts.
- Hazard3/GDB proof: timestamped end-to-end trace connects input event,
selected task, communication object, result, deadline/ordering invariant
and final PASS.
- Main pitfall: adding every learned primitive instead of choosing the
smallest correct synchronization mechanism.
## Common card contract
Every new card must contain:
1. a one-page goal and scope contract;
2. one principal Task divided into viewpoint Blocks and Phases/Steps;
3. only applicable A1A8 views, with explicit reasons for unavailable views;
4. a stable `code_ref` for every CODE step;
5. a debug strategy, checkpoint and non-empty assertion set for every RUN
step;
6. a student exercise that changes one variable without changing the whole
experiment;
7. a Hazard3/GDB acceptance proof including source and ELF identity;
8. HTML and TeX generated from one `card_source.json`;
9. no PDF generation and no commit unless explicitly requested.
## Implementation order
```text
FC03 scheduler
→ FC04 state/delay
→ FC05 queues
→ FC06 software timers
→ FC07 interrupts/semaphores
→ FC08 resources/mutex
→ FC09 event groups
→ FC10 notifications
→ FC11 static allocation
→ FC12 diagnostics
→ FC13 UART
→ FC14 GPIO/timer
→ FC15 integration
```
Ukończenie FC15 jest pierwszą z dwóch bramek wejścia do FreeRTOS C++; drugą
jest ukończenie właściwych kart językowych C++/OOP.