{ "card": { "number": "11", "slug": "static-allocation", "title": "Static and dynamic allocation", "topic": "task, queue and timer with two storage policies", "status": "Gotowa", "version": "v00.01" }, "front": { "goal": "Uczeń rozdziela semantykę obiektu FreeRTOS od polityki przechowywania i dowodzi jej przez adresy oraz cztery pomiary wolnego heap.", "scope": "Dynamiczny i statyczny task, queue oraz timer wykonują ten sam eksperyment. H1 jest mniejsze od H0, H2 równa się H1, a H3 równa się H2. Pamięć Idle i timer-service dostarcza aplikacja." }, "viewpoints": [ { "id": "A1", "label": "CONTEXT", "status": "enabled", "subtitle": "ownership boundaries" }, { "id": "A2", "label": "STRUCTURE", "status": "enabled", "subtitle": "dynamic/static object pairs" }, { "id": "A3", "label": "DISPATCH", "status": "unavailable", "subtitle": "same kernel dispatch", "reason": "Storage policy does not change callback dispatch." }, { "id": "A4", "label": "APPLICATION", "status": "enabled", "subtitle": "behavior parity" }, { "id": "A5", "label": "FLOW", "status": "enabled", "subtitle": "H0/H1/H2/H3" }, { "id": "A6", "label": "STATE", "status": "unavailable", "subtitle": "covered by flow", "reason": "No new lifecycle state machine; the card compares storage." }, { "id": "A7", "label": "RUNTIME", "status": "enabled", "subtitle": "address provenance" }, { "id": "A8", "label": "PATTERNS", "status": "unavailable", "subtitle": "policy comparison", "reason": "No wrapper pattern is introduced in this C card." } ], "artifact": { "source": "src/tasks/task01_static_allocation.c", "elf": "build/task01_static_allocation/prog.elf", "image": "build/task01_static_allocation/prog.bin" }, "strategies": [ { "id": "code.storage", "kind": "code", "action": "open", "expected_observations": [ "persistent Static* buffers", "application static Idle/timer task memory" ], "assertions": [ "no local-lifetime storage", "both allocation modes enabled" ], "evidence_fields": [ "symbol", "section", "code_ref" ], "prerequisites": [ "FC11 source" ], "layout": [ "buffers", "create APIs", "FreeRTOSConfig" ], "commands": [ "rg -n 'x.*CreateStatic|vApplicationGet.*TaskMemory|Static(Task|Queue|Timer)_t' include src" ] }, { "id": "run.heap", "kind": "run", "action": "replay", "expected_observations": [ "H1 < H0", "H2 == H1", "H3 == H2" ], "assertions": [ "objects alive at H3", "no exact delta assumption" ], "evidence_fields": [ "H0", "H1", "H2", "H3", "timestamp" ], "prerequisites": [ "clean Hazard3 RAM" ], "layout": [ "heap values", "event order" ], "commands": [ "print g_fc11.heap_h0", "print g_fc11.heap_h1", "print g_fc11.heap_h2", "print g_fc11.heap_h3" ] }, { "id": "run.parity", "kind": "run", "action": "replay", "expected_observations": [ "both receive 0xCAFE", "both timers callback once" ], "assertions": [ "distinct stacks", "PASS and deterministic digest" ], "evidence_fields": [ "received", "timer calls", "SP", "digest" ], "prerequisites": [ "scheduler running" ], "layout": [ "two branches", "verifier" ], "commands": [ "print/x g_fc11.dynamic_received", "print/x g_fc11.static_received", "print g_fc11_pass" ] } ], "checkpoints": { "task01.h0": { "event_id": "E01", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 1" }, "verify": { "expressions": [ { "expr": "g_fc11_event_count", "equals": 1 } ] } }, "task01.h1": { "event_id": "E02", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 2" }, "verify": { "expressions": [ { "expr": "g_fc11.heap_h1 < g_fc11.heap_h0", "equals": 1 } ] } }, "task01.h2": { "event_id": "E03", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 3" }, "verify": { "expressions": [ { "expr": "g_fc11.heap_h2 == g_fc11.heap_h1", "equals": 1 } ] } }, "task01.dynamic-run": { "event_id": "E04", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 4" }, "verify": { "expressions": [ { "expr": "g_fc11.dynamic_received", "equals": 51966 } ] } }, "task01.static-run": { "event_id": "E05", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 5" }, "verify": { "expressions": [ { "expr": "g_fc11.static_received", "equals": 51966 } ] } }, "task01.dynamic-callback": { "event_id": "E06", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 6" }, "verify": { "expressions": [ { "expr": "g_fc11.dynamic_timer_calls", "equals": 1 } ] } }, "task01.static-callback": { "event_id": "E07", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 7" }, "verify": { "expressions": [ { "expr": "g_fc11.static_timer_calls", "equals": 1 } ] } }, "task01.pass": { "event_id": "E08", "stop": { "symbol": "fc11_checkpoint_committed", "offset": 0, "condition": "$a0 == 8" }, "verify": { "expressions": [ { "expr": "g_fc11_pass", "equals": 1 } ] } } }, "sections": [ { "id": "A1", "label": "CONTEXT", "title": "Context", "order": 10, "orientation": "portrait", "description": "Application, kernel and RAM responsibilities are explicit.", "content_tex": "Application, kernel and RAM responsibilities are explicit.", "assets": [ { "stem": "a1-context", "title": "A1 · ownership boundaries", "caption": "A1 CONTEXT — ownership boundaries.", "label": "fig:a1-context", "alt": "ownership boundaries", "phases": [ { "id": "context", "label": "OWNERSHIP BOUNDARIES", "steps": [ { "id": "application", "number": 1, "label": "application owns experiment", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "01", "code_ref": "src/tasks/task01_static_allocation.c:20", "description": "application owns experiment", "evidence": "global experiment" }, { "id": "dynamic", "number": 2, "label": "dynamic APIs request storage", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "02", "code_ref": "src/tasks/task01_static_allocation.c:218", "description": "dynamic APIs request storage", "evidence": "xTaskCreate/xQueueCreate/xTimerCreate" }, { "id": "static", "number": 3, "label": "static APIs receive storage", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "03", "code_ref": "src/tasks/task01_static_allocation.c:239", "description": "static APIs receive storage", "evidence": "named buffers" }, { "id": "kernel", "number": 4, "label": "kernel owns object semantics", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "04", "code_ref": "vendor/FreeRTOS-Kernel/tasks.c:1", "description": "kernel owns object semantics", "evidence": "same scheduler" }, { "id": "ram", "number": 5, "label": "both policies coexist in RAM", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "05", "code_ref": "src/tasks/task01_static_allocation.c:26", "description": "both policies coexist in RAM", "evidence": "ucHeap plus static buffers" } ] } ] } ] }, { "id": "A2", "label": "STRUCTURE", "title": "Structure", "order": 20, "orientation": "landscape", "description": "Task, queue and timer are compared pairwise.", "content_tex": "Task, queue and timer are compared pairwise.", "assets": [ { "stem": "a2-structure", "title": "A2 · object pairs", "caption": "A2 STRUCTURE — object pairs.", "label": "fig:a2-structure", "alt": "object pairs", "phases": [ { "id": "structure", "label": "OBJECT PAIRS", "steps": [ { "id": "dynamic-task", "number": 1, "label": "dynamic task handle is in heap", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.heap", "svg_label": "01", "code_ref": "src/tasks/task01_static_allocation.c:218", "snapshot_ref": "task01.h1", "description": "dynamic task handle is in heap", "evidence": "heap address" }, { "id": "static-task", "number": 2, "label": "static task uses TCB and stack buffers", "mode": "RUN", "event_id": "E03", "strategy_ref": "run.heap", "svg_label": "02", "code_ref": "src/tasks/task01_static_allocation.c:239", "snapshot_ref": "task01.h2", "description": "static task uses TCB and stack buffers", "evidence": "outside heap" }, { "id": "dynamic-queue", "number": 3, "label": "dynamic queue object is in heap", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.heap", "svg_label": "03", "code_ref": "src/tasks/task01_static_allocation.c:228", "snapshot_ref": "task01.h1", "description": "dynamic queue object is in heap", "evidence": "heap address" }, { "id": "static-queue", "number": 4, "label": "static queue uses supplied storage", "mode": "RUN", "event_id": "E03", "strategy_ref": "run.heap", "svg_label": "04", "code_ref": "src/tasks/task01_static_allocation.c:247", "snapshot_ref": "task01.h2", "description": "static queue uses supplied storage", "evidence": "outside heap" }, { "id": "dynamic-timer", "number": 5, "label": "dynamic timer object is in heap", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.heap", "svg_label": "05", "code_ref": "src/tasks/task01_static_allocation.c:229", "snapshot_ref": "task01.h1", "description": "dynamic timer object is in heap", "evidence": "heap address" }, { "id": "static-timer", "number": 6, "label": "static timer uses StaticTimer_t", "mode": "RUN", "event_id": "E03", "strategy_ref": "run.heap", "svg_label": "06", "code_ref": "src/tasks/task01_static_allocation.c:250", "snapshot_ref": "task01.h2", "description": "static timer uses StaticTimer_t", "evidence": "outside heap" }, { "id": "services", "number": 7, "label": "Idle and timer-service storage is static", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "07", "code_ref": "src/tasks/task01_static_allocation.c:45", "description": "Idle and timer-service storage is static", "evidence": "two application callbacks" } ] } ] } ] }, { "id": "A4", "label": "APPLICATION", "title": "Application", "order": 40, "orientation": "portrait", "description": "Storage differs while application behavior remains equal.", "content_tex": "Storage differs while application behavior remains equal.", "assets": [ { "stem": "a4-application", "title": "A4 · behavior parity", "caption": "A4 APPLICATION — behavior parity.", "label": "fig:a4-application", "alt": "behavior parity", "phases": [ { "id": "application", "label": "BEHAVIOR PARITY", "steps": [ { "id": "dynamic-worker", "number": 1, "label": "dynamic branch receives message", "mode": "RUN", "event_id": "E04", "strategy_ref": "run.parity", "svg_label": "01", "code_ref": "src/tasks/task01_static_allocation.c:121", "snapshot_ref": "task01.dynamic-run", "description": "dynamic branch receives message", "evidence": "0xCAFE" }, { "id": "static-worker", "number": 2, "label": "static branch receives message", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.parity", "svg_label": "02", "code_ref": "src/tasks/task01_static_allocation.c:139", "snapshot_ref": "task01.static-run", "description": "static branch receives message", "evidence": "0xCAFE" }, { "id": "daemon", "number": 3, "label": "daemon executes both callbacks", "mode": "RUN", "event_id": "E07", "strategy_ref": "run.parity", "svg_label": "03", "code_ref": "src/tasks/task01_static_allocation.c:99", "snapshot_ref": "task01.static-callback", "description": "daemon executes both callbacks", "evidence": "1 + 1" }, { "id": "verifier", "number": 4, "label": "verifier checks behavior parity", "mode": "RUN", "event_id": "E08", "strategy_ref": "run.parity", "svg_label": "04", "code_ref": "src/tasks/task01_static_allocation.c:157", "snapshot_ref": "task01.pass", "description": "verifier checks behavior parity", "evidence": "PASS" } ] } ] } ] }, { "id": "A5", "label": "FLOW", "title": "Flow", "order": 50, "orientation": "landscape", "description": "H0/H1/H2/H3 bracket creation and scheduler startup.", "content_tex": "H0/H1/H2/H3 bracket creation and scheduler startup.", "assets": [ { "stem": "a5-flow", "title": "A5 · four heap checkpoints", "caption": "A5 FLOW — four heap checkpoints.", "label": "fig:a5-flow", "alt": "four heap checkpoints", "phases": [ { "id": "flow", "label": "FOUR HEAP CHECKPOINTS", "steps": [ { "id": "h0", "number": 1, "label": "H0 baseline", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.heap", "svg_label": "01", "code_ref": "src/tasks/task01_static_allocation.c:214", "snapshot_ref": "task01.h0", "description": "H0 baseline", "evidence": "baseline" }, { "id": "h1", "number": 2, "label": "dynamic objects make H1 smaller", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.heap", "svg_label": "02", "code_ref": "src/tasks/task01_static_allocation.c:236", "snapshot_ref": "task01.h1", "description": "dynamic objects make H1 smaller", "evidence": "H1 < H0" }, { "id": "h2", "number": 3, "label": "static objects leave heap unchanged", "mode": "RUN", "event_id": "E03", "strategy_ref": "run.heap", "svg_label": "03", "code_ref": "src/tasks/task01_static_allocation.c:263", "snapshot_ref": "task01.h2", "description": "static objects leave heap unchanged", "evidence": "H2 = H1" }, { "id": "dynamic-run", "number": 4, "label": "dynamic worker runs", "mode": "RUN", "event_id": "E04", "strategy_ref": "run.parity", "svg_label": "04", "code_ref": "src/tasks/task01_static_allocation.c:121", "snapshot_ref": "task01.dynamic-run", "description": "dynamic worker runs", "evidence": "message" }, { "id": "static-run", "number": 5, "label": "static worker runs", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.parity", "svg_label": "05", "code_ref": "src/tasks/task01_static_allocation.c:139", "snapshot_ref": "task01.static-run", "description": "static worker runs", "evidence": "message" }, { "id": "dynamic-callback", "number": 6, "label": "dynamic timer callback", "mode": "RUN", "event_id": "E06", "strategy_ref": "run.parity", "svg_label": "06", "code_ref": "src/tasks/task01_static_allocation.c:99", "snapshot_ref": "task01.dynamic-callback", "description": "dynamic timer callback", "evidence": "count 1" }, { "id": "static-callback", "number": 7, "label": "static timer callback", "mode": "RUN", "event_id": "E07", "strategy_ref": "run.parity", "svg_label": "07", "code_ref": "src/tasks/task01_static_allocation.c:99", "snapshot_ref": "task01.static-callback", "description": "static timer callback", "evidence": "count 1" }, { "id": "pass", "number": 8, "label": "H3 unchanged and verifier passes", "mode": "RUN", "event_id": "E08", "strategy_ref": "run.parity", "svg_label": "08", "code_ref": "src/tasks/task01_static_allocation.c:157", "snapshot_ref": "task01.pass", "description": "H3 unchanged and verifier passes", "evidence": "H3 = H2" } ] } ], "diagram_kind": "sequence" } ] }, { "id": "A7", "label": "RUNTIME", "title": "Runtime", "order": 70, "orientation": "portrait", "description": "Debugger evidence connects handles to heap or named buffers.", "content_tex": "Debugger evidence connects handles to heap or named buffers.", "assets": [ { "stem": "a7-runtime", "title": "A7 · address provenance", "caption": "A7 RUNTIME — address provenance.", "label": "fig:a7-runtime", "alt": "address provenance", "phases": [ { "id": "runtime", "label": "ADDRESS PROVENANCE", "steps": [ { "id": "heap-arena", "number": 1, "label": "dynamic handles lie in ucHeap", "mode": "RUN", "event_id": "E08", "strategy_ref": "run.heap", "svg_label": "01", "code_ref": "src/tasks/task01_static_allocation.c:174", "snapshot_ref": "task01.pass", "description": "dynamic handles lie in ucHeap", "evidence": "three true predicates" }, { "id": "named-buffers", "number": 2, "label": "static handles lie outside ucHeap", "mode": "RUN", "event_id": "E08", "strategy_ref": "run.heap", "svg_label": "02", "code_ref": "src/tasks/task01_static_allocation.c:177", "snapshot_ref": "task01.pass", "description": "static handles lie outside ucHeap", "evidence": "three false predicates" }, { "id": "service-buffers", "number": 3, "label": "kernel-service buffers are named", "mode": "CODE", "strategy_ref": "code.storage", "svg_label": "03", "code_ref": "src/tasks/task01_static_allocation.c:34", "description": "kernel-service buffers are named", "evidence": "Idle and daemon buffers" }, { "id": "heap-relation", "number": 4, "label": "four checkpoints satisfy relation", "mode": "RUN", "event_id": "E08", "strategy_ref": "run.heap", "svg_label": "04", "code_ref": "include/task01_static_allocation_model.h:34", "snapshot_ref": "task01.pass", "description": "four checkpoints satisfy relation", "evidence": "H1