77 lines
2.9 KiB
Markdown
77 lines
2.9 KiB
Markdown
# K08 — DynamicTask, StaticTask, deletion and lifetime
|
||
|
||
## Position
|
||
|
||
- Series: FreeRTOS C++
|
||
- Lesson: L07, card K08
|
||
- Duration: 30 minutes
|
||
- Real dynamic `heap_4` plus caller TCB/stack in `.bss`
|
||
- Idle task itself and the verifier use static storage to isolate measurement
|
||
|
||
## Outcome
|
||
|
||
After 30 minutes the student can calculate stack words and bytes, prove dynamic
|
||
heap cost versus zero-delta static creation, classify TCB/stack addresses, and
|
||
explain why self-deletion and actual dynamic memory reclamation are separated by
|
||
idle-task cleanup.
|
||
|
||
## Lesson plan
|
||
|
||
| Time | Mode | Evidence |
|
||
| --- | --- | --- |
|
||
| 0–5 | units/storage | predict 256 words, bytes and locations |
|
||
| 5–10 | dynamic create | measure heap delta and classify TCB/stack |
|
||
| 10–15 | static create | caller TCB/stack addresses; heap delta zero |
|
||
| 15–20 | run/complete | identical result 500500; wrappers completed/null |
|
||
| 20–25 | delete timing | heap still reduced immediately after self-delete |
|
||
| 25–30 | idle cleanup | block verifier; recover exact dynamic delta/baseline |
|
||
|
||
## Canonical timeline
|
||
|
||
```text
|
||
baseline
|
||
-> xTaskCreate(dynamic): heap - dynamic_cost
|
||
-> xTaskCreateStatic(static): no heap change
|
||
-> both run and complete
|
||
-> both call vTaskDelete(nullptr)
|
||
-> verifier runs before idle: dynamic storage still pending cleanup
|
||
-> verifier blocks
|
||
-> idle calls termination cleanup:
|
||
dynamic TCB/stack -> vPortFree
|
||
static TCB/stack -> not freed (caller owned)
|
||
-> verifier wakes: heap == baseline
|
||
```
|
||
|
||
## Stable evidence
|
||
|
||
| Evidence | Required relation |
|
||
| --- | --- |
|
||
| dynamic cost | baseline - after_dynamic > 0 |
|
||
| static delta | after_static == after_dynamic |
|
||
| verifier delta | static verifier creation also leaves heap unchanged |
|
||
| dynamic addresses | TCB and stack base lie in `ucHeap` |
|
||
| static addresses | observed TCB/stack equal caller storage and lie outside heap |
|
||
| before idle | free equals post-create value, despite completed wrappers |
|
||
| after idle | free=baseline; recovered bytes=dynamic cost |
|
||
| units | 256 `StackType_t` words = 1024 B on RV32I |
|
||
|
||
## Main traps
|
||
|
||
1. `stack_depth` counts words, not bytes.
|
||
2. `vTaskDelete(nullptr)` removes the current task from scheduling but dynamic
|
||
memory reclamation is deferred to idle.
|
||
3. Static task deletion does not free caller storage; premature reuse is a
|
||
lifetime bug.
|
||
4. A wrapper handle becoming null is not proof that idle cleanup already ran.
|
||
5. Forced deletion does not run arbitrary C++ destructors on the victim stack.
|
||
|
||
## Acceptance
|
||
|
||
- host test proves both create APIs receive the same stable context and static
|
||
native handle equals caller TCB;
|
||
- ABI proves static worker storage is `.bss` and no vtable/init runtime exists;
|
||
- static create and verifier create have exactly zero heap delta;
|
||
- dynamic cost is recovered only after the verifier lets idle run;
|
||
- both results are 500500, states completed, handles null and final PASS is 1.
|
||
|