{ "$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 A1–A8", "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" ] }