Files

63 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# K09 — Scheduler facade and scoped kernel guards
## Position
- Series: FreeRTOS C++
- Lesson: L08, card K09
- Duration: 30 minutes
- Platform: Hazard3 / RV32I, FreeRTOS V11.3.0
- Evidence: kernel state, `xCriticalNesting`, `mstatus.MIE`, ELF assembly
## Outcome
After 30 minutes the student can distinguish scheduler suspension from a
critical section, choose a static facade versus an RAII guard, and prove that
three early-return paths restore the paired kernel state.
## Lesson plan
| Time | Mode | Evidence |
| --- | --- | --- |
| 05 | raw API | classify service calls and paired calls |
| 510 | critical nesting | record 0→1→2→1→0 and MIE transitions |
| 1015 | critical guard | run three early returns; prove depth 0/MIE 1 |
| 1520 | scheduler guard | prove suspended state with interrupts enabled |
| 2025 | nesting/`this_task` | nested guards, current handle, tick and yield |
| 2530 | ABI and repair | no wrapper symbols; repair three-exit function |
## Canonical comparison
| Operation | Context switch | Interrupt MIE | Pair |
| --- | --- | --- | --- |
| `vTaskSuspendAll` | deferred | remains enabled | `xTaskResumeAll` |
| `taskENTER_CRITICAL` | prevented | disabled | `taskEXIT_CRITICAL` |
Scheduler suspension can nest. The inner guard's destructor decreases the
nesting level but the state remains suspended until the outer guard exits.
Critical sections also nest; MIE is enabled only when depth returns to zero.
## Student repair
Start with a function containing a manual enter/suspend call and three returns.
Replace only the pairing mechanism with the appropriate guard. Verify every
path at the checkpoint rather than accepting source-level appearance as proof.
## Acceptance
- static facade is non-constructible;
- both guards are non-copyable/non-movable and restore all three paths;
- raw critical values are exactly 0/1/2/1/0 and MIE 1/0/0/0/1;
- scheduler suspension leaves MIE enabled;
- nested scheduler guard remains suspended after inner destruction;
- `this_task::current()` equals the worker handle;
- facade and guard calls are inline with no vtable, RTTI or hosted runtime;
- target exits with PASS.
## Main traps
1. `Scheduler` is a facade, not a scoped owner.
2. Scheduler suspension is not interrupt masking.
3. Never block while the scheduler is suspended.
4. A task-context critical guard is not an ISR-safe mutex.
5. RAII balances control flow; it does not make an invalid operation valid.