feat: add lab-rv32i-freertos-task-wrapper card
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# K07 — `TaskHandle_t`, explicit `start()` and static trampoline
|
||||
|
||||
K07 isolates the exact C/C++ task-entry boundary. A local `CounterTask` object
|
||||
is constructed without touching the FreeRTOS heap. Only an explicit `start()`
|
||||
calls `xTaskCreate()` and passes the stable object address as `void*` context.
|
||||
The kernel later calls a static, non-virtual trampoline, which recovers the
|
||||
typed object and invokes its private `run()` member.
|
||||
|
||||
```text
|
||||
CounterTask object
|
||||
-> start()
|
||||
-> xTaskCreate(static trampoline, context=&object)
|
||||
-> kernel chooses task
|
||||
-> trampoline(void*)
|
||||
-> static_cast<CounterTask*>(context)
|
||||
-> object.run()
|
||||
-> state=completed, handle=nullptr, vTaskDelete(nullptr)
|
||||
```
|
||||
|
||||
The wrapper is non-copyable and non-movable because a live kernel task retains
|
||||
its object address. The destructor does not attempt asynchronous task deletion.
|
||||
|
||||
## Three distinct address domains
|
||||
|
||||
The checked Hazard3 run records:
|
||||
|
||||
```text
|
||||
C++ object = 0x800fffcc (local object on the retained main stack)
|
||||
TCB/handle = 0x800038b0 (dynamic kernel object in ucHeap)
|
||||
task stack = 0x800034a0..0x80003890
|
||||
result = 500500
|
||||
```
|
||||
|
||||
The object address remains identical before start, in `xTaskCreate` context,
|
||||
inside the trampoline, inside `run()` and at completion. The numeric handle is
|
||||
the TCB address and is deliberately different from the C++ object.
|
||||
|
||||
## Lifecycle evidence
|
||||
|
||||
| Point | Evidence |
|
||||
| --- | --- |
|
||||
| 1 | object constructed; heap unchanged; handle null |
|
||||
| 2 | state `starting` inside explicit start |
|
||||
| 3 | state `ready`; typed object passed as raw context |
|
||||
| 4 | `xTaskCreate` returned; handle now identifies the TCB |
|
||||
| 5 | scheduler not yet started; object still at same address |
|
||||
| 6 | static trampoline receives the original object address |
|
||||
| 7 | state `running` before member body |
|
||||
| 8 | body records current handle, stack bounds and result |
|
||||
| 10 | state `completed`, handle cleared, current task self-deletes |
|
||||
| 11–12 | raw verifier checks identity/lifecycle and emits PASS |
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
make check
|
||||
```
|
||||
|
||||
Expected summary:
|
||||
|
||||
```text
|
||||
PASS host: explicit start, stable context, duplicate/failure states
|
||||
PASS ABI: static trampoline; no vtable, RTTI or hosted runtime
|
||||
PASS task01: explicit start + stable context + trampoline
|
||||
```
|
||||
|
||||
## Debug
|
||||
|
||||
```gdb
|
||||
b explicit_task_debug_checkpoint
|
||||
p g_checkpoint_trace
|
||||
p/x g_object_before_start
|
||||
p/x g_trampoline_context
|
||||
p/x g_run_this
|
||||
p/x g_handle_after_start
|
||||
p/x g_tcb_address
|
||||
p/x g_stack_low
|
||||
p/x g_stack_high
|
||||
p/x g_stack_local
|
||||
p g_counter_result
|
||||
p g_task_wrapper_pass
|
||||
```
|
||||
|
||||
## Scope boundary
|
||||
|
||||
K07 uses dynamic kernel storage only to study entry and identity. K08 compares
|
||||
dynamic and caller-supplied static TCB/stack policies and the timing of idle-task
|
||||
cleanup. A `Task` destructor still does not force-delete a running task.
|
||||
|
||||
Reference in New Issue
Block a user