Files
lab-rv32i-c-interrupts/json/card_source.json
T
2026-07-21 19:14:20 +02:00

668 lines
33 KiB
JSON
Raw 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-inf-c-10-traps-interrupt-control",
"series": "c",
"series_title": "C · Freestanding RV32I and K&R",
"number": "10",
"count": "13",
"slug": "traps-interrupt-control",
"title": "Pułapki i sterowanie przerwaniami RV32I",
"topic": "ecall, mepc, mcause, machine software IRQ oraz bramki mie/mstatus",
"project": "Freestanding C na RV32I",
"subject": "Informatyka",
"level": "Rok 1 · C10 · RV32I/Hazard3",
"revision_date": "2026-07-20T00:00:00+02:00",
"status": "Gotowa",
"version": "v00.01",
"uuid": "ec04ecee-1c4d-529a-a4e2-d3f9b40700ec",
"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,
"template": "templates/karta-klasyczna.json",
"title_block": {
"category": "KARTA PRACY · INFORMATYKA",
"prepared_by": "M. Pabiszczak",
"prepared_on": "2026-07-20T00:00:00+02:00",
"title": "Pułapki i sterowanie przerwaniami RV32I",
"url": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/8fb9c110-557b-5081-8ae2-a56800f872e8",
"repository_url": "https://zsl-gitea.mpabi.pl/edu-inf/lab-rv32i-c-interrupts",
"url_host_uuid": "dce7fb9d-7b2f-5d49-96a2-3a30d3070b84",
"url_domain": "mpabi.pl",
"doc_uuid": "8fb9c110-557b-5081-8ae2-a56800f872e8",
"revision": "v00.01",
"issued_on": "2026-07-20T00:00:00+02:00",
"series": "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_break": true,
"front_page_scope": {
"title": "Cel karty",
"content_tex": "Uczeń odróżnia synchroniczny wyjątek od asynchronicznego przerwania, wyprowadza adres wznowienia z mepc oraz dowodzi, że samo pending nie wystarcza bez indywidualnej i globalnej bramki enable.",
"scope_title": "Zakres i zachowane przykłady",
"scope_content_tex": "Trzy obrazy RV32I działają na rzeczywistym modelu Hazard3. Task01 wykonuje \\texttt{ecall}; Task02 używa kontrolowanego machine software interrupt; Task03 mierzy macierz pending, \\texttt{mie.MSIE} i \\texttt{mstatus.MIE}. Peryferia pojawiają się dopiero w C12 i C13.\\par\\textbf{Układ każdego przykładu:} pełny profil A1--A8; widok N/D ma jawny powód, a diagram nie jest wymagany, gdy tekst daje lepszy dowód.",
"scope_table": {
"headers": [
"Typ",
"Task",
"Idea",
"Waga"
],
"rows": [
{
"chapter": "ECALL",
"task": "Task01",
"idea_tex": "synchroniczny cause 11, mepc i mret",
"priority": "kluczowe",
"key": true
},
{
"chapter": "MSIP",
"task": "Task02",
"idea_tex": "MSIP, MSIE, MIE, vector 3 i mret",
"priority": "kluczowe",
"key": true
},
{
"chapter": "GATE",
"task": "Task03",
"idea_tex": "to samo źródło, dwie niezależne bramki",
"priority": "kluczowe",
"key": true
}
]
}
},
"side_margin_tree_layout": {
"columns": [
{
"id": "zawodowe",
"label": "TECH",
"side": "left",
"tree": "WE -> EK -> KW",
"description": "Kod C, ABI i obserwacja RV32I."
},
{
"id": "ogolne",
"label": "OG",
"side": "right",
"tree": "WE -> EN -> KW",
"description": "Przewidywanie, pomiar i wniosek."
}
]
},
"learning_effects": {
"C10.EN01": {
"bloom_level": "Analiza",
"label": "Cause, gate i resume",
"text": "Uczeń osobno zapisuje źródło zdarzenia, mcause, mepc, stan pending, obie bramki enable i efekt po mret.",
"assessment_criteria": [
"C10.KW01"
]
},
"C10.EK01": {
"bloom_level": "Zastosowanie",
"label": "Pułapka widoczna w listingu",
"text": "Uczeń uruchamia trzy obrazy Hazard3 i wiąże raporty runtime z instrukcjami ecall, CSR, wektorami i mret.",
"assessment_criteria": [
"C10.KW01"
]
}
},
"assessment_criteria": {
"C10.KW01": {
"text": "Task01: jeden ecall daje mcause=11, mepc jest zwiększone o 4 i kod normalny wznawia pracę. Task02: software IRQ ma mcause=0x80000003, pending 1 przed i w ISR, 0 po clear oraz jedno wznowienie. Task03: pending pozostaje zablokowane osobno bez MSIE i bez MIE, a jest dostarczone dokładnie raz dopiero z obiema bramkami.",
"learning_effects": [
"C10.EN01",
"C10.EK01"
]
}
},
"educational_requirements": {
"C10.WE01": {
"text": "Konfiguracja i analiza machine-mode trap z jawnym kontraktem źródła, pending, enable, handlera i adresu wznowienia.",
"label": "ecall, mepc, mcause, machine software IRQ oraz bramki mie/mstatus",
"learning_effects": [
"C10.EN01",
"C10.EK01"
],
"learning_tree": {
"schema": "we-learning-tree.v1",
"policy": "Najpierw przewidywanie, następnie wykonanie i odczyt dowodu.",
"ogolne": [
{
"effect_ref": "C10.EN01",
"display": "EN C10 01",
"source": "LOCAL",
"official": "C",
"local": "01",
"kind": "EN",
"tree_id": "C10.WE01.OG.LOCAL.C.01",
"text": "Uczeń osobno zapisuje źródło zdarzenia, mcause, mepc, stan pending, obie bramki enable i efekt po mret.",
"kw": [
{
"criterion_ref": "C10.KW01",
"display": "KW C10 01",
"source": "LOCAL",
"kind": "KW",
"official": "C",
"local": "01",
"text": "Kod, przewidywanie i pomiar tworzą jeden dowód."
}
]
}
],
"zawodowe": [
{
"effect_ref": "C10.EK01",
"display": "EK C10 01",
"source": "LOCAL",
"official": "C",
"local": "01",
"kind": "EK",
"tree_id": "C10.WE01.TECH.LOCAL.C.01",
"text": "Uczeń uruchamia trzy obrazy Hazard3 i wiąże raporty runtime z instrukcjami ecall, CSR, wektorami i mret.",
"kw": [
{
"criterion_ref": "C10.KW01",
"display": "KW C10 01",
"source": "LOCAL",
"kind": "KW",
"official": "C",
"local": "01",
"text": "Kod, przewidywanie i pomiar tworzą jeden dowód."
}
]
}
]
}
}
},
"sections": [
{
"title": "1 — Wyjątek synchroniczny wskazuje instrukcję",
"order": 10,
"content_kind": "prose",
"page_orientation": "portrait",
"content_tex": "\\texttt{ecall} jest wykonywany przez bieżący strumień instrukcji, więc \\texttt{mcause=11} nie ma ustawionego bitu interrupt, a \\texttt{mepc} wskazuje samo \\texttt{ecall}. Handler Task01 świadomie zapisuje \\texttt{mepc+4}; bez tego \\texttt{mret} wykonałby ponownie tę samą instrukcję. Taka polityka jest poprawna dla tego kontrolowanego ECALL, ale nie wolno automatycznie pomijać instrukcji przy każdym błędzie.",
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_refs": [
"C10.KW01"
]
},
{
"title": "2 — Software IRQ jest asynchronicznym źródłem poziomowym",
"order": 20,
"content_kind": "prose",
"page_orientation": "portrait",
"content_tex": "Testbench ustawia MSIP hart0, a rdzeń widzi \\texttt{mip.MSIP}. Dostarczenie wymaga dodatkowo \\texttt{mie.MSIE=1} i \\texttt{mstatus.MIE=1}. Wektor 3 prowadzi do \\texttt{isr\\_machine\\_softirq}; handler odczytuje \\texttt{mcause=0x80000003}, usuwa źródło i dopiero potem publikuje licznik. \\texttt{mret} wraca do przerwanego kodu, a nie do instrukcji wybranej ręcznie przez aplikację.",
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_refs": [
"C10.KW01"
]
},
{
"title": "3 — Pending i enable odpowiadają na inne pytania",
"order": 30,
"content_kind": "prose",
"page_orientation": "portrait",
"content_tex": "Pending mówi, że źródło żąda obsługi. \\texttt{mie.MSIE} dopuszcza konkretną klasę, a \\texttt{mstatus.MIE} otwiera globalną bramkę machine mode. Task03 utrzymuje to samo pending i kolejno sprawdza dwa stany z jedną zamkniętą bramką oraz stan z obiema otwartymi. Dzięki temu kod 0 dowodzi całej macierzy, a nie tylko tego, że ISR kiedyś się wykonał.",
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_refs": [
"C10.KW01"
]
},
{
"title": "Zadania — zachowane przykłady w profilu A1A8",
"order": 40,
"content_kind": "tasks",
"page_orientation": "portrait",
"task_refs": [
"task01",
"task02",
"task03"
],
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_refs": [
"C10.KW01"
]
}
],
"tasks": {
"task01": {
"title": "ECALL i wznowienie pod mepc+4",
"uuid": "2cd1da12-b916-5def-b868-da4b13ff9089",
"prompt_tex": "Przed uruchomieniem przewidź bit interrupt i kod mcause, wskaż wartość mepc oraz adres wznowienia. Wyjaśnij, co stałoby się bez zapisu mepc+4.",
"criterion": "Hazard3: count=1, mcause=0x0000000b, resume_pc-mepc=4, resumed=1, pass=1 i kod 0.",
"conclusion_tex": "",
"render_task_acceptance": false,
"viewpoints": [
{
"id": "A1",
"status": "enabled",
"title": "CONTEXT — kontrolowany wyjątek M-mode",
"content_tex": "Granica zaczyna się na instrukcji \\texttt{ecall} w main i kończy po powrocie do kolejnej instrukcji. Nie ma zewnętrznego peryferium ani pending IRQ; rdzeń sam tworzy synchroniczną pułapkę."
},
{
"id": "A2",
"status": "enabled",
"title": "STRUCTURE — mcause, mepc i mtvec",
"content_tex": "\\texttt{mcause} zapisuje klasę 11 bez bitu interrupt, \\texttt{mepc} zapisuje adres ECALL, a baza \\texttt{mtvec} prowadzi wszystkie synchroniczne wyjątki do \\texttt{handle\\_exception}. Handler publikuje oryginał i osobny adres wznowienia."
},
{
"id": "A3",
"status": "enabled",
"title": "DISPATCH — synchroniczny slot mtvec",
"content_tex": "Sprzęt wybiera bazowy slot wektora, ponieważ zdarzenie jest wyjątkiem, nie IRQ. \\texttt{handle\\_exception} odczytuje mcause i obsługuje jedyny dopuszczony przypadek ECALL. To granica trap dispatch, choć nie ma tablicy callbacków."
},
{
"id": "A4",
"status": "enabled",
"title": "APPLICATION — cause 11 i stały krok 4",
"content_tex": "ECALL w RV32I jest instrukcją 32-bitową, dlatego dla tego przykładu poprawny resume ma wartość \\texttt{mepc+4}. Gate wymaga jednego wejścia, cause 11, delty 4 i ustawienia resumed dopiero po mret."
},
{
"id": "A5",
"status": "enabled",
"title": "FLOW — ecall, save, patch, mret",
"content_tex": "Normalny kod wykonuje ECALL. Rdzeń zapisuje mepc/mcause, skacze do wektora, handler odczytuje oba CSR i zapisuje nowe mepc. Epilog \\texttt{interrupt(\"machine\")} kończy się mret; dopiero potem main zapisuje resumed."
},
{
"id": "A6",
"status": "enabled",
"title": "STATE — RUNNING, TRAP, RESUMED",
"content_tex": "Stan przechodzi \\texttt{RUNNING -> TRAP(mepc=ecall,cause=11) -> RESUMED(pc=mepc+4)}. Licznik 1 odróżnia pojedyncze wznowienie od pętli ponownego wykonywania ECALL."
},
{
"id": "A7",
"status": "enabled",
"title": "RUNTIME — ecall i mret w ELF",
"content_tex": "Oracle porównuje raportowane adresy i niezależnie wymaga różnicy 4. Objdump musi pokazać \\texttt{ecall} w main oraz \\texttt{mret} w handlerze. Segmenty LOAD pozostają rozdzielone R-X/R-W."
},
{
"id": "A8",
"status": "enabled",
"title": "PATTERNS — explicit resume policy",
"content_tex": "Wzorzec handlera wyjątku obejmuje jawną decyzję: retry, skip albo terminate. Task01 wybiera skip tylko dla znanego ECALL. Dla faultu pamięci bezwarunkowe mepc+4 mogłoby ukryć błąd i jest niedozwolone."
}
],
"flow": [
{
"kind": "block",
"id": "task01.a1",
"title": "A1 CONTEXT · AKTYWNE — kontrolowany wyjątek M-mode",
"content_tex": "\\textbf{Zachowany przykład:} \\nolinkurl{src/tasks/task01_ecall_resume.c}.\\par Granica zaczyna się na instrukcji \\texttt{ecall} w main i kończy po powrocie do kolejnej instrukcji. Nie ma zewnętrznego peryferium ani pending IRQ; rdzeń sam tworzy synchroniczną pułapkę."
},
{
"kind": "block",
"id": "task01.a2",
"title": "A2 STRUCTURE · AKTYWNE — mcause, mepc i mtvec",
"content_tex": "\\texttt{mcause} zapisuje klasę 11 bez bitu interrupt, \\texttt{mepc} zapisuje adres ECALL, a baza \\texttt{mtvec} prowadzi wszystkie synchroniczne wyjątki do \\texttt{handle\\_exception}. Handler publikuje oryginał i osobny adres wznowienia."
},
{
"kind": "block",
"id": "task01.a3",
"title": "A3 DISPATCH · AKTYWNE — synchroniczny slot mtvec",
"content_tex": "Sprzęt wybiera bazowy slot wektora, ponieważ zdarzenie jest wyjątkiem, nie IRQ. \\texttt{handle\\_exception} odczytuje mcause i obsługuje jedyny dopuszczony przypadek ECALL. To granica trap dispatch, choć nie ma tablicy callbacków."
},
{
"kind": "block",
"id": "task01.a4",
"title": "A4 APPLICATION · AKTYWNE — cause 11 i stały krok 4",
"content_tex": "ECALL w RV32I jest instrukcją 32-bitową, dlatego dla tego przykładu poprawny resume ma wartość \\texttt{mepc+4}. Gate wymaga jednego wejścia, cause 11, delty 4 i ustawienia resumed dopiero po mret."
},
{
"kind": "block",
"id": "task01.a5",
"title": "A5 FLOW · AKTYWNE — ecall, save, patch, mret",
"content_tex": "Normalny kod wykonuje ECALL. Rdzeń zapisuje mepc/mcause, skacze do wektora, handler odczytuje oba CSR i zapisuje nowe mepc. Epilog \\texttt{interrupt(\"machine\")} kończy się mret; dopiero potem main zapisuje resumed."
},
{
"kind": "block",
"id": "task01.a6",
"title": "A6 STATE · AKTYWNE — RUNNING, TRAP, RESUMED",
"content_tex": "Stan przechodzi \\texttt{RUNNING -> TRAP(mepc=ecall,cause=11) -> RESUMED(pc=mepc+4)}. Licznik 1 odróżnia pojedyncze wznowienie od pętli ponownego wykonywania ECALL."
},
{
"kind": "block",
"id": "task01.a7",
"title": "A7 RUNTIME · AKTYWNE — ecall i mret w ELF",
"content_tex": "Oracle porównuje raportowane adresy i niezależnie wymaga różnicy 4. Objdump musi pokazać \\texttt{ecall} w main oraz \\texttt{mret} w handlerze. Segmenty LOAD pozostają rozdzielone R-X/R-W."
},
{
"kind": "block",
"id": "task01.a8",
"title": "A8 PATTERNS · AKTYWNE — explicit resume policy",
"content_tex": "Wzorzec handlera wyjątku obejmuje jawną decyzję: retry, skip albo terminate. Task01 wybiera skip tylko dla znanego ECALL. Dla faultu pamięci bezwarunkowe mepc+4 mogłoby ukryć błąd i jest niedozwolone."
},
{
"kind": "exercise",
"id": "task01.proof",
"title": "Przewidywanie → wykonanie → wniosek",
"prompt_tex": "Przed uruchomieniem przewidź bit interrupt i kod mcause, wskaż wartość mepc oraz adres wznowienia. Wyjaśnij, co stałoby się bez zapisu mepc+4.",
"evidence_tex": "Adres ecall i dwa adresy mepc z raportu/listingu, cause 11, instrukcja mret oraz kod wyjścia Hazard3.",
"criterion": "Hazard3: count=1, mcause=0x0000000b, resume_pc-mepc=4, resumed=1, pass=1 i kod 0."
},
{
"kind": "block",
"id": "task01.worksheet",
"title": "TASK01 · Zapis dowodu ucznia",
"content_tex": "\\textbf{1. Przewidywanie przed uruchomieniem}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{2. mcause, mepc i adres wznowienia}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{3. ecall/mret w listingu i kod wyjścia}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{4. Wniosek: reguła języka lub kontrakt targetu potwierdzony przez pomiar}\\par\\noindent\\dotfill\\par\\noindent\\dotfill"
}
],
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_ref": "C10.KW01"
},
"task02": {
"title": "Machine software IRQ i clear źródła",
"uuid": "a4b503ba-cacc-5af1-9ecd-31f51563ca76",
"prompt_tex": "Zapisz stan pending przed globalnym enable, mcause w ISR i pending po clear. Rozdziel źródło MSIP od obu bramek oraz wskaż, dlaczego handler musi usunąć źródło przed mret.",
"criterion": "Hazard3: count=1, mcause=0x80000003, pending_before=1, pending_in_handler=1, pending_after=0, resumed=1, pass=1 i kod 0.",
"conclusion_tex": "",
"render_task_acceptance": false,
"viewpoints": [
{
"id": "A1",
"status": "enabled",
"title": "CONTEXT — kontrolowane źródło bez peryferium",
"content_tex": "\\texttt{tb\\_set\\_softirq(0)} podnosi machine software interrupt hart0. Testbench jest źródłem, CSR są kontrolą rdzenia, ISR usuwa żądanie, a main ocenia wznowienie. UART/GPIO nie uczestniczą."
},
{
"id": "A2",
"status": "enabled",
"title": "STRUCTURE — trzy bity i jeden wektor",
"content_tex": "Źródło jest widoczne jako \\texttt{mip.MSIP}; indywidualna bramka to \\texttt{mie.MSIE}, globalna to \\texttt{mstatus.MIE}. Cause 3 w trybie vectored wybiera slot 3 i symbol \\texttt{isr\\_machine\\_softirq}."
},
{
"id": "A3",
"status": "enabled",
"title": "DISPATCH — sprzęt wybiera vector 3",
"content_tex": "Bit interrupt w mcause i kod 3 powodują sprzętowy wybór slotu machine software IRQ. Nie jest to statyczne jal z main. Po wejściu symbol handlera jest już określony przez wektor, a mret odtwarza przerwany kontekst."
},
{
"id": "A4",
"status": "enabled",
"title": "APPLICATION — pending 1 do 0",
"content_tex": "Przy MSIE=1 i MIE=0 źródło jest już pending, lecz licznik wynosi 0. Po otwarciu MIE handler widzi \\texttt{0x80000003} i pending=1, wykonuje clear, zwiększa licznik, a po mret main mierzy pending=0."
},
{
"id": "A5",
"status": "enabled",
"title": "FLOW — configure, assert, observe, enable",
"content_tex": "Kolejność eliminuje wyścig pomiaru: najpierw wyłącz wszystko, ustaw MSIE, podnieś źródło, zmierz pending, dopiero potem ustaw MIE. Handler odczytuje cause/pending przed clear i publikuje licznik po clear."
},
{
"id": "A6",
"status": "enabled",
"title": "STATE — MASKED_PENDING, ACTIVE, CLEARED",
"content_tex": "Źródło przechodzi do \\texttt{MASKED\\_PENDING}, bo globalna bramka jest zamknięta. Po MIE staje się ACTIVE; clear w ISR tworzy CLEARED. Resumed=1 jest osobnym stanem normalnego kodu po mret."
},
{
"id": "A7",
"status": "enabled",
"title": "RUNTIME — cause z bitem 31",
"content_tex": "Wartość \\texttt{0x80000003} łączy bit interrupt i kod 3. Listing ma pokazać CSR dla mie/mstatus/mip, dostęp do testbench clear oraz mret. Oracle wymaga całego śladu, nie tylko pass."
},
{
"id": "A8",
"status": "enabled",
"title": "PATTERNS — clear level source before publish",
"content_tex": "Źródło poziomowe usuwa się przed opublikowaniem ukończenia ISR. Gdyby licznik wzrósł bez clear, po mret żądanie pozostałoby aktywne i handler mógłby wejść ponownie."
}
],
"flow": [
{
"kind": "block",
"id": "task02.a1",
"title": "A1 CONTEXT · AKTYWNE — kontrolowane źródło bez peryferium",
"content_tex": "\\textbf{Zachowany przykład:} \\nolinkurl{src/tasks/task02_machine_software_irq.c}.\\par \\texttt{tb\\_set\\_softirq(0)} podnosi machine software interrupt hart0. Testbench jest źródłem, CSR są kontrolą rdzenia, ISR usuwa żądanie, a main ocenia wznowienie. UART/GPIO nie uczestniczą."
},
{
"kind": "block",
"id": "task02.a2",
"title": "A2 STRUCTURE · AKTYWNE — trzy bity i jeden wektor",
"content_tex": "Źródło jest widoczne jako \\texttt{mip.MSIP}; indywidualna bramka to \\texttt{mie.MSIE}, globalna to \\texttt{mstatus.MIE}. Cause 3 w trybie vectored wybiera slot 3 i symbol \\texttt{isr\\_machine\\_softirq}."
},
{
"kind": "block",
"id": "task02.a3",
"title": "A3 DISPATCH · AKTYWNE — sprzęt wybiera vector 3",
"content_tex": "Bit interrupt w mcause i kod 3 powodują sprzętowy wybór slotu machine software IRQ. Nie jest to statyczne jal z main. Po wejściu symbol handlera jest już określony przez wektor, a mret odtwarza przerwany kontekst."
},
{
"kind": "block",
"id": "task02.a4",
"title": "A4 APPLICATION · AKTYWNE — pending 1 do 0",
"content_tex": "Przy MSIE=1 i MIE=0 źródło jest już pending, lecz licznik wynosi 0. Po otwarciu MIE handler widzi \\texttt{0x80000003} i pending=1, wykonuje clear, zwiększa licznik, a po mret main mierzy pending=0."
},
{
"kind": "block",
"id": "task02.a5",
"title": "A5 FLOW · AKTYWNE — configure, assert, observe, enable",
"content_tex": "Kolejność eliminuje wyścig pomiaru: najpierw wyłącz wszystko, ustaw MSIE, podnieś źródło, zmierz pending, dopiero potem ustaw MIE. Handler odczytuje cause/pending przed clear i publikuje licznik po clear."
},
{
"kind": "block",
"id": "task02.a6",
"title": "A6 STATE · AKTYWNE — MASKED_PENDING, ACTIVE, CLEARED",
"content_tex": "Źródło przechodzi do \\texttt{MASKED\\_PENDING}, bo globalna bramka jest zamknięta. Po MIE staje się ACTIVE; clear w ISR tworzy CLEARED. Resumed=1 jest osobnym stanem normalnego kodu po mret."
},
{
"kind": "block",
"id": "task02.a7",
"title": "A7 RUNTIME · AKTYWNE — cause z bitem 31",
"content_tex": "Wartość \\texttt{0x80000003} łączy bit interrupt i kod 3. Listing ma pokazać CSR dla mie/mstatus/mip, dostęp do testbench clear oraz mret. Oracle wymaga całego śladu, nie tylko pass."
},
{
"kind": "block",
"id": "task02.a8",
"title": "A8 PATTERNS · AKTYWNE — clear level source before publish",
"content_tex": "Źródło poziomowe usuwa się przed opublikowaniem ukończenia ISR. Gdyby licznik wzrósł bez clear, po mret żądanie pozostałoby aktywne i handler mógłby wejść ponownie."
},
{
"kind": "exercise",
"id": "task02.proof",
"title": "Przewidywanie → wykonanie → wniosek",
"prompt_tex": "Zapisz stan pending przed globalnym enable, mcause w ISR i pending po clear. Rozdziel źródło MSIP od obu bramek oraz wskaż, dlaczego handler musi usunąć źródło przed mret.",
"evidence_tex": "Ślad źródło→pending→MSIE/MIE→vector 3→ISR→clear→mret, raport globali i kod wyjścia Hazard3.",
"criterion": "Hazard3: count=1, mcause=0x80000003, pending_before=1, pending_in_handler=1, pending_after=0, resumed=1, pass=1 i kod 0."
},
{
"kind": "block",
"id": "task02.worksheet",
"title": "TASK02 · Zapis dowodu ucznia",
"content_tex": "\\textbf{1. Przewidywanie przed uruchomieniem}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{2. Pending i bramki przed wejściem}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{3. mcause, clear, mret i wznowienie}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{4. Wniosek: reguła języka lub kontrakt targetu potwierdzony przez pomiar}\\par\\noindent\\dotfill\\par\\noindent\\dotfill"
}
],
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_ref": "C10.KW01"
},
"task03": {
"title": "Macierz pending, MSIE i MIE",
"uuid": "f56dba83-f7a9-5643-8f2e-84df1e8a2190",
"prompt_tex": "Wypełnij trzy wiersze: pending=1 z samym MIE, pending=1 z samym MSIE oraz pending=1 z obiema bramkami. Przewidź licznik ISR i końcowy pending.",
"criterion": "Hazard3: pending=1, blocked_no_msie=1, blocked_no_mie=1, delivered_both=1, count=1, mcause=0x80000003, pending_after=0, pass=1 i kod 0.",
"conclusion_tex": "",
"render_task_acceptance": false,
"viewpoints": [
{
"id": "A1",
"status": "enabled",
"title": "CONTEXT — jedna zmienna, dwie kontrolki",
"content_tex": "Bodziec MSIP pozostaje ten sam podczas dwóch prób blokowanych i próby dostarczonej. Przykład zmienia wyłącznie bramki rdzenia, więc nie myli nowego zdarzenia z nową konfiguracją."
},
{
"id": "A2",
"status": "enabled",
"title": "STRUCTURE — macierz 1×2×2",
"content_tex": "Oś danych to pending=1. Dwie osie sterujące to MSIE i MIE. Cztery kombinacje mają jeden stan dostarczalny: oba bity 1. Przykład mierzy trzy istotne wiersze przy utrzymanym pending."
},
{
"id": "A3",
"status": "enabled",
"title": "DISPATCH — wejście dopiero dla 1/1",
"content_tex": "Sprzętowy dispatch do vector 3 nie zachodzi przy żadnej pojedynczej otwartej bramce. Dopiero MSIE=1 i MIE=1 pozwalają utworzyć trap, zapisać cause i wejść do ISR kończącego się mret."
},
{
"id": "A4",
"status": "enabled",
"title": "APPLICATION — dwa razy blocked, raz delivered",
"content_tex": "Przy MIE=1/MSIE=0 licznik zostaje 0. Przy MIE=0/MSIE=1 również zostaje 0. Przy obu równych 1 rośnie dokładnie do 1, mcause ma wartość 0x80000003, a clear zeruje pending."
},
{
"id": "A5",
"status": "enabled",
"title": "FLOW — nie zmieniaj źródła między próbami",
"content_tex": "Program podnosi MSIP raz, następnie testuje global-only, individual-only i both. Globalny bit jest zamykany przed zmianą MSIE, aby dostarczenie nie zaszło między pomiarem a zapisaniem wyniku."
},
{
"id": "A6",
"status": "enabled",
"title": "STATE — P10, P01, P11, CLEAR",
"content_tex": "Skrót \\texttt{Pxy} oznacza pending=1, MSIE=x, MIE=y. Ślad to \\texttt{P01(blocked) -> P10(blocked) -> P11(active) -> CLEAR}. Licznik zmienia się tylko na trzeciej krawędzi."
},
{
"id": "A7",
"status": "enabled",
"title": "RUNTIME — odczyt mip, zapisy mie/mstatus",
"content_tex": "Raport utrwala trzy decyzje i cause. Listing rozdziela \\texttt{csrs/csrc mie}, \\texttt{csrs/csrc mstatus} oraz odczyt mip. Objdump niezależnie potwierdza mret w ISR."
},
{
"id": "A8",
"status": "enabled",
"title": "PATTERNS — source, individual, global gate",
"content_tex": "Trzywarstwowy model zapobiega typowemu błędowi: pending nie znaczy delivered. Ten sam wzorzec wróci dla MTIP/MTIE oraz external IRQ z enable peryferium, kontrolera i globalnym MIE."
}
],
"flow": [
{
"kind": "block",
"id": "task03.a1",
"title": "A1 CONTEXT · AKTYWNE — jedna zmienna, dwie kontrolki",
"content_tex": "\\textbf{Zachowany przykład:} \\nolinkurl{src/tasks/task03_pending_enable_matrix.c}.\\par Bodziec MSIP pozostaje ten sam podczas dwóch prób blokowanych i próby dostarczonej. Przykład zmienia wyłącznie bramki rdzenia, więc nie myli nowego zdarzenia z nową konfiguracją."
},
{
"kind": "block",
"id": "task03.a2",
"title": "A2 STRUCTURE · AKTYWNE — macierz 1×2×2",
"content_tex": "Oś danych to pending=1. Dwie osie sterujące to MSIE i MIE. Cztery kombinacje mają jeden stan dostarczalny: oba bity 1. Przykład mierzy trzy istotne wiersze przy utrzymanym pending."
},
{
"kind": "block",
"id": "task03.a3",
"title": "A3 DISPATCH · AKTYWNE — wejście dopiero dla 1/1",
"content_tex": "Sprzętowy dispatch do vector 3 nie zachodzi przy żadnej pojedynczej otwartej bramce. Dopiero MSIE=1 i MIE=1 pozwalają utworzyć trap, zapisać cause i wejść do ISR kończącego się mret."
},
{
"kind": "block",
"id": "task03.a4",
"title": "A4 APPLICATION · AKTYWNE — dwa razy blocked, raz delivered",
"content_tex": "Przy MIE=1/MSIE=0 licznik zostaje 0. Przy MIE=0/MSIE=1 również zostaje 0. Przy obu równych 1 rośnie dokładnie do 1, mcause ma wartość 0x80000003, a clear zeruje pending."
},
{
"kind": "block",
"id": "task03.a5",
"title": "A5 FLOW · AKTYWNE — nie zmieniaj źródła między próbami",
"content_tex": "Program podnosi MSIP raz, następnie testuje global-only, individual-only i both. Globalny bit jest zamykany przed zmianą MSIE, aby dostarczenie nie zaszło między pomiarem a zapisaniem wyniku."
},
{
"kind": "block",
"id": "task03.a6",
"title": "A6 STATE · AKTYWNE — P10, P01, P11, CLEAR",
"content_tex": "Skrót \\texttt{Pxy} oznacza pending=1, MSIE=x, MIE=y. Ślad to \\texttt{P01(blocked) -> P10(blocked) -> P11(active) -> CLEAR}. Licznik zmienia się tylko na trzeciej krawędzi."
},
{
"kind": "block",
"id": "task03.a7",
"title": "A7 RUNTIME · AKTYWNE — odczyt mip, zapisy mie/mstatus",
"content_tex": "Raport utrwala trzy decyzje i cause. Listing rozdziela \\texttt{csrs/csrc mie}, \\texttt{csrs/csrc mstatus} oraz odczyt mip. Objdump niezależnie potwierdza mret w ISR."
},
{
"kind": "block",
"id": "task03.a8",
"title": "A8 PATTERNS · AKTYWNE — source, individual, global gate",
"content_tex": "Trzywarstwowy model zapobiega typowemu błędowi: pending nie znaczy delivered. Ten sam wzorzec wróci dla MTIP/MTIE oraz external IRQ z enable peryferium, kontrolera i globalnym MIE."
},
{
"kind": "exercise",
"id": "task03.proof",
"title": "Przewidywanie → wykonanie → wniosek",
"prompt_tex": "Wypełnij trzy wiersze: pending=1 z samym MIE, pending=1 z samym MSIE oraz pending=1 z obiema bramkami. Przewidź licznik ISR i końcowy pending.",
"evidence_tex": "Tabela prawdy dwóch bramek dla jednego utrzymywanego pending, licznik ISR, końcowy clear, mret i kod wyjścia Hazard3.",
"criterion": "Hazard3: pending=1, blocked_no_msie=1, blocked_no_mie=1, delivered_both=1, count=1, mcause=0x80000003, pending_after=0, pass=1 i kod 0."
},
{
"kind": "block",
"id": "task03.worksheet",
"title": "TASK03 · Zapis dowodu ucznia",
"content_tex": "\\textbf{1. Przewidywanie przed uruchomieniem}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{2. Macierz pending/MSIE/MIE}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{3. Dostarczenie, clear i kod wyjścia}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{4. Wniosek: reguła języka lub kontrakt targetu potwierdzony przez pomiar}\\par\\noindent\\dotfill\\par\\noindent\\dotfill"
}
],
"educational_requirement_refs": [
"C10.WE01"
],
"learning_effect_refs": [
"C10.EN01",
"C10.EK01"
],
"assessment_criterion_ref": "C10.KW01"
}
},
"tasks_order": [
"task01",
"task02",
"task03"
]
}