Files

1489 lines
49 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.
{
"$schema": "../../../tools/card-layouts/schemas/card-source.schema.json",
"schema": "esc-card-source.v1",
"card": {
"id": "mpabi-freertos-c-10-notifications",
"series": "freertos-c",
"series_title": "FreeRTOS C",
"number": "10",
"count": "15",
"slug": "notifications",
"title": "Direct-to-task notifications",
"topic": "count, overwrite, set bits i target-owned slot",
"project": "Freestanding C nad FreeRTOS",
"subject": "Informatyka",
"level": "Rok 2 · L10 · RV32I/Hazard3",
"revision_date": "2026-07-19T00:00:00+02:00",
"status": "Gotowa",
"version": "v00.01",
"uuid": "8632c2af-76f9-51b2-84f8-e7baaf6eaf03",
"author": "M. Pabiszczak",
"year": "2026"
},
"generated": {
"tex": "doc/generated/main.tex",
"html": "web/index.html",
"html_css": "web/style.css",
"html_tree_inspector": false,
"react_app": true
},
"render_dictionary": false,
"viewpoints": [
{
"id": "A1",
"label": "CONTEXT",
"subtitle": "Granice",
"status": "unavailable",
"reason": "Brak nowej granicy sprzętowej."
},
{
"id": "A2",
"label": "STRUCTURE",
"subtitle": "Target-owned slot 0",
"status": "enabled",
"target_label": "fig:a2-structure"
},
{
"id": "A3",
"label": "DISPATCH",
"subtitle": "TaskHandle_t → target TCB",
"status": "enabled",
"target_label": "fig:a3-dispatch"
},
{
"id": "A4",
"label": "APPLICATION",
"subtitle": "Topologia",
"status": "unavailable",
"reason": "Sender/receiver topology jest kompletna w A2 i A5."
},
{
"id": "A5",
"label": "FLOW",
"subtitle": "E01E12 three protocols",
"status": "enabled",
"target_label": "fig:a5-flow"
},
{
"id": "A6",
"label": "STATE",
"subtitle": "Value plus pending state",
"status": "enabled",
"target_label": "fig:a6-state"
},
{
"id": "A7",
"label": "RUNTIME",
"subtitle": "Public states, stacks and TCB slot",
"status": "enabled",
"target_label": "fig:a7-runtime"
},
{
"id": "A8",
"label": "PATTERNS",
"subtitle": "Count, latest value and flags",
"status": "enabled",
"target_label": "fig:a8-patterns"
}
],
"debug_strategies": {
"code.contract": {
"id": "code.contract",
"kind": "code",
"action": "open",
"expected_observations": [
"one index",
"three explicit actions"
],
"assertions": [
"no queue/event group API",
"fixed target handle"
],
"evidence_fields": [
"API",
"action",
"code_ref"
],
"prerequisites": [
"źródło FC10"
],
"layout": [
"notification config",
"sender/receiver",
"no object storage"
],
"commands": [
"rg -n 'configUSE_TASK_NOTIFICATIONS|xTaskNotify|ulTaskNotify' include src"
]
},
"run.blocked": {
"id": "run.blocked",
"kind": "run",
"action": "replay",
"expected_observations": [
"eBlocked before each batch",
"p3 sender cannot be preempted by p2 receiver"
],
"assertions": [
"finite phase wait",
"three state proofs"
],
"evidence_fields": [
"phase",
"state",
"PC",
"SP",
"timestamp"
],
"prerequisites": [
"clean Hazard3 RAM"
],
"layout": [
"receiver phase/state",
"sender priority",
"event log"
],
"commands": [
"print g_fc10.receiver_phase",
"print g_fc10.receiver_state_before_count"
]
},
"run.values": {
"id": "run.values",
"kind": "run",
"action": "replay",
"expected_observations": [
"3",
"0x22",
"0x24"
],
"assertions": [
"clear probes all 1",
"single receiver"
],
"evidence_fields": [
"value",
"clear",
"event order"
],
"prerequisites": [
"receiver blocked"
],
"layout": [
"count/overwrite/bits result",
"clear probes"
],
"commands": [
"print/x g_fc10.count_result",
"print/x g_fc10.overwrite_result",
"print/x g_fc10.bits_result"
]
},
"run.pass": {
"id": "run.pass",
"kind": "run",
"action": "replay",
"expected_observations": [
"PASS=1",
"12 events"
],
"assertions": [
"three-run deterministic",
"distinct stacks"
],
"evidence_fields": [
"PASS",
"digest",
"hashes",
"timestamp"
],
"prerequisites": [
"sender and receiver done"
],
"layout": [
"PASS",
"bounded records",
"digest"
],
"commands": [
"print g_fc10_pass",
"print g_fc10.evidence_digest"
]
}
},
"template": "templates/karta-klasyczna.json",
"title_block": {
"category": "KARTA PRACY · INFORMATYKA",
"prepared_by": "M. Pabiszczak",
"prepared_on": "2026-07-19T00:00:00+02:00",
"title": "Direct-to-task notifications",
"url": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/3b57334e-2c35-5207-a51d-9321906db078",
"repository_url": "https://zsl-gitea.mpabi.pl/edu-freertos-c/lab-rv32i-freertos-c-notifications",
"url_host_uuid": "dce7fb9d-7b2f-5d49-96a2-3a30d3070b84",
"url_domain": "mpabi.pl",
"doc_uuid": "3b57334e-2c35-5207-a51d-9321906db078",
"revision": "v00.01",
"issued_on": "2026-07-19T00:00:00+02:00",
"series": "FREERTOS-C-10",
"document_type": "karta pracy",
"tool": "card-layouts",
"show_qr": true,
"show_repository_qr": true,
"height_cm": 2.6,
"repeat_on_every_page": true,
"replace_front_matter": true
},
"front_page_scope": {
"title": "Cel karty",
"content_tex": "Uczeń dobiera akcję notification do kontraktu informacji i odróżnia wartość slotu od stanu pending.",
"scope_title": "Zakres karty",
"scope_content_tex": "Jeden receiver i jeden slot index 0 przechodzą kolejno przez counting=3, overwrite=0x22 i bit-set=0x24. Sender p3 publikuje dopiero po potwierdzeniu receivera w eBlocked. Zero-time probe potwierdza wyczyszczenie slotu między fazami. Brak kolejki, semafora i EventGroup.",
"scope_table": {
"headers": [
"Lekcja",
"Task",
"Najważniejsza idea",
"Priorytet",
"Status",
"Version"
],
"rows": [
{
"chapter": "FC10",
"task": "Task01",
"idea_tex": "count, overwrite, set bits i target-owned slot",
"priority": "główny",
"status": "ready",
"version": "v00.01",
"key": true
}
]
}
},
"side_margin_tree_layout": {
"columns": [
{
"id": "zawodowe",
"label": "TECH",
"side": "left",
"tree": "WE -> EK -> KW",
"description": "Dowody runtime."
},
{
"id": "ogolne",
"label": "OG",
"side": "right",
"tree": "WE -> EN -> KW",
"description": "Model FreeRTOS C."
}
]
},
"learning_effects": {
"FC10.EN01": {
"bloom_level": "Analiza",
"label": "Model slotu notification",
"text": "Uczeń rozdziela target binding, pending state, value and action semantics.",
"assessment_criteria": [
"FC10.KW01"
]
},
"FC10.EK01": {
"bloom_level": "Zastosowanie",
"label": "Replay three modes",
"text": "Uczeń odtwarza E01E12 i pokazuje eBlocked, 3, 0x22, 0x24, clear probes, stacks and digest.",
"assessment_criteria": [
"FC10.KW01"
]
}
},
"assessment_criteria": {
"FC10.KW01": {
"text": "PASS; receiver Blocked before each batch; results 3/0x22/0x24; three clear probes; deterministic digest.",
"learning_effects": [
"FC10.EN01",
"FC10.EK01"
]
}
},
"educational_requirements": {
"FC10.WE01": {
"text": "Dobór i zbadanie direct-to-task notification bez ukrytego obiektu synchronizacyjnego.",
"label": "count, overwrite, set bits i target-owned slot",
"learning_effects": [
"FC10.EN01",
"FC10.EK01"
],
"learning_tree": {
"schema": "we-learning-tree.v1",
"policy": "Każda aktywna kotwica wskazuje kod lub checkpoint.",
"ogolne": [
{
"effect_ref": "FC10.EN01",
"display": "EN LOCAL RTOS.10",
"source": "LOCAL",
"official": "RTOS",
"local": "10",
"kind": "EN",
"tree_id": "FC10.WE01.OG.LOCAL.RTOS.10",
"text": "Uczeń rozdziela target binding, pending state, value and action semantics.",
"kw": [
{
"criterion_ref": "FC10.KW01",
"display": "KW LOCAL RTOS.10",
"source": "LOCAL",
"kind": "KW",
"official": "RTOS",
"local": "10",
"text": "Łączy kod, diagram i zweryfikowany dowód."
}
]
}
],
"zawodowe": [
{
"effect_ref": "FC10.EK01",
"display": "EK LOCAL RTOS.10",
"source": "LOCAL",
"official": "RTOS",
"local": "10",
"kind": "EK",
"tree_id": "FC10.WE01.TECH.LOCAL.RTOS.10",
"text": "Uczeń odtwarza E01E12 i pokazuje eBlocked, 3, 0x22, 0x24, clear probes, stacks and digest.",
"kw": [
{
"criterion_ref": "FC10.KW01",
"display": "KW LOCAL RTOS.10",
"source": "LOCAL",
"kind": "KW",
"official": "RTOS",
"local": "10",
"text": "Łączy kod, diagram i zweryfikowany dowód."
}
]
}
]
}
}
},
"debug_checkpoints": {
"schema": "stem-debug-checkpoints.v1",
"semantics": "deterministic-replay",
"artifact": {
"source": "src/tasks/task01_notifications.c",
"source_git_blob": "bea15a9a59917776316a92ca3317879836937225",
"elf": "build/task01_notifications/prog.elf",
"hazard3_elf_sha256": "856b4a35b1cb6f1fadb11965cd94c56a64e8656eb6ae1718c3c39ab9726794b0",
"hazard3_image": "build/task01_notifications/prog.bin",
"hazard3_image_sha256": "f792e07c27afc3564e04bf2071e231510a6099d9cbb4f2f432932f05319de906"
},
"targets": {
"hazard3-sim": {
"adapter": "hazard3-reset-load-replay.v1",
"baseline": "restart-backend",
"clean_ram": true
}
},
"items": {
"task01.config": {
"event_id": "E01",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 1"
},
"verify": {
"expressions": [
{
"expr": "g_fc10_event_count",
"equals": 1
}
]
}
},
"task01.sender-armed": {
"event_id": "E02",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 2"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.sender_sp != 0",
"equals": 1
}
]
}
},
"task01.wait-count": {
"event_id": "E03",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 3"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.receiver_phase",
"equals": 1
},
{
"expr": "g_fc10.receiver_sp != 0",
"equals": 1
}
]
}
},
"task01.post-count": {
"event_id": "E04",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 4"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.receiver_state_before_count",
"equals": 2
}
]
}
},
"task01.receive-count": {
"event_id": "E05",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 5"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.count_result",
"equals": 3
}
]
}
},
"task01.wait-overwrite": {
"event_id": "E06",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 6"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.clear_after_count",
"equals": 1
}
]
}
},
"task01.post-overwrite": {
"event_id": "E07",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 7"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.receiver_state_before_overwrite",
"equals": 2
}
]
}
},
"task01.receive-overwrite": {
"event_id": "E08",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 8"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.overwrite_result",
"equals": 34
}
]
}
},
"task01.wait-bits": {
"event_id": "E09",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 9"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.clear_after_overwrite",
"equals": 1
}
]
}
},
"task01.post-bits": {
"event_id": "E10",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 10"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.receiver_state_before_bits",
"equals": 2
}
]
}
},
"task01.receive-bits": {
"event_id": "E11",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 11"
},
"verify": {
"expressions": [
{
"expr": "g_fc10.bits_result",
"equals": 36
},
{
"expr": "g_fc10.clear_after_bits",
"equals": 1
}
]
}
},
"task01.pass": {
"event_id": "E12",
"stop": {
"symbol": "fc10_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 12"
},
"verify": {
"expressions": [
{
"expr": "g_fc10_pass",
"equals": 1
},
{
"expr": "g_fc10_event_count",
"equals": 12
}
]
}
}
}
},
"sections": [
{
"title": "A2 — Structure",
"order": 20,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "\\texttt{TaskHandle\\_t} selects one target TCB and index 0. Count, overwrite and bits are three actions on the same value/state pair.",
"assets": [
{
"path": "assets/a2-structure.png",
"html_path": "assets/a2-structure.svg",
"source_path": "assets/a2-structure.puml",
"caption": "A2 STRUCTURE — receiver TCB notification slot.",
"label": "fig:a2-structure",
"alt": "Struktura direct notification.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"sender": 1,
"receiver": 1,
"count": 1,
"overwrite": 1,
"bits": 1,
"absent": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc10-a2-structure",
"title": "A2 · target-owned slot",
"task": {
"id": "task01",
"label": "Task01 · notification modes"
},
"block": {
"id": "a2",
"label": "A2 STRUCTURE",
"description": "Notification state lives in the target task, not in an intermediary object."
},
"phases": [
{
"id": "structure",
"label": "SENDER / TARGET / MODES",
"steps": [
{
"id": "sender",
"number": 1,
"label": "sender stores target handle",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "01",
"code_ref": "include/task01_notifications.h:24",
"description": "No shared object handle is created.",
"evidence": "receiver_handle."
},
{
"id": "receiver",
"number": 2,
"label": "slot belongs to receiver TCB",
"mode": "RUN",
"event_id": "E03",
"strategy_ref": "run.blocked",
"svg_label": "02",
"code_ref": "src/tasks/task01_notifications.c:153",
"snapshot_ref": "task01.wait-count",
"description": "Only receiver consumes slot 0.",
"evidence": "receiver stack and phase."
},
{
"id": "count",
"number": 3,
"label": "counting accumulates occurrences",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.values",
"svg_label": "03",
"code_ref": "src/tasks/task01_notifications.c:164",
"snapshot_ref": "task01.receive-count",
"description": "pdTRUE returns and clears all three.",
"evidence": "3."
},
{
"id": "overwrite",
"number": 4,
"label": "overwrite keeps latest value",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.values",
"svg_label": "04",
"code_ref": "src/tasks/task01_notifications.c:177",
"snapshot_ref": "task01.receive-overwrite",
"description": "0x11 is intentionally lost.",
"evidence": "0x22."
},
{
"id": "bits",
"number": 5,
"label": "set bits combines flags",
"mode": "RUN",
"event_id": "E11",
"strategy_ref": "run.values",
"svg_label": "05",
"code_ref": "src/tasks/task01_notifications.c:196",
"snapshot_ref": "task01.receive-bits",
"description": "OR semantics.",
"evidence": "0x24."
},
{
"id": "absent",
"number": 6,
"label": "no intermediary kernel object",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "06",
"code_ref": "src/tasks/task01_notifications.c:260",
"description": "No create API except tasks.",
"evidence": "link and source inspection."
}
]
}
]
}
}
]
},
{
"title": "A3 — Dispatch",
"order": 30,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "portrait",
"content_tex": "xTaskGenericNotify receives target handle, index and action. Only the selected target can move from Blocked to Ready.",
"assets": [
{
"path": "assets/a3-dispatch.png",
"html_path": "assets/a3-dispatch.svg",
"source_path": "assets/a3-dispatch.puml",
"caption": "A3 DISPATCH — handle to TCB slot 0.",
"label": "fig:a3-dispatch",
"alt": "Dispatch direct notification.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 660,
"page_height": 760,
"overview": true,
"step_tiles": {
"sender": 1,
"handle": 1,
"api": 1,
"tcb": 1,
"ready": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc10-a3-dispatch",
"title": "A3 · target dispatch",
"task": {
"id": "task01",
"label": "Task01 · notification modes"
},
"block": {
"id": "a3",
"label": "A3 DISPATCH",
"description": "A handle binds the action to one target slot."
},
"phases": [
{
"id": "dispatch",
"label": "HANDLE / ACTION / TARGET",
"steps": [
{
"id": "sender",
"number": 1,
"label": "sender chooses protocol action",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "01",
"code_ref": "src/tasks/task01_notifications.c:118",
"description": "Give, overwrite or bits.",
"evidence": "three call sites."
},
{
"id": "handle",
"number": 2,
"label": "receiver_handle fixes recipient",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "02",
"code_ref": "src/tasks/task01_notifications.c:118",
"description": "Not broadcast.",
"evidence": "one TaskHandle_t."
},
{
"id": "api",
"number": 3,
"label": "generic API updates index 0",
"mode": "RUN",
"event_id": "E07",
"strategy_ref": "run.values",
"svg_label": "03",
"code_ref": "src/tasks/task01_notifications.c:124",
"snapshot_ref": "task01.post-overwrite",
"description": "Action controls information loss.",
"evidence": "latest value 0x22."
},
{
"id": "tcb",
"number": 4,
"label": "value and pending are distinct",
"mode": "RUN",
"event_id": "E09",
"strategy_ref": "run.values",
"svg_label": "04",
"code_ref": "src/tasks/task01_notifications.c:188",
"snapshot_ref": "task01.wait-bits",
"description": "Clear probe demonstrates value zero.",
"evidence": "probe=1."
},
{
"id": "ready",
"number": 5,
"label": "only blocked receiver wakes",
"mode": "RUN",
"event_id": "E10",
"strategy_ref": "run.blocked",
"svg_label": "05",
"code_ref": "src/tasks/task01_notifications.c:134",
"snapshot_ref": "task01.post-bits",
"description": "State captured before post.",
"evidence": "eBlocked."
}
]
}
]
}
}
]
},
{
"title": "A5 — Flow",
"order": 40,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "Phase and eBlocked handshakes prevent the receiver from running between posts while the p3 sender accumulates or combines values.",
"assets": [
{
"path": "assets/a5-flow.png",
"html_path": "assets/a5-flow.svg",
"source_path": "assets/a5-flow.puml",
"caption": "A5 FLOW — count, overwrite and bits.",
"label": "fig:a5-flow",
"alt": "Sekwencja direct notifications.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"config": 1,
"arm": 1,
"wait-count": 1,
"post-count": 1,
"count": 1,
"wait-overwrite": 1,
"post-overwrite": 1,
"overwrite": 1,
"wait-bits": 1,
"post-bits": 1,
"bits": 1,
"pass": 1
}
},
"interactive": {
"kind": "uml-sequence",
"storage_key": "fc10-a5-flow",
"title": "A5 · three notification modes",
"task": {
"id": "task01",
"label": "Task01 · notification modes"
},
"block": {
"id": "a5",
"label": "A5 FLOW",
"description": "Complete E01E12 run through three protocols."
},
"phases": [
{
"id": "flow",
"label": "COUNT / OVERWRITE / BITS / PASS",
"steps": [
{
"id": "config",
"number": 1,
"label": "clean slot contract",
"mode": "RUN",
"event_id": "E01",
"strategy_ref": "run.blocked",
"svg_label": "01",
"code_ref": "src/tasks/task01_notifications.c:263",
"snapshot_ref": "task01.config",
"description": "One index configured.",
"evidence": "event count 1."
},
{
"id": "arm",
"number": 2,
"label": "sender waits for phase and Blocked",
"mode": "RUN",
"event_id": "E02",
"strategy_ref": "run.blocked",
"svg_label": "02",
"code_ref": "src/tasks/task01_notifications.c:115",
"snapshot_ref": "task01.sender-armed",
"description": "No timing-only synchronization.",
"evidence": "sender SP."
},
{
"id": "wait-count",
"number": 3,
"label": "receiver waits for count",
"mode": "RUN",
"event_id": "E03",
"strategy_ref": "run.blocked",
"svg_label": "03",
"code_ref": "src/tasks/task01_notifications.c:162",
"snapshot_ref": "task01.wait-count",
"description": "Phase 1.",
"evidence": "receiver SP."
},
{
"id": "post-count",
"number": 4,
"label": "three gives while receiver Blocked",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.blocked",
"svg_label": "04",
"code_ref": "src/tasks/task01_notifications.c:116",
"snapshot_ref": "task01.post-count",
"description": "p3 posts without receiver interleave.",
"evidence": "state eBlocked."
},
{
"id": "count",
"number": 5,
"label": "take returns 3",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.values",
"svg_label": "05",
"code_ref": "src/tasks/task01_notifications.c:164",
"snapshot_ref": "task01.receive-count",
"description": "Clear all count.",
"evidence": "3."
},
{
"id": "wait-overwrite",
"number": 6,
"label": "slot zero before overwrite",
"mode": "RUN",
"event_id": "E06",
"strategy_ref": "run.values",
"svg_label": "06",
"code_ref": "src/tasks/task01_notifications.c:169",
"snapshot_ref": "task01.wait-overwrite",
"description": "Zero-time probe.",
"evidence": "clear=1."
},
{
"id": "post-overwrite",
"number": 7,
"label": "latest value wins",
"mode": "RUN",
"event_id": "E07",
"strategy_ref": "run.blocked",
"svg_label": "07",
"code_ref": "src/tasks/task01_notifications.c:124",
"snapshot_ref": "task01.post-overwrite",
"description": "0x11 then 0x22.",
"evidence": "receiver Blocked."
},
{
"id": "overwrite",
"number": 8,
"label": "wait returns 0x22",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.values",
"svg_label": "08",
"code_ref": "src/tasks/task01_notifications.c:177",
"snapshot_ref": "task01.receive-overwrite",
"description": "Intermediate state lost by contract.",
"evidence": "34."
},
{
"id": "wait-bits",
"number": 9,
"label": "slot zero before bit phase",
"mode": "RUN",
"event_id": "E09",
"strategy_ref": "run.values",
"svg_label": "09",
"code_ref": "src/tasks/task01_notifications.c:188",
"snapshot_ref": "task01.wait-bits",
"description": "Second clear proof.",
"evidence": "clear=1."
},
{
"id": "post-bits",
"number": 10,
"label": "two flags OR while Blocked",
"mode": "RUN",
"event_id": "E10",
"strategy_ref": "run.blocked",
"svg_label": "10",
"code_ref": "src/tasks/task01_notifications.c:136",
"snapshot_ref": "task01.post-bits",
"description": "0x04 and 0x20.",
"evidence": "state eBlocked."
},
{
"id": "bits",
"number": 11,
"label": "wait returns 0x24",
"mode": "RUN",
"event_id": "E11",
"strategy_ref": "run.values",
"svg_label": "11",
"code_ref": "src/tasks/task01_notifications.c:196",
"snapshot_ref": "task01.receive-bits",
"description": "Both flags preserved.",
"evidence": "36 and clear=1."
},
{
"id": "pass",
"number": 12,
"label": "verifier commits PASS",
"mode": "RUN",
"event_id": "E12",
"strategy_ref": "run.pass",
"svg_label": "12",
"code_ref": "src/tasks/task01_notifications.c:234",
"snapshot_ref": "task01.pass",
"description": "All three contracts hold.",
"evidence": "digest c60747cb."
}
]
}
]
}
}
]
},
{
"title": "A6 — State",
"order": 50,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "portrait",
"content_tex": "A pending notification can contain different values according to action. Consume/clear semantics are selected separately by receive API arguments.",
"assets": [
{
"path": "assets/a6-state.png",
"html_path": "assets/a6-state.svg",
"source_path": "assets/a6-state.puml",
"caption": "A6 STATE — value and pending across three phases.",
"label": "fig:a6-state",
"alt": "Maszyna stanu notification.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 660,
"page_height": 760,
"overview": true,
"step_tiles": {
"clear": 1,
"count": 1,
"overwrite": 1,
"bits": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc10-a6-state",
"title": "A6 · notification state",
"task": {
"id": "task01",
"label": "Task01 · notification modes"
},
"block": {
"id": "a6",
"label": "A6 STATE",
"description": "Notification value and pending state are not synonyms."
},
"phases": [
{
"id": "state",
"label": "CLEAR / WAITING / PENDING / CONSUMED",
"steps": [
{
"id": "clear",
"number": 1,
"label": "slot begins clear",
"mode": "RUN",
"event_id": "E01",
"strategy_ref": "run.values",
"svg_label": "01",
"code_ref": "src/tasks/task01_notifications.c:263",
"snapshot_ref": "task01.config",
"description": "Value zero, not pending.",
"evidence": "clean RAM."
},
{
"id": "count",
"number": 4,
"label": "three increments create count 3",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.values",
"svg_label": "04",
"code_ref": "src/tasks/task01_notifications.c:118",
"snapshot_ref": "task01.receive-count",
"description": "pdTRUE clears whole count.",
"evidence": "3 then zero."
},
{
"id": "overwrite",
"number": 7,
"label": "overwrite replaces prior value",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.values",
"svg_label": "07",
"code_ref": "src/tasks/task01_notifications.c:124",
"snapshot_ref": "task01.receive-overwrite",
"description": "Latest state semantics.",
"evidence": "0x22."
},
{
"id": "bits",
"number": 10,
"label": "set bits combines flags",
"mode": "RUN",
"event_id": "E11",
"strategy_ref": "run.values",
"svg_label": "10",
"code_ref": "src/tasks/task01_notifications.c:136",
"snapshot_ref": "task01.receive-bits",
"description": "OR semantics.",
"evidence": "0x24 then zero."
}
]
}
]
}
}
]
},
{
"title": "A7 — Runtime",
"order": 60,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "Acceptance does not read private TCB fields. GDB may correlate ulNotifiedValue and ucNotifyState with the public results and source lines.",
"assets": [
{
"path": "assets/a7-runtime.png",
"html_path": "assets/a7-runtime.svg",
"source_path": "assets/a7-runtime.puml",
"caption": "A7 RUNTIME — task stacks and notification slot.",
"label": "fig:a7-runtime",
"alt": "Runtime direct notifications.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"exp": 1,
"sender": 1,
"receiver": 1,
"slot": 1,
"absent": 1,
"log": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc10-a7-runtime",
"title": "A7 · runtime evidence",
"task": {
"id": "task01",
"label": "Task01 · notification modes"
},
"block": {
"id": "a7",
"label": "A7 RUNTIME",
"description": "Public state proves blocking; TCB slot is debugger-only evidence."
},
"phases": [
{
"id": "runtime",
"label": "EXPERIMENT / TASKS / SLOT / LOG",
"steps": [
{
"id": "exp",
"number": 1,
"label": "g_fc10 stores public results",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "01",
"code_ref": "include/task01_notifications.h:22",
"description": "Persistent evidence object.",
"evidence": "states, values, probes."
},
{
"id": "sender",
"number": 2,
"label": "sender p3 owns distinct stack",
"mode": "RUN",
"event_id": "E02",
"strategy_ref": "run.blocked",
"svg_label": "02",
"code_ref": "src/tasks/task01_notifications.c:114",
"snapshot_ref": "task01.sender-armed",
"description": "Posting context.",
"evidence": "sender_sp."
},
{
"id": "receiver",
"number": 3,
"label": "receiver is public eBlocked",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.blocked",
"svg_label": "03",
"code_ref": "src/tasks/task01_notifications.c:116",
"snapshot_ref": "task01.post-count",
"description": "No private state assertion.",
"evidence": "receiver_sp and eBlocked."
},
{
"id": "slot",
"number": 4,
"label": "TCB slot is debugger evidence",
"mode": "RUN",
"event_id": "E07",
"strategy_ref": "run.values",
"svg_label": "04",
"code_ref": "vendor/FreeRTOS-Kernel/tasks.c:7800",
"snapshot_ref": "task01.post-overwrite",
"description": "Inspect value/state, do not depend on layout.",
"evidence": "0x22 pending."
},
{
"id": "absent",
"number": 5,
"label": "no queue or EventGroup object",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "05",
"code_ref": "src/tasks/task01_notifications.c:260",
"description": "Direct path is part of topology.",
"evidence": "source and symbols."
},
{
"id": "log",
"number": 6,
"label": "twelve commit-last records",
"mode": "RUN",
"event_id": "E12",
"strategy_ref": "run.pass",
"svg_label": "06",
"code_ref": "src/tasks/task01_notifications.c:53",
"snapshot_ref": "task01.pass",
"description": "Stable evidence chain.",
"evidence": "digest."
}
]
}
]
}
}
]
},
{
"title": "A8 — Patterns",
"order": 70,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "Count preserves multiplicity, overwrite preserves only latest state, and set-bits preserves a set of flags. None is a broadcast or general message queue.",
"assets": [
{
"path": "assets/a8-patterns.png",
"html_path": "assets/a8-patterns.svg",
"source_path": "assets/a8-patterns.puml",
"caption": "A8 PATTERNS — count, latest value and flags.",
"label": "fig:a8-patterns",
"alt": "Wzorce notification actions.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"count": 1,
"overwrite": 1,
"bits": 1,
"limits": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc10-a8-patterns",
"title": "A8 · notification contracts",
"task": {
"id": "task01",
"label": "Task01 · notification modes"
},
"block": {
"id": "a8",
"label": "A8 PATTERNS",
"description": "Choose action by what information may be lost."
},
"phases": [
{
"id": "patterns",
"label": "COUNT / LATEST / FLAGS / LIMITS",
"steps": [
{
"id": "count",
"number": 1,
"label": "count preserves occurrences",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.values",
"svg_label": "01",
"code_ref": "src/tasks/task01_notifications.c:164",
"snapshot_ref": "task01.receive-count",
"description": "Choose clear-all or decrement-one.",
"evidence": "3."
},
{
"id": "overwrite",
"number": 2,
"label": "overwrite preserves latest only",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.values",
"svg_label": "02",
"code_ref": "src/tasks/task01_notifications.c:124",
"snapshot_ref": "task01.receive-overwrite",
"description": "0x11 may be lost intentionally.",
"evidence": "0x22."
},
{
"id": "bits",
"number": 3,
"label": "bits preserve independent flags",
"mode": "RUN",
"event_id": "E11",
"strategy_ref": "run.values",
"svg_label": "03",
"code_ref": "src/tasks/task01_notifications.c:136",
"snapshot_ref": "task01.receive-bits",
"description": "OR combines flags.",
"evidence": "0x24."
},
{
"id": "limits",
"number": 4,
"label": "slot is not queue or broadcast",
"mode": "CODE",
"strategy_ref": "code.contract",
"svg_label": "04",
"code_ref": "doc/card-plan.md:1",
"description": "One target consumes its own slot.",
"evidence": "explicit limitation."
}
]
}
]
}
}
]
},
{
"title": "Task01 — notification modes",
"order": 90,
"content_kind": "tasks",
"task_refs": [
"task01"
]
}
],
"tasks": {
"task01": {
"title": "Count, overwrite i bit flags na jednym slocie",
"uuid": "3b57334e-2c35-5207-a51d-9321906db078",
"prompt_tex": "Przejdź po A2, A3, A5, A6, A7 i A8. Odtwórz E01E12 i wyjaśnij, jaką informację zachowuje i traci każda akcja.",
"criterion": "PASS; receiver Blocked before each batch; results 3/0x22/0x24; three clear probes; deterministic digest.",
"conclusion_tex": "Direct notification jest szybkim protokołem skierowanym do jednego taska. Poprawność zależy od jawnego wyboru semantyki wartości, pending i clear.",
"flow": [
{
"kind": "block",
"id": "predict",
"title": "A — kontrakty informacji",
"content_tex": "Przewidź wynik każdej pary API.",
"steps": [
{
"id": "values",
"title": "Zapisz 3, 0x22 i 0x24.",
"content_tex": "Wskaż, dlaczego 0x11 nie musi być obserwowalne."
},
{
"id": "clear",
"title": "Rozdziel value i pending.",
"content_tex": "Opisz działanie pdTRUE oraz bits-to-clear."
}
]
},
{
"kind": "block",
"id": "replay",
"title": "B — replay Hazard3",
"content_tex": "Każdy RUN startuje od clean RAM.",
"steps": [
{
"id": "blocked",
"title": "Zbadaj E03/E06/E09.",
"content_tex": "Potwierdź receiver phase i Blocked."
},
{
"id": "results",
"title": "Zbadaj E05/E08/E11.",
"content_tex": "Porównaj wyniki i clear probes."
},
{
"id": "pass",
"title": "Zbadaj E12.",
"content_tex": "Zapisz PASS, SP i digest."
}
]
},
{
"kind": "exercise",
"id": "choose-action",
"title": "Ćwiczenie — dobór akcji",
"prompt_tex": "Dla licznika impulsów, najnowszej nastawy i dwóch niezależnych alarmów dobierz give/take, overwrite albo set-bits. Zapisz kontrakt utraty informacji.",
"evidence_tex": "Tabela protocol→action→clear oraz trzy krótkie ślady.",
"criterion": "Każdy wybór zachowuje dokładnie informację wymaganą przez protokół.",
"based_on": [
"predict",
"replay"
]
}
],
"educational_requirement_refs": [
"FC10.WE01"
],
"learning_effect_refs": [
"FC10.EN01",
"FC10.EK01"
],
"assessment_criterion_ref": "FC10.KW01"
}
},
"tasks_order": [
"task01"
]
}