Files

864 lines
28 KiB
JSON
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.
{
"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<H0; H2=H1; H3=H2"
},
{
"id": "evidence",
"number": 5,
"label": "commit-last evidence is deterministic",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.parity",
"svg_label": "05",
"code_ref": "src/tasks/task01_static_allocation.c:72",
"snapshot_ref": "task01.pass",
"description": "commit-last evidence is deterministic",
"evidence": "cdf44a0a"
}
]
}
]
}
]
}
],
"learning": {
"model_label": "Storage ownership",
"model": "Uczeń rozdziela semantykę obiektu i politykę przechowywania.",
"replay_label": "Heap replay",
"replay": "Uczeń odtwarza E01E08 i dowodzi H1<H0, H2=H1, H3=H2.",
"criterion": "PASS; address provenance; message and callback parity; deterministic digest.",
"requirement": "Porównanie dynamicznej i statycznej polityki pamięci obiektów FreeRTOS."
},
"task": {
"short_label": "two storage policies",
"title": "Same behavior, two storage policies",
"prompt_tex": "Przejdź po A1, A2, A4, A5 i A7. Odtwórz E01E08 oraz udowodnij relacje H1<H0, H2=H1 i H3=H2.",
"conclusion_tex": "Statyczne API zmienia własność pamięci, ale nie semantykę taska, kolejki ani timera.",
"flow": [
{
"kind": "block",
"id": "predict",
"title": "A — przewidywanie",
"content_tex": "Przewidź cztery pomiary heap.",
"steps": [
{
"id": "relation",
"title": "Zapisz relacje H0H3.",
"content_tex": "Nie zakładaj dokładnej liczby bajtów."
},
{
"id": "ownership",
"title": "Wskaż właściciela pamięci.",
"content_tex": "Rozdziel ucHeap i named buffers."
}
]
},
{
"kind": "block",
"id": "replay",
"title": "B — replay Hazard3",
"content_tex": "Wykonaj E01E08 z clean RAM.",
"steps": [
{
"id": "heap",
"title": "Zbadaj H0/H1/H2/H3.",
"content_tex": "Zapisz wartości i relacje."
},
{
"id": "parity",
"title": "Zbadaj obie gałęzie.",
"content_tex": "Porównaj message, timer callback i stack."
},
{
"id": "pass",
"title": "Zbadaj E08.",
"content_tex": "Zapisz PASS, digest i timestamp."
}
]
},
{
"kind": "exercise",
"id": "choose-policy",
"title": "Ćwiczenie — wybór polityki",
"prompt_tex": "Dla taska okresowego, kolejki telemetrycznej i timera bezpieczeństwa wybierz dynamiczne albo statyczne tworzenie. Uzasadnij lifetime i ownership.",
"evidence_tex": "Tabela obiekt→API→storage→lifetime oraz ślad H0H3.",
"criterion": "Każdy bufor ma trwałość co najmniej tak długą jak obiekt kernelowy.",
"based_on": [
"predict",
"replay"
]
}
]
}
}