{ "$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": "E01–E12 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 E01–E12 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 E01–E12 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": "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 E01–E12 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 E01–E12 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" ] }