Files

1270 lines
42 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-04-delay-state",
"series": "freertos-c",
"series_title": "FreeRTOS C",
"number": "04",
"count": "15",
"slug": "delay-state",
"title": "Delay, blokowanie, stany taska i usuwanie",
"topic": "vTaskDelayUntil, Blocked, Suspended i vTaskDelete",
"project": "Freestanding C nad FreeRTOS",
"subject": "Informatyka",
"level": "Rok 2 · L04 · RV32I/Hazard3",
"revision_date": "2026-07-19T00:00:00+02:00",
"status": "Gotowa",
"version": "v00.01",
"uuid": "7691d61c-eaae-5228-b9c8-fa42527b75b9",
"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 systemu",
"status": "unavailable",
"reason": "Granica aplikacjakernelHazard3 nie zmienia się względem FC03."
},
{
"id": "A2",
"label": "STRUCTURE",
"subtitle": "Konteksty i oś wybudzeń",
"status": "enabled",
"target_label": "fig:a2-structure"
},
{
"id": "A3",
"label": "DISPATCH",
"subtitle": "Callback ABI",
"status": "unavailable",
"reason": "TaskFunction_t i void* zostały udowodnione w FC02."
},
{
"id": "A4",
"label": "APPLICATION",
"subtitle": "Topologia",
"status": "unavailable",
"reason": "Topologia trzech tasków jest już kompletna w A2 i A5."
},
{
"id": "A5",
"label": "FLOW",
"subtitle": "E01E10 od startu do PASS",
"status": "enabled",
"target_label": "fig:a5-flow"
},
{
"id": "A6",
"label": "STATE",
"subtitle": "Ready, Running, Blocked, Suspended, Deleted",
"status": "enabled",
"target_label": "fig:a6-state"
},
{
"id": "A7",
"label": "RUNTIME",
"subtitle": "eTaskState, TCB, stack i tick",
"status": "enabled",
"target_label": "fig:a7-runtime"
},
{
"id": "A8",
"label": "PATTERNS",
"subtitle": "Wzorce",
"status": "unavailable",
"reason": "Karta bada semantykę stanu kernela, nie wzorzec aplikacyjny."
}
],
"debug_strategies": {
"code.state-model": {
"id": "code.state-model",
"kind": "code",
"action": "open",
"expected_observations": [
"stan aplikacyjny i eTaskState są osobnymi pojęciami",
"context pozostaje po self-delete"
],
"assertions": [
"Blocked ma warunek wybudzenia",
"Suspended nie ma automatycznego wake tick"
],
"evidence_fields": [
"code_ref",
"typ pola",
"kotwica UML"
],
"prerequisites": [
"źródło FC04"
],
"layout": [
"nagłówek kontekstów",
"kod tasków",
"diagram stanu"
],
"commands": [
"rg -n 'PeriodicContext|SuspendContext|eTaskState|Fc04Phase' include src"
]
},
"run.state": {
"id": "run.state",
"kind": "run",
"action": "replay",
"expected_observations": [
"observer widzi eBlocked i eSuspended",
"resume wybiera wyższy task"
],
"assertions": [
"publiczne handle są ważne podczas obserwacji",
"każdy task czyści własny handle"
],
"evidence_fields": [
"event_id",
"state",
"handle",
"PC",
"SP",
"timestamp"
],
"prerequisites": [
"Hazard3 online",
"czysta RAM"
],
"layout": [
"source",
"eTaskState",
"handle/TCB",
"PC/SP"
],
"commands": [
"print g_periodic",
"print g_suspend_target",
"print g_observer"
]
},
"run.timeline": {
"id": "run.timeline",
"kind": "run",
"action": "replay",
"expected_observations": [
"kolejne delty wynoszą dokładnie 2",
"task jest Blocked między wybudzeniami"
],
"assertions": [
"release count=3",
"SP mieści się w stack range"
],
"evidence_fields": [
"initial tick",
"release ticks",
"SP",
"stack range"
],
"prerequisites": [
"scheduler uruchomiony",
"period=2"
],
"layout": [
"vTaskDelayUntil call",
"wake ticks",
"task stack"
],
"commands": [
"print g_periodic.initial_tick",
"print g_periodic.release_tick",
"print g_periodic.release_count"
]
},
"run.pass": {
"id": "run.pass",
"kind": "run",
"action": "replay",
"expected_observations": [
"timeline 2/4/6",
"resumed=1",
"PASS=1"
],
"assertions": [
"observer uruchamia się po wyższych taskach",
"forensic context nie jest dereferencją usuniętego TCB"
],
"evidence_fields": [
"PASS",
"timeline",
"source blob",
"image hash",
"timestamp"
],
"prerequisites": [
"oba taski robocze zakończone"
],
"layout": [
"contexts",
"timeline",
"final assertions"
],
"commands": [
"print g_fc04_pass",
"print g_periodic",
"print g_suspend_target"
]
}
},
"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": "Delay, blokowanie, stany taska i usuwanie",
"url": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/4a7ef04c-ab08-5783-9192-5b02a90f05f8",
"repository_url": "https://zsl-gitea.mpabi.pl/edu-freertos-c/lab-rv32i-freertos-c-delay-state",
"url_host_uuid": "dce7fb9d-7b2f-5d49-96a2-3a30d3070b84",
"url_domain": "mpabi.pl",
"doc_uuid": "4a7ef04c-ab08-5783-9192-5b02a90f05f8",
"revision": "v00.01",
"issued_on": "2026-07-19T00:00:00+02:00",
"series": "FREERTOS-C-04",
"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ń odróżnia Ready, Running, Blocked, Suspended i Deleted oraz wiąże każdy stan z konkretną przyczyną i publiczną obserwacją FreeRTOS.",
"scope_title": "Zakres karty",
"scope_content_tex": "Task okresowy budzi się co dwa ticki przez vTaskDelayUntil. Drugi task zawiesza się bez warunku czasowego i jest jawnie wznawiany. Observer sprawdza publiczne eTaskState, dokładną oś 2/4/6, osobny stos i bezpieczny zapis przed self-delete.",
"scope_table": {
"headers": [
"Lekcja",
"Task",
"Najważniejsza idea",
"Priorytet",
"Status",
"Version"
],
"rows": [
{
"chapter": "FC04",
"task": "Task01",
"idea_tex": "vTaskDelayUntil, Blocked, Suspended i vTaskDelete",
"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": {
"FC04.EN01": {
"bloom_level": "Analiza",
"label": "Model stanów taska",
"text": "Uczeń rozróżnia Ready, Running, Blocked, Suspended i Deleted oraz przyczynę każdego przejścia.",
"assessment_criteria": [
"FC04.KW01"
]
},
"FC04.EK01": {
"bloom_level": "Zastosowanie",
"label": "Replay delay i resume",
"text": "Uczeń odtwarza E01E10 i wiąże publiczny stan, tick, PC/SP, TCB oraz stos.",
"assessment_criteria": [
"FC04.KW01"
]
}
},
"assessment_criteria": {
"FC04.KW01": {
"text": "Program kończy się PASS; observer widzi eBlocked i eSuspended; timeline ma dokładne delty 2; resume działa raz; context, TCB i stack pozostają rozdzielone.",
"learning_effects": [
"FC04.EN01",
"FC04.EK01"
]
}
},
"educational_requirements": {
"FC04.WE01": {
"text": "Zaprojektowanie i zbadanie deterministycznego eksperymentu delay, suspend, resume i self-delete.",
"label": "vTaskDelayUntil, Blocked, Suspended i vTaskDelete",
"learning_effects": [
"FC04.EN01",
"FC04.EK01"
],
"learning_tree": {
"schema": "we-learning-tree.v1",
"policy": "Każda aktywna kotwica wskazuje kod lub checkpoint.",
"ogolne": [
{
"effect_ref": "FC04.EN01",
"display": "EN LOCAL RTOS.04",
"source": "LOCAL",
"official": "RTOS",
"local": "04",
"kind": "EN",
"tree_id": "FC04.WE01.OG.LOCAL.RTOS.04",
"text": "Uczeń rozróżnia Ready, Running, Blocked, Suspended i Deleted oraz przyczynę każdego przejścia.",
"kw": [
{
"criterion_ref": "FC04.KW01",
"display": "KW LOCAL RTOS.04",
"source": "LOCAL",
"kind": "KW",
"official": "RTOS",
"local": "04",
"text": "Łączy kod, diagram i zweryfikowany dowód."
}
]
}
],
"zawodowe": [
{
"effect_ref": "FC04.EK01",
"display": "EK LOCAL RTOS.04",
"source": "LOCAL",
"official": "RTOS",
"local": "04",
"kind": "EK",
"tree_id": "FC04.WE01.TECH.LOCAL.RTOS.04",
"text": "Uczeń odtwarza E01E10 i wiąże publiczny stan, tick, PC/SP, TCB oraz stos.",
"kw": [
{
"criterion_ref": "FC04.KW01",
"display": "KW LOCAL RTOS.04",
"source": "LOCAL",
"kind": "KW",
"official": "RTOS",
"local": "04",
"text": "Łączy kod, diagram i zweryfikowany dowód."
}
]
}
]
}
}
},
"debug_checkpoints": {
"schema": "stem-debug-checkpoints.v1",
"semantics": "deterministic-replay",
"artifact": {
"source": "src/tasks/task01_delay_state.c",
"source_git_blob": "0a1cbe0370664498693cefb30c22112b9a7ceae6",
"elf": "build/task01_delay_state/prog.elf",
"hazard3_elf_sha256": "14ca6067a49ed05baa8f545a4694e1f6e4c722d9cac06c316d116caf761ef4f6",
"hazard3_image": "build/task01_delay_state/prog.bin",
"hazard3_image_sha256": "9e7091e3ba1389bbc2e2d92b7f87ee1add277c284297df1b62c074410bca16f6"
},
"targets": {
"hazard3-sim": {
"adapter": "hazard3-reset-load-replay.v1",
"baseline": "restart-backend",
"clean_ram": true
}
},
"items": {
"task01.config": {
"event_id": "E01",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 1"
},
"verify": {
"expressions": [
{
"expr": "g_fc04_last_checkpoint",
"equals": 1
},
{
"expr": "g_periodic.handle == 0",
"equals": 1
}
]
}
},
"task01.scheduler": {
"event_id": "E02",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 2"
},
"verify": {
"expressions": [
{
"expr": "g_periodic.handle != 0",
"equals": 1
},
{
"expr": "g_suspend_target.handle != 0",
"equals": 1
},
{
"expr": "g_observer.handle != 0",
"equals": 1
}
]
}
},
"task01.periodic-entry": {
"event_id": "E03",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 3 && $a1 == &g_periodic"
},
"verify": {
"expressions": [
{
"expr": "g_periodic.phase",
"equals": 4
},
{
"expr": "g_periodic.release_count",
"equals": 0
}
]
}
},
"task01.states": {
"event_id": "E04",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 4 && $a1 == &g_observer"
},
"verify": {
"expressions": [
{
"expr": "g_observer.periodic_state",
"equals": 2
},
{
"expr": "g_observer.suspend_state",
"equals": 3
}
]
}
},
"task01.resumed": {
"event_id": "E05",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 5 && $a1 == &g_suspend_target"
},
"verify": {
"expressions": [
{
"expr": "g_suspend_target.resumed",
"equals": 1
},
{
"expr": "g_suspend_target.phase",
"equals": 4
}
]
}
},
"task01.release-1": {
"event_id": "E06",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 6 && $a1 == &g_periodic"
},
"verify": {
"expressions": [
{
"expr": "g_periodic.release_count",
"equals": 1
},
{
"expr": "g_periodic.release_tick[0] - g_periodic.initial_tick",
"equals": 2
}
]
}
},
"task01.release-2": {
"event_id": "E07",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 7 && $a1 == &g_periodic"
},
"verify": {
"expressions": [
{
"expr": "g_periodic.release_count",
"equals": 2
},
{
"expr": "g_periodic.release_tick[1] - g_periodic.release_tick[0]",
"equals": 2
}
]
}
},
"task01.release-3": {
"event_id": "E08",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 8 && $a1 == &g_periodic"
},
"verify": {
"expressions": [
{
"expr": "g_periodic.release_count",
"equals": 3
},
{
"expr": "g_periodic.release_tick[2] - g_periodic.release_tick[1]",
"equals": 2
}
]
}
},
"task01.periodic-finished": {
"event_id": "E09",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 9 && $a1 == &g_periodic"
},
"verify": {
"expressions": [
{
"expr": "g_periodic.phase",
"equals": 5
},
{
"expr": "g_periodic.handle == 0",
"equals": 1
}
]
}
},
"task01.pass": {
"event_id": "E10",
"stop": {
"symbol": "fc04_checkpoint_committed",
"offset": 0,
"condition": "$a0 == 10 && $a1 == &g_observer"
},
"verify": {
"expressions": [
{
"expr": "g_fc04_pass",
"equals": 1
},
{
"expr": "g_suspend_target.resumed",
"equals": 1
},
{
"expr": "g_periodic.release_count",
"equals": 3
}
]
}
}
}
},
"sections": [
{
"title": "A2 — Structure",
"order": 20,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "Konteksty aplikacyjne przechowują uchwyty, stan diagnostyczny i bounded evidence; nie kopiują prywatnych list kernela.",
"assets": [
{
"path": "assets/a2-structure.png",
"html_path": "assets/a2-structure.svg",
"source_path": "assets/a2-structure.puml",
"caption": "A2 STRUCTURE — trzy konteksty i absolutna oś wybudzeń.",
"label": "fig:a2-structure",
"alt": "PeriodicContext, SuspendContext, ObserverContext i timeline.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"periodic": 1,
"suspend": 1,
"observer": 1,
"timeline": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc04-a2-structure",
"title": "A2 · konteksty i timeline",
"task": {
"id": "task01",
"label": "Task01 · delay i stany"
},
"block": {
"id": "a2",
"label": "A2 STRUCTURE",
"description": "Konteksty C i ograniczona oś czasu."
},
"phases": [
{
"id": "contexts",
"label": "CONTEXTS / TIMELINE",
"steps": [
{
"id": "periodic",
"number": 1,
"label": "periodic context owns wake evidence",
"mode": "CODE",
"strategy_ref": "code.state-model",
"svg_label": "01",
"svg_target": "Periodic",
"code_ref": "include/task01_delay_state.h:23",
"description": "Context zachowuje t0 i trzy release ticks.",
"evidence": "Static storage przeżywa self-delete."
},
{
"id": "suspend",
"number": 2,
"label": "suspend context records explicit resume",
"mode": "CODE",
"strategy_ref": "code.state-model",
"svg_label": "02",
"svg_target": "Suspend",
"code_ref": "include/task01_delay_state.h:37",
"description": "Suspended nie ma time-based wake.",
"evidence": "resumed zmienia się wyłącznie po vTaskResume."
},
{
"id": "observer",
"number": 3,
"label": "observer stores public eTaskState",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.state",
"svg_label": "03",
"svg_target": "Observer",
"code_ref": "src/tasks/task01_delay_state.c:150",
"snapshot_ref": "task01.states",
"description": "Publiczne API odróżnia Blocked i Suspended.",
"evidence": "eBlocked oraz eSuspended."
},
{
"id": "timeline",
"number": 4,
"label": "absolute timeline has exact deltas",
"mode": "RUN",
"event_id": "E10",
"strategy_ref": "run.timeline",
"svg_label": "04",
"svg_target": "Timeline",
"code_ref": "src/tasks/task01_delay_state.c:168",
"snapshot_ref": "task01.pass",
"description": "Deltas nie zależą od momentu powrotu z pracy.",
"evidence": "t0, t0+2, t0+4, t0+6."
}
]
}
]
}
}
]
},
{
"title": "A5 — Flow",
"order": 40,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "Sekwencja pokazuje przyczynę każdego przejścia i jawny moment zapisu dowodu.",
"assets": [
{
"path": "assets/a5-flow.png",
"html_path": "assets/a5-flow.svg",
"source_path": "assets/a5-flow.puml",
"caption": "A5 FLOW — od konfiguracji do okresowych wybudzeń i PASS.",
"label": "fig:a5-flow",
"alt": "Sekwencja periodic, suspend target, observer i scheduler.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"config": 1,
"scheduler": 1,
"periodic-entry": 1,
"states": 1,
"resumed": 1,
"release-1": 1,
"release-2": 1,
"release-3": 1,
"periodic-finished": 1,
"pass": 1
}
},
"interactive": {
"kind": "uml-sequence",
"storage_key": "fc04-a5-flow",
"title": "A5 · delay i resume",
"task": {
"id": "task01",
"label": "Task01 · delay i stany"
},
"block": {
"id": "a5",
"label": "A5 FLOW",
"description": "Jeden deterministyczny przebieg E01E10."
},
"phases": [
{
"id": "replay",
"label": "DELAY / STATE / DELETE",
"steps": [
{
"id": "config",
"number": 1,
"label": "configuration committed",
"mode": "RUN",
"event_id": "E01",
"strategy_ref": "run.state",
"svg_label": "01",
"code_ref": "src/tasks/task01_delay_state.c:227",
"snapshot_ref": "task01.config",
"description": "Czysta RAM i konfiguracja FC04.",
"evidence": "Brak uchwytów przed create."
},
{
"id": "scheduler",
"number": 2,
"label": "three tasks created",
"mode": "RUN",
"event_id": "E02",
"strategy_ref": "run.state",
"svg_label": "02",
"code_ref": "src/tasks/task01_delay_state.c:256",
"snapshot_ref": "task01.scheduler",
"description": "Wszystkie publiczne handle są ważne.",
"evidence": "Priorytety 3,2,1."
},
{
"id": "periodic-entry",
"number": 3,
"label": "periodic starts and blocks",
"mode": "RUN",
"event_id": "E03",
"strategy_ref": "run.timeline",
"svg_label": "03",
"code_ref": "src/tasks/task01_delay_state.c:87",
"snapshot_ref": "task01.periodic-entry",
"description": "t0 jest punktem odniesienia vTaskDelayUntil.",
"evidence": "release_count=0."
},
{
"id": "states",
"number": 4,
"label": "observer sees Blocked and Suspended",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.state",
"svg_label": "04",
"code_ref": "src/tasks/task01_delay_state.c:150",
"snapshot_ref": "task01.states",
"description": "Oba stany mają różną przyczynę.",
"evidence": "eBlocked i eSuspended."
},
{
"id": "resumed",
"number": 5,
"label": "target resumes and self-deletes",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.state",
"svg_label": "05",
"code_ref": "src/tasks/task01_delay_state.c:122",
"snapshot_ref": "task01.resumed",
"description": "Wyższy priorytet preemptuje observera.",
"evidence": "resumed=1."
},
{
"id": "release-1",
"number": 6,
"label": "release at t0 plus 2",
"mode": "RUN",
"event_id": "E06",
"strategy_ref": "run.timeline",
"svg_label": "06",
"code_ref": "src/tasks/task01_delay_state.c:96",
"snapshot_ref": "task01.release-1",
"description": "Pierwszy absolute wake.",
"evidence": "delta=2."
},
{
"id": "release-2",
"number": 7,
"label": "release at t0 plus 4",
"mode": "RUN",
"event_id": "E07",
"strategy_ref": "run.timeline",
"svg_label": "07",
"code_ref": "src/tasks/task01_delay_state.c:96",
"snapshot_ref": "task01.release-2",
"description": "Drugi absolute wake.",
"evidence": "delta=2."
},
{
"id": "release-3",
"number": 8,
"label": "release at t0 plus 6",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.timeline",
"svg_label": "08",
"code_ref": "src/tasks/task01_delay_state.c:96",
"snapshot_ref": "task01.release-3",
"description": "Trzeci absolute wake.",
"evidence": "delta=2."
},
{
"id": "periodic-finished",
"number": 9,
"label": "periodic clears handle before delete",
"mode": "RUN",
"event_id": "E09",
"strategy_ref": "run.state",
"svg_label": "09",
"code_ref": "src/tasks/task01_delay_state.c:99",
"snapshot_ref": "task01.periodic-finished",
"description": "Context zachowuje forensic values.",
"evidence": "phase=COMPLETED, handle=NULL."
},
{
"id": "pass",
"number": 10,
"label": "observer verifies PASS",
"mode": "RUN",
"event_id": "E10",
"strategy_ref": "run.pass",
"svg_label": "10",
"code_ref": "src/tasks/task01_delay_state.c:192",
"snapshot_ref": "task01.pass",
"description": "Observer sprawdza stany, timeline i stack.",
"evidence": "PASS=1."
}
]
}
]
}
}
]
},
{
"title": "A6 — State",
"order": 50,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "Blocked ma warunek czasu lub zdarzenia; Suspended wymaga jawnego resume. Deleted nie oznacza natychmiastowego wymazania wszystkich śladów.",
"assets": [
{
"path": "assets/a6-state.png",
"html_path": "assets/a6-state.svg",
"source_path": "assets/a6-state.puml",
"caption": "A6 STATE — Ready, Running, Blocked, Suspended i Deleted.",
"label": "fig:a6-state",
"alt": "Maszyna stanów taska FreeRTOS.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"ready": 1,
"running": 1,
"blocked": 1,
"suspended": 1,
"resumed-ready": 1,
"completed": 1,
"deleted": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc04-a6-state",
"title": "A6 · stany taska",
"task": {
"id": "task01",
"label": "Task01 · delay i stany"
},
"block": {
"id": "a6",
"label": "A6 STATE",
"description": "Przyczyny przejść między stanami taska."
},
"phases": [
{
"id": "states",
"label": "TASK STATE",
"steps": [
{
"id": "ready",
"number": 1,
"label": "Ready waits for selection",
"mode": "RUN",
"event_id": "E02",
"strategy_ref": "run.state",
"svg_label": "01",
"code_ref": "src/tasks/task01_delay_state.c:229",
"snapshot_ref": "task01.scheduler",
"description": "Created nie znaczy Running.",
"evidence": "handle ważny przed startem."
},
{
"id": "running",
"number": 2,
"label": "highest Ready task runs",
"mode": "RUN",
"event_id": "E03",
"strategy_ref": "run.state",
"svg_label": "02",
"code_ref": "src/tasks/task01_delay_state.c:72",
"snapshot_ref": "task01.periodic-entry",
"description": "Periodic ma priorytet 3.",
"evidence": "PC/SP w periodic."
},
{
"id": "blocked",
"number": 3,
"label": "delay moves task to Blocked",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.state",
"svg_label": "03",
"code_ref": "src/tasks/task01_delay_state.c:92",
"snapshot_ref": "task01.states",
"description": "Wake tick istnieje.",
"evidence": "eBlocked."
},
{
"id": "suspended",
"number": 4,
"label": "self-suspend has no wake tick",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.state",
"svg_label": "04",
"code_ref": "src/tasks/task01_delay_state.c:118",
"snapshot_ref": "task01.states",
"description": "Tylko jawne resume przywraca Ready.",
"evidence": "eSuspended."
},
{
"id": "resumed-ready",
"number": 5,
"label": "resume makes target Ready",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.state",
"svg_label": "05",
"code_ref": "src/tasks/task01_delay_state.c:160",
"snapshot_ref": "task01.resumed",
"description": "Priorytet 2 wyprzedza observera 1.",
"evidence": "target Running po resume."
},
{
"id": "completed",
"number": 6,
"label": "application records completion",
"mode": "RUN",
"event_id": "E09",
"strategy_ref": "run.state",
"svg_label": "06",
"code_ref": "src/tasks/task01_delay_state.c:99",
"snapshot_ref": "task01.periodic-finished",
"description": "COMPLETED jest stanem diagnostycznym aplikacji.",
"evidence": "Zapis przed delete."
},
{
"id": "deleted",
"number": 7,
"label": "self-delete delegates cleanup",
"mode": "RUN",
"event_id": "E10",
"strategy_ref": "run.pass",
"svg_label": "07",
"code_ref": "src/tasks/task01_delay_state.c:102",
"snapshot_ref": "task01.pass",
"description": "Idle może później odzyskać TCB/stack.",
"evidence": "Context static pozostaje."
}
]
}
]
}
}
]
},
{
"title": "A7 — Runtime",
"order": 60,
"content_kind": "prose",
"asset_page_mode": "one-per-page",
"page_orientation": "landscape",
"content_tex": "A7 wiąże publiczne eTaskState z pamięcią taska i bounded evidence, bez uzależniania programu od pxCurrentTCB.",
"assets": [
{
"path": "assets/a7-runtime.png",
"html_path": "assets/a7-runtime.svg",
"source_path": "assets/a7-runtime.puml",
"caption": "A7 RUNTIME — stany publiczne, task memory, wake ticks i PASS.",
"label": "fig:a7-runtime",
"alt": "Runtime evidence dla delay i suspend.",
"kind": "diagram",
"width": 1.0,
"page_grid": {
"columns": 1,
"rows": 1,
"page_width": 940,
"page_height": 560,
"overview": true,
"step_tiles": {
"public": 1,
"periodic-runtime": 1,
"wake": 1,
"suspend-runtime": 1,
"evidence": 1
}
},
"interactive": {
"kind": "uml-class",
"storage_key": "fc04-a7-runtime",
"title": "A7 · runtime evidence",
"task": {
"id": "task01",
"label": "Task01 · delay i stany"
},
"block": {
"id": "a7",
"label": "A7 RUNTIME",
"description": "Publiczny stan, TCB/stack i oś ticków."
},
"phases": [
{
"id": "runtime",
"label": "STATE / MEMORY / TIME",
"steps": [
{
"id": "public",
"number": 1,
"label": "public API exposes two states",
"mode": "RUN",
"event_id": "E04",
"strategy_ref": "run.state",
"svg_label": "01",
"svg_target": "Public",
"code_ref": "src/tasks/task01_delay_state.c:150",
"snapshot_ref": "task01.states",
"description": "Program nie czyta prywatnych list.",
"evidence": "eBlocked, eSuspended."
},
{
"id": "periodic-runtime",
"number": 2,
"label": "periodic has separate TCB and stack",
"mode": "RUN",
"event_id": "E03",
"strategy_ref": "run.timeline",
"svg_label": "02",
"svg_target": "Periodic",
"code_ref": "src/tasks/task01_delay_state.c:59",
"snapshot_ref": "task01.periodic-entry",
"description": "SP należy do task stack.",
"evidence": "created_handle i stack range."
},
{
"id": "wake",
"number": 3,
"label": "absolute wake timeline is exact",
"mode": "RUN",
"event_id": "E08",
"strategy_ref": "run.timeline",
"svg_label": "03",
"svg_target": "Wake",
"code_ref": "src/tasks/task01_delay_state.c:96",
"snapshot_ref": "task01.release-3",
"description": "Trzy wybudzenia zachowują okres.",
"evidence": "2/4/6."
},
{
"id": "suspend-runtime",
"number": 4,
"label": "suspended task resumes explicitly",
"mode": "RUN",
"event_id": "E05",
"strategy_ref": "run.state",
"svg_label": "04",
"svg_target": "Suspend",
"code_ref": "src/tasks/task01_delay_state.c:107",
"snapshot_ref": "task01.resumed",
"description": "Brak time-based wake.",
"evidence": "resumed=1."
},
{
"id": "evidence",
"number": 5,
"label": "forensic evidence remains bounded",
"mode": "RUN",
"event_id": "E10",
"strategy_ref": "run.pass",
"svg_label": "05",
"svg_target": "Evidence",
"code_ref": "src/tasks/task01_delay_state.c:192",
"snapshot_ref": "task01.pass",
"description": "Snapshot wiąże wynik ze źródłem i ELF.",
"evidence": "PASS, source blob, image hash, timestamp."
}
]
}
]
}
}
]
},
{
"title": "Task01 — delay i stany",
"order": 90,
"content_kind": "tasks",
"task_refs": [
"task01"
]
}
],
"tasks": {
"task01": {
"title": "Delay, blokowanie, zawieszenie i self-delete",
"uuid": "4a7ef04c-ab08-5783-9192-5b02a90f05f8",
"prompt_tex": "Przejdź po A2, A5, A6 i A7. Odtwórz E01E10, rozróżnij Blocked od Suspended i udowodnij dokładny okres vTaskDelayUntil.",
"criterion": "Program kończy się PASS; observer widzi eBlocked i eSuspended; timeline ma dokładne delty 2; resume działa raz; context, TCB i stack pozostają rozdzielone.",
"conclusion_tex": "Blocked task ma warunek wybudzenia, Suspended wymaga jawnego resume, a vTaskDelayUntil utrzymuje absolutną fazę okresu. Self-delete kończy task, lecz aplikacyjny context może zachować bounded forensic evidence.",
"flow": [
{
"kind": "block",
"id": "state-model",
"title": "A — model stanów",
"content_tex": "Najpierw przewidź przyczynę i wyjście z każdego stanu.",
"steps": [
{
"id": "classify",
"title": "Sklasyfikuj Blocked i Suspended.",
"content_tex": "Wskaż warunek automatycznego wybudzenia albo jego brak."
},
{
"id": "predict",
"title": "Przewidź oś czasu.",
"content_tex": "Zapisz oczekiwane t0+2, t0+4 i t0+6."
}
]
},
{
"kind": "block",
"id": "runtime-replay",
"title": "B — replay Hazard3",
"content_tex": "Każdy RUN zaczyna się od czystej RAM.",
"steps": [
{
"id": "observe",
"title": "Zbadaj E04.",
"content_tex": "Zapisz publiczne stany obu tasków i ich przyczyny."
},
{
"id": "resume",
"title": "Zbadaj E05.",
"content_tex": "Wyjaśnij, dlaczego target preemptuje observera."
},
{
"id": "timeline",
"title": "Zbadaj E06E08.",
"content_tex": "Policz delty release ticks i sprawdź stack taska."
},
{
"id": "finish",
"title": "Zbadaj E09E10.",
"content_tex": "Oddziel application completion od cleanup kernela."
}
]
},
{
"kind": "exercise",
"id": "relative-delay-drift",
"title": "Ćwiczenie — względny delay i dryf",
"prompt_tex": "Zastąp vTaskDelayUntil przez vTaskDelay i dodaj bounded workload trwający jeden tick po każdym wybudzeniu. Zmierz trzy release ticks i porównaj fazę z wersją bazową.",
"evidence_tex": "Timestampowane snapshoty release ticks oraz krótka tabela różnic względem 2/4/6.",
"criterion": "Uczeń poprawnie wyjaśnia, dlaczego relative delay kumuluje czas pracy i przesuwa fazę.",
"based_on": [
"state-model",
"runtime-replay"
]
}
],
"educational_requirement_refs": [
"FC04.WE01"
],
"learning_effect_refs": [
"FC04.EN01",
"FC04.EK01"
],
"assessment_criterion_ref": "FC04.KW01"
}
},
"tasks_order": [
"task01"
]
}