Files
2026-07-21 19:14:20 +02:00

668 lines
36 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-inf-c-12-uart-polling-interrupts",
"series": "c",
"series_title": "C · Freestanding RV32I and K&R",
"number": "12",
"count": "13",
"slug": "uart-polling-interrupts",
"title": "UART — polling i przerwania RX",
"topic": "MMIO UART, external IRQ oraz jednokomórkowa skrzynka ISR do main",
"project": "Freestanding C na RV32I",
"subject": "Informatyka",
"level": "Rok 1 · C12 · RV32I/Hazard3",
"revision_date": "2026-07-20T00:00:00+02:00",
"status": "Gotowa",
"version": "v00.01",
"uuid": "e766c4bb-2a43-5f4e-b10a-b3393a42932c",
"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": "UART — polling i przerwania RX",
"url": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/64f7c516-78b1-58ee-8619-a82d7061079f",
"repository_url": "https://zsl-gitea.mpabi.pl/edu-inf/lab-rv32i-c-uart",
"url_host_uuid": "dce7fb9d-7b2f-5d49-96a2-3a30d3070b84",
"url_domain": "mpabi.pl",
"doc_uuid": "64f7c516-78b1-58ee-8619-a82d7061079f",
"revision": "v00.01",
"issued_on": "2026-07-20T00:00:00+02:00",
"series": "C-12",
"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 polling rejestru statusu od odbioru sterowanego zdarzeniem. Dla ścieżki przerwania wskazuje osobno: bajt w RX FIFO, stan linii external IRQ 16, selekcję przez kontroler Hazard3, wywołanie ISR i efekt konsumowany później przez main.",
"scope_title": "Zakres i zachowane przykłady",
"scope_content_tex": "Karta korzysta z laboratoryjnego modelu UART Hazard3. Rejestr \\texttt{TB\\_UART\\_TEST\\_RX} jest wyłącznie kontrolowanym bodźcem testbench; nie występuje w produkcyjnym UART ani na RP2350. Po wstrzyknięciu bajtu Task02 i Task03 przechodzą jednak przez rzeczywisty kontroler external IRQ, \\texttt{mtvec}, dispatcher i \\texttt{mret} modelowanego rdzenia.\\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": "MMIO",
"task": "Task01",
"idea_tex": "STATUS, DATA i kontrolowany RX stimulus",
"priority": "kluczowe",
"key": true
},
{
"chapter": "IRQ",
"task": "Task02",
"idea_tex": "FIFO, pending, enable, dispatcher i mret",
"priority": "kluczowe",
"key": true
},
{
"chapter": "ISR",
"task": "Task03",
"idea_tex": "krótki ISR, jawne przepełnienie i konsumpcja w main",
"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": {
"C12.EN01": {
"bloom_level": "Analiza",
"label": "Źródło to nie handler",
"text": "Uczeń rozpisuje cztery oddzielne etapy: stan FIFO, pending i enable, decyzję dispatchera oraz zmianę stanu aplikacji.",
"assessment_criteria": [
"C12.KW01"
]
},
"C12.EK01": {
"bloom_level": "Zastosowanie",
"label": "Dowód na Hazard3",
"text": "Uczeń uruchamia trzy obrazy RV32I, odczytuje status UART, numer IRQ, bajty i liczniki oraz wiąże je z listingiem i kodem wyjścia.",
"assessment_criteria": [
"C12.KW01"
]
}
},
"assessment_criteria": {
"C12.KW01": {
"text": "Wszystkie trzy programy kończą się kodem 0 w Hazard3. Task01 odczytuje P przez polling: status 0x3 przed i 0x2 po odczycie. Task02 przed globalnym enable widzi pending=1, handler numeru 16 odczytuje R przy statusie 0x13, a po obsłudze pending=0. Task03 obsługuje trzy IRQ, przyjmuje A i C, odrzuca B zgodnie z drop-newest i kończy z accepted=2, dropped=1.",
"learning_effects": [
"C12.EN01",
"C12.EK01"
]
}
},
"educational_requirements": {
"C12.WE01": {
"text": "Obsługa MMIO i przerwania UART z jawnym rozdzieleniem bodźca testbench, stanu peryferium, kontrolera przerwań, ISR i normalnego kodu.",
"label": "MMIO UART, external IRQ oraz jednokomórkowa skrzynka ISR do main",
"learning_effects": [
"C12.EN01",
"C12.EK01"
],
"learning_tree": {
"schema": "we-learning-tree.v1",
"policy": "Najpierw przewidywanie, następnie wykonanie i odczyt dowodu.",
"ogolne": [
{
"effect_ref": "C12.EN01",
"display": "EN C12 01",
"source": "LOCAL",
"official": "C",
"local": "01",
"kind": "EN",
"tree_id": "C12.WE01.OG.LOCAL.C.01",
"text": "Uczeń rozpisuje cztery oddzielne etapy: stan FIFO, pending i enable, decyzję dispatchera oraz zmianę stanu aplikacji.",
"kw": [
{
"criterion_ref": "C12.KW01",
"display": "KW C12 01",
"source": "LOCAL",
"kind": "KW",
"official": "C",
"local": "01",
"text": "Kod, przewidywanie i pomiar tworzą jeden dowód."
}
]
}
],
"zawodowe": [
{
"effect_ref": "C12.EK01",
"display": "EK C12 01",
"source": "LOCAL",
"official": "C",
"local": "01",
"kind": "EK",
"tree_id": "C12.WE01.TECH.LOCAL.C.01",
"text": "Uczeń uruchamia trzy obrazy RV32I, odczytuje status UART, numer IRQ, bajty i liczniki oraz wiąże je z listingiem i kodem wyjścia.",
"kw": [
{
"criterion_ref": "C12.KW01",
"display": "KW C12 01",
"source": "LOCAL",
"kind": "KW",
"official": "C",
"local": "01",
"text": "Kod, przewidywanie i pomiar tworzą jeden dowód."
}
]
}
]
}
}
},
"sections": [
{
"title": "Polling pyta o stan w rytmie programu",
"order": 10,
"content_kind": "prose",
"page_orientation": "portrait",
"content_tex": "Rejestr \\texttt{STATUS.RX\\_AVAIL} opisuje niepusty RX FIFO, a odczyt \\texttt{DATA} usuwa jeden bajt. W Task01 przerwanie RX pozostaje wyłączone: program sam wykonuje kolejne odczyty statusu. Jest to poprawne dla prostego, krótkiego oczekiwania, lecz czas CPU zależy od częstotliwości odpytywania. Zapis \\texttt{TB\\_UART\\_TEST\\_RX='P'} jest bodźcem laboratoryjnym, nie częścią sterownika produkcyjnego.",
"educational_requirement_refs": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_refs": [
"C12.KW01"
]
},
{
"title": "RX IRQ jest ścieżką pięciu stanów",
"order": 20,
"content_kind": "prose",
"page_orientation": "portrait",
"content_tex": "W Task02 bajt trafia do FIFO i model podnosi external IRQ 16 tylko wtedy, gdy \\texttt{CTRL.RX\\_IRQ\\_EN=1}. Kontroler Hazard3 próbkuje i udostępnia bieżący poziom pending; \\texttt{mstatus.MIE}, \\texttt{mie.MEIE} i enable linii decydują, czy rdzeń wejdzie do wektora. Dispatcher odczytuje \\texttt{meinext}, wybiera wpis 16 z tablicy i wykonuje \\texttt{jalr}. Odczyt DATA opróżnia FIFO, więc linia poziomowa i widoczny pending opadają; dopiero \\texttt{mret} wraca do normalnego kodu.",
"educational_requirement_refs": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_refs": [
"C12.KW01"
]
},
{
"title": "ISR przekazuje minimum, main nadaje znaczenie",
"order": 30,
"content_kind": "prose",
"page_orientation": "portrait",
"content_tex": "Task03 nie analizuje komendy w ISR. Handler zawsze opróżnia DATA, a potem albo zapisuje bajt do jednej komórki, albo zwiększa licznik odrzuceń, gdy komórka jest pełna. Polityka \\texttt{drop-newest} jest celowo jawna i mierzalna. To nie jest kolejka ani synchronizacja RTOS: pojedyncze 32-bitowe obiekty \\texttt{volatile} i kontrolowana kolejność wystarczają wyłącznie dla tego jednego rdzenia i tego przykładu.",
"educational_requirement_refs": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_refs": [
"C12.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": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_refs": [
"C12.KW01"
]
}
],
"tasks": {
"task01": {
"title": "Polling jednego bajtu",
"uuid": "611a873f-8d37-5084-9ab6-1230e2505249",
"prompt_tex": "Przewidź bity statusu przed i po odczycie P. Wskaż, która operacja tworzy bodziec testbench, która tylko obserwuje FIFO, a która usuwa bajt. Potwierdź także zapis T do rejestru TX.",
"criterion": "Hazard3: status_before=0x3, rx_byte='P'=80, status_after=0x2, tx_byte='T'=84, osobna linia T w logu testbencha, pass=1 i kod wyjścia 0.",
"conclusion_tex": "",
"render_task_acceptance": false,
"viewpoints": [
{
"id": "A1",
"status": "enabled",
"title": "CONTEXT — polling w granicy modelu",
"content_tex": "Odpowiedzialność przykładu zaczyna się od kontrolowanego wstrzyknięcia P do RX FIFO i kończy na odczycie P oraz zapisie T do TX. Nie konfiguruje kontrolera przerwań. \\texttt{TEST\\_RX} należy wyłącznie do testbench; DATA, STATUS i CTRL modelują interfejs peryferium."
},
{
"id": "A2",
"status": "enabled",
"title": "STRUCTURE — cztery rejestry i FIFO",
"content_tex": "Pod bazą UART0 leżą DATA +0, STATUS +4, CTRL +8 i testowy \\texttt{TEST\\_RX} +12. FIFO nie jest bezpośrednio adresowalne: \\texttt{RX\\_AVAIL} mówi tylko, czy zawiera co najmniej jeden bajt, a DATA zwraca i usuwa element czołowy."
},
{
"id": "A3",
"status": "unavailable",
"title": "DISPATCH",
"reason": "RX IRQ pozostaje wyłączone, więc nie ma wejścia przez mtvec, wyboru ISR ani pośredniego jalr; wszystkie funkcje są wywołaniami bezpośrednimi normalnego kodu."
},
{
"id": "A4",
"status": "enabled",
"title": "APPLICATION — przewidywanie bitów",
"content_tex": "Bez klienta TCP status po wstrzyknięciu P ma wartość 0x3: \\texttt{RX\\_AVAIL} i \\texttt{TX\\_READY}. \\texttt{RX\\_IRQ} jest zerem, bo CTRL nie włącza źródła. Po odczycie DATA FIFO jest puste, więc zostaje 0x2. Znaki mają wartości P=80 i T=84."
},
{
"id": "A5",
"status": "enabled",
"title": "FLOW — inject, status, data, status, tx",
"content_tex": "Kolejność jest częścią dowodu: wyłącz IRQ, wstrzyknij P, odczytaj pierwszy status, odczytaj DATA, odczytaj drugi status, zapisz T. Zamiana DATA z pierwszym statusem zniszczyłaby obserwację \\texttt{RX\\_AVAIL=1}."
},
{
"id": "A6",
"status": "enabled",
"title": "STATE — EMPTY do P do EMPTY",
"content_tex": "RX FIFO przechodzi \\texttt{EMPTY -> ['P'] -> EMPTY}. Status jest funkcją tego stanu i nie przechowuje osobnej kopii flagi. Zapis TX jest widoczny jako T w logu testbencha; bez klienta TCP model nie zachowuje tego bajtu w kolejce sieciowej. Nie zmienia to stanu RX."
},
{
"id": "A7",
"status": "enabled",
"title": "RUNTIME — adresy 0xc00002xx",
"content_tex": "W listingu znajdź zapisy i odczyty pod bazą \\texttt{0xc0000200}. W checkpointcie globale mają wartości 3, 80, 2 i 84. Kod 0 pochodzi z pełnego gate, a nie z samego faktu, że program dotarł do \\texttt{\\_exit}."
},
{
"id": "A8",
"status": "enabled",
"title": "PATTERNS — status-before-data",
"content_tex": "Nazwany wzorzec polling RX brzmi: sprawdź availability, dopiero potem odczytaj destructive DATA. Jest prosty i deterministyczny, ale zużywa czas CPU, jeśli pętla oczekiwania nie ma ograniczenia ani innej pracy."
}
],
"flow": [
{
"kind": "block",
"id": "task01.a1",
"title": "A1 CONTEXT · AKTYWNE — polling w granicy modelu",
"content_tex": "\\textbf{Zachowany przykład:} \\nolinkurl{src/tasks/task01_uart_polling.c}.\\par Odpowiedzialność przykładu zaczyna się od kontrolowanego wstrzyknięcia P do RX FIFO i kończy na odczycie P oraz zapisie T do TX. Nie konfiguruje kontrolera przerwań. \\texttt{TEST\\_RX} należy wyłącznie do testbench; DATA, STATUS i CTRL modelują interfejs peryferium."
},
{
"kind": "block",
"id": "task01.a2",
"title": "A2 STRUCTURE · AKTYWNE — cztery rejestry i FIFO",
"content_tex": "Pod bazą UART0 leżą DATA +0, STATUS +4, CTRL +8 i testowy \\texttt{TEST\\_RX} +12. FIFO nie jest bezpośrednio adresowalne: \\texttt{RX\\_AVAIL} mówi tylko, czy zawiera co najmniej jeden bajt, a DATA zwraca i usuwa element czołowy."
},
{
"kind": "block",
"id": "task01.a3",
"title": "A3 DISPATCH · N/D",
"content_tex": "\\textbf{N/D.} RX IRQ pozostaje wyłączone, więc nie ma wejścia przez mtvec, wyboru ISR ani pośredniego jalr; wszystkie funkcje są wywołaniami bezpośrednimi normalnego kodu."
},
{
"kind": "block",
"id": "task01.a4",
"title": "A4 APPLICATION · AKTYWNE — przewidywanie bitów",
"content_tex": "Bez klienta TCP status po wstrzyknięciu P ma wartość 0x3: \\texttt{RX\\_AVAIL} i \\texttt{TX\\_READY}. \\texttt{RX\\_IRQ} jest zerem, bo CTRL nie włącza źródła. Po odczycie DATA FIFO jest puste, więc zostaje 0x2. Znaki mają wartości P=80 i T=84."
},
{
"kind": "block",
"id": "task01.a5",
"title": "A5 FLOW · AKTYWNE — inject, status, data, status, tx",
"content_tex": "Kolejność jest częścią dowodu: wyłącz IRQ, wstrzyknij P, odczytaj pierwszy status, odczytaj DATA, odczytaj drugi status, zapisz T. Zamiana DATA z pierwszym statusem zniszczyłaby obserwację \\texttt{RX\\_AVAIL=1}."
},
{
"kind": "block",
"id": "task01.a6",
"title": "A6 STATE · AKTYWNE — EMPTY do P do EMPTY",
"content_tex": "RX FIFO przechodzi \\texttt{EMPTY -> ['P'] -> EMPTY}. Status jest funkcją tego stanu i nie przechowuje osobnej kopii flagi. Zapis TX jest widoczny jako T w logu testbencha; bez klienta TCP model nie zachowuje tego bajtu w kolejce sieciowej. Nie zmienia to stanu RX."
},
{
"kind": "block",
"id": "task01.a7",
"title": "A7 RUNTIME · AKTYWNE — adresy 0xc00002xx",
"content_tex": "W listingu znajdź zapisy i odczyty pod bazą \\texttt{0xc0000200}. W checkpointcie globale mają wartości 3, 80, 2 i 84. Kod 0 pochodzi z pełnego gate, a nie z samego faktu, że program dotarł do \\texttt{\\_exit}."
},
{
"kind": "block",
"id": "task01.a8",
"title": "A8 PATTERNS · AKTYWNE — status-before-data",
"content_tex": "Nazwany wzorzec polling RX brzmi: sprawdź availability, dopiero potem odczytaj destructive DATA. Jest prosty i deterministyczny, ale zużywa czas CPU, jeśli pętla oczekiwania nie ma ograniczenia ani innej pracy."
},
{
"kind": "exercise",
"id": "task01.proof",
"title": "Przewidywanie → wykonanie → wniosek",
"prompt_tex": "Przewidź bity statusu przed i po odczycie P. Wskaż, która operacja tworzy bodziec testbench, która tylko obserwuje FIFO, a która usuwa bajt. Potwierdź także zapis T do rejestru TX.",
"evidence_tex": "Tabela bitów STATUS przed i po DATA, odczyt globali Task01, wskazanie transakcji MMIO w listingu RV32I oraz kod wyjścia Hazard3.",
"criterion": "Hazard3: status_before=0x3, rx_byte='P'=80, status_after=0x2, tx_byte='T'=84, osobna linia T w logu testbencha, pass=1 i kod wyjścia 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. Status i bajt w modelu UART}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{3. Transakcje MMIO RV32I 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": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_ref": "C12.KW01"
},
"task02": {
"title": "Odbiór R przez external IRQ 16",
"uuid": "1cd0396c-3eea-5a66-92a9-48439de20b15",
"prompt_tex": "Rozpisz osobno bity CTRL, pending linii 16, mstatus.MIE, mie.MEIE i enable kontrolera. Przewidź stan przed globalnym enable, numer wybrany przez meinext oraz czynność, która usuwa źródło poziomowe.",
"criterion": "Hazard3: pending_before_enable=1; jeden handler IRQ 16 widzi status 0x13 i byte='R'=82; po odczycie DATA pending_after=0, pass=1 i kod 0.",
"conclusion_tex": "",
"render_task_acceptance": false,
"viewpoints": [
{
"id": "A1",
"status": "enabled",
"title": "CONTEXT — pięć granic odpowiedzialności",
"content_tex": "\\texttt{TEST\\_RX} tworzy bodziec, UART utrzymuje FIFO i linię 16, kontroler Hazard3 utrzymuje pending/priority/enable, dispatcher wybiera wpis, a ISR odczytuje DATA. Normalny kod tylko konfiguruje, włącza globalny bit, czeka i ocenia dowód."
},
{
"id": "A2",
"status": "enabled",
"title": "STRUCTURE — stan peryferium, CSR i tabela",
"content_tex": "Stan obejmuje \\texttt{CTRL.RX\\_IRQ\\_EN}, niepusty FIFO, pending linii 16, tablicę \\texttt{\\_external\\_irq\\_table[16]}, priorytet, \\texttt{mie.MEIE} i \\texttt{mstatus.MIE}. Żaden pojedynczy bit nie wystarcza do wejścia w ISR."
},
{
"id": "A3",
"status": "enabled",
"title": "DISPATCH — meinext do wpisu 16",
"content_tex": "Wektor machine external IRQ wchodzi do \\texttt{isr\\_external\\_irq}. Odczyt \\texttt{meinext} zwraca gotowy offset tablicy — numer linii 16 przesunięty o dwa bity. Dispatcher dodaje go do bazy \\texttt{\\_external\\_irq\\_table} i wykonuje \\texttt{jalr} do \\texttt{task02\\_uart\\_handler}. To jest rzeczywisty wybór wykonawcy, nie zwykłe statyczne wywołanie."
},
{
"id": "A4",
"status": "enabled",
"title": "APPLICATION — R i status 0x13",
"content_tex": "Przed globalnym enable pending ma być 1, lecz licznik handlera nadal 0. Po enable ISR ma zobaczyć \\texttt{RX\\_AVAIL}, \\texttt{TX\\_READY} i \\texttt{RX\\_IRQ}, czyli 0x13, odczytać R=82 i opublikować numer 16."
},
{
"id": "A5",
"status": "enabled",
"title": "FLOW — konfiguracja przed globalnym enable",
"content_tex": "Najpierw MIE jest wyzerowane, potem ustawiane są handler, priorytet, enable linii, MEIE i CTRL. Dopiero po wstrzyknięciu R i zmierzeniu pending program ustawia MIE. ISR czyta DATA, dispatcher odtwarza kontekst i wykonuje mret."
},
{
"id": "A6",
"status": "enabled",
"title": "STATE — PENDING, ACTIVE, DRAINED",
"content_tex": "Po bodźcu stan jest PENDING: FIFO zawiera R, linia 16 jest aktywna, lecz globalny gate blokuje wejście. Po MIE przechodzi do ACTIVE. Odczyt DATA tworzy DRAINED: FIFO pusty, linia i pending opadają, a licznik wynosi 1."
},
{
"id": "A7",
"status": "enabled",
"title": "RUNTIME — mcause 0x8000000b i meinext 16",
"content_tex": "Wejście sprzętowe ma machine external interrupt cause 11, czyli \\texttt{mcause=0x8000000b}; konkretną linię 16 wybiera dopiero kontroler przez meinext. Listing ma zawierać zapis tablicy, operacje CSR, pośredni jalr i mret."
},
{
"id": "A8",
"status": "enabled",
"title": "PATTERNS — drain level-triggered source",
"content_tex": "Dla źródła poziomowego ISR musi usunąć warunek w peryferium, tutaj opróżnić DATA. Samo wejście do handlera nie jest acknowledge. Gdyby FIFO pozostał niepusty, linia byłaby nadal aktywna i przerwanie wróciłoby po mret."
}
],
"flow": [
{
"kind": "block",
"id": "task02.a1",
"title": "A1 CONTEXT · AKTYWNE — pięć granic odpowiedzialności",
"content_tex": "\\textbf{Zachowany przykład:} \\nolinkurl{src/tasks/task02_uart_rx_interrupt.c}.\\par \\texttt{TEST\\_RX} tworzy bodziec, UART utrzymuje FIFO i linię 16, kontroler Hazard3 utrzymuje pending/priority/enable, dispatcher wybiera wpis, a ISR odczytuje DATA. Normalny kod tylko konfiguruje, włącza globalny bit, czeka i ocenia dowód."
},
{
"kind": "block",
"id": "task02.a2",
"title": "A2 STRUCTURE · AKTYWNE — stan peryferium, CSR i tabela",
"content_tex": "Stan obejmuje \\texttt{CTRL.RX\\_IRQ\\_EN}, niepusty FIFO, pending linii 16, tablicę \\texttt{\\_external\\_irq\\_table[16]}, priorytet, \\texttt{mie.MEIE} i \\texttt{mstatus.MIE}. Żaden pojedynczy bit nie wystarcza do wejścia w ISR."
},
{
"kind": "block",
"id": "task02.a3",
"title": "A3 DISPATCH · AKTYWNE — meinext do wpisu 16",
"content_tex": "Wektor machine external IRQ wchodzi do \\texttt{isr\\_external\\_irq}. Odczyt \\texttt{meinext} zwraca gotowy offset tablicy — numer linii 16 przesunięty o dwa bity. Dispatcher dodaje go do bazy \\texttt{\\_external\\_irq\\_table} i wykonuje \\texttt{jalr} do \\texttt{task02\\_uart\\_handler}. To jest rzeczywisty wybór wykonawcy, nie zwykłe statyczne wywołanie."
},
{
"kind": "block",
"id": "task02.a4",
"title": "A4 APPLICATION · AKTYWNE — R i status 0x13",
"content_tex": "Przed globalnym enable pending ma być 1, lecz licznik handlera nadal 0. Po enable ISR ma zobaczyć \\texttt{RX\\_AVAIL}, \\texttt{TX\\_READY} i \\texttt{RX\\_IRQ}, czyli 0x13, odczytać R=82 i opublikować numer 16."
},
{
"kind": "block",
"id": "task02.a5",
"title": "A5 FLOW · AKTYWNE — konfiguracja przed globalnym enable",
"content_tex": "Najpierw MIE jest wyzerowane, potem ustawiane są handler, priorytet, enable linii, MEIE i CTRL. Dopiero po wstrzyknięciu R i zmierzeniu pending program ustawia MIE. ISR czyta DATA, dispatcher odtwarza kontekst i wykonuje mret."
},
{
"kind": "block",
"id": "task02.a6",
"title": "A6 STATE · AKTYWNE — PENDING, ACTIVE, DRAINED",
"content_tex": "Po bodźcu stan jest PENDING: FIFO zawiera R, linia 16 jest aktywna, lecz globalny gate blokuje wejście. Po MIE przechodzi do ACTIVE. Odczyt DATA tworzy DRAINED: FIFO pusty, linia i pending opadają, a licznik wynosi 1."
},
{
"kind": "block",
"id": "task02.a7",
"title": "A7 RUNTIME · AKTYWNE — mcause 0x8000000b i meinext 16",
"content_tex": "Wejście sprzętowe ma machine external interrupt cause 11, czyli \\texttt{mcause=0x8000000b}; konkretną linię 16 wybiera dopiero kontroler przez meinext. Listing ma zawierać zapis tablicy, operacje CSR, pośredni jalr i mret."
},
{
"kind": "block",
"id": "task02.a8",
"title": "A8 PATTERNS · AKTYWNE — drain level-triggered source",
"content_tex": "Dla źródła poziomowego ISR musi usunąć warunek w peryferium, tutaj opróżnić DATA. Samo wejście do handlera nie jest acknowledge. Gdyby FIFO pozostał niepusty, linia byłaby nadal aktywna i przerwanie wróciłoby po mret."
},
{
"kind": "exercise",
"id": "task02.proof",
"title": "Przewidywanie → wykonanie → wniosek",
"prompt_tex": "Rozpisz osobno bity CTRL, pending linii 16, mstatus.MIE, mie.MEIE i enable kontrolera. Przewidź stan przed globalnym enable, numer wybrany przez meinext oraz czynność, która usuwa źródło poziomowe.",
"evidence_tex": "Ślad źródło→pending→enable→dispatcher→ISR→resume, wartości globali w checkpointcie, fragment \\texttt{jalr} z \\texttt{irq\\_dispatch.S} i kod wyjścia Hazard3.",
"criterion": "Hazard3: pending_before_enable=1; jeden handler IRQ 16 widzi status 0x13 i byte='R'=82; po odczycie DATA pending_after=0, 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. Macierz pending i enable przed ISR}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{3. Numer IRQ, status, bajt i powrót mret}\\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": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_ref": "C12.KW01"
},
"task03": {
"title": "Jednokomórkowa skrzynka drop-newest",
"uuid": "c60d485a-0e23-522a-a06a-78c86be36f76",
"prompt_tex": "Prześledź A, B i C. Dla każdego bajtu zapisz stan FIFO, \\texttt{mailbox\\_full}, decyzję ISR i późniejszy odczyt main. Wyjaśnij, dlaczego B jest odrzucone, a mimo to DATA musi zostać odczytane.",
"criterion": "Hazard3: irq_count=3, accepted=2, dropped=1, first_consumed='A'=65, second_consumed='C'=67, mailbox_full=0, pass=1 i kod 0.",
"conclusion_tex": "",
"render_task_acceptance": false,
"viewpoints": [
{
"id": "A1",
"status": "enabled",
"title": "CONTEXT — ISR transportuje, main konsumuje",
"content_tex": "Handler odpowiada za szybkie opróżnienie DATA i próbę publikacji jednego bajtu. Nie interpretuje komendy. Main odpowiada za konsumpcję. Gdy skrzynka jest pełna, kontrakt jawnie odrzuca najnowszy bajt i liczy stratę."
},
{
"id": "A2",
"status": "enabled",
"title": "STRUCTURE — payload, flaga i telemetria",
"content_tex": "Skrzynkę tworzą \\texttt{mailbox\\_byte} i \\texttt{mailbox\\_full}. Osobne liczniki irq, accepted i dropped nie sterują algorytmem; są telemetrią dowodu. Każdy obiekt ma szerokość 32 bitów i jest volatile w tym jednordzeniowym kontrakcie bare-metal."
},
{
"id": "A3",
"status": "enabled",
"title": "DISPATCH — ten sam IRQ, inny odbiorca",
"content_tex": "Linia 16 przechodzi przez ten sam dispatcher co Task02, lecz wpis tablicy wskazuje \\texttt{task03\\_uart\\_handler}. Dynamiczny wybór kończy się pośrednim jalr; decyzja accepted/drop odbywa się dopiero wewnątrz handlera na podstawie danych."
},
{
"id": "A4",
"status": "enabled",
"title": "APPLICATION — A przyjęte, B odrzucone, C przyjęte",
"content_tex": "Po A skrzynka jest pełna i accepted=1. B wywołuje drugie IRQ, DATA zostaje opróżnione, lecz payload A pozostaje, a dropped rośnie do 1. Main pobiera A. Po C pusta skrzynka znów przyjmuje dane; main pobiera C."
},
{
"id": "A5",
"status": "enabled",
"title": "FLOW — drain przed decyzją publish/drop",
"content_tex": "ISR najpierw odczytuje DATA, dzięki czemu usuwa źródło poziomowe niezależnie od stanu skrzynki. Następnie zwiększa \\texttt{irq\\_count} i wybiera publikację albo drop. Main czeka na konkretną liczbę obsług, a nie na sam upływ pętli."
},
{
"id": "A6",
"status": "enabled",
"title": "STATE — EMPTY, FULL(A), FULL(A), EMPTY, FULL(C), EMPTY",
"content_tex": "Pełny ślad skrzynki to \\texttt{EMPTY -> FULL(A) -> FULL(A) -> EMPTY -> FULL(C) -> EMPTY}. Drugie przejście nie zmienia payloadu, ale zmienia licznik dropped; dlatego stan domenowy i telemetria muszą być czytane razem."
},
{
"id": "A7",
"status": "enabled",
"title": "RUNTIME — trzy wejścia i trzy mret",
"content_tex": "Checkpoint ma pokazać irq=3, accepted=2, dropped=1, 65, 67 i full=0. W listingu wskaż trzy klasy operacji: MMIO DATA, zapisy globali przez ISR oraz odtworzenie kontekstu i mret w dispatcherze."
},
{
"id": "A8",
"status": "enabled",
"title": "PATTERNS — bounded mailbox z jawną utratą",
"content_tex": "Jednokomórkowa skrzynka ogranicza czas i pamięć ISR. Jej ważną częścią jest polityka przeciążenia i licznik strat. Nie należy nazywać jej kolejką; nie zachowuje serii zdarzeń i nie zastępuje synchronizacji wielordzeniowej ani RTOS."
}
],
"flow": [
{
"kind": "block",
"id": "task03.a1",
"title": "A1 CONTEXT · AKTYWNE — ISR transportuje, main konsumuje",
"content_tex": "\\textbf{Zachowany przykład:} \\nolinkurl{src/tasks/task03_uart_mailbox.c}.\\par Handler odpowiada za szybkie opróżnienie DATA i próbę publikacji jednego bajtu. Nie interpretuje komendy. Main odpowiada za konsumpcję. Gdy skrzynka jest pełna, kontrakt jawnie odrzuca najnowszy bajt i liczy stratę."
},
{
"kind": "block",
"id": "task03.a2",
"title": "A2 STRUCTURE · AKTYWNE — payload, flaga i telemetria",
"content_tex": "Skrzynkę tworzą \\texttt{mailbox\\_byte} i \\texttt{mailbox\\_full}. Osobne liczniki irq, accepted i dropped nie sterują algorytmem; są telemetrią dowodu. Każdy obiekt ma szerokość 32 bitów i jest volatile w tym jednordzeniowym kontrakcie bare-metal."
},
{
"kind": "block",
"id": "task03.a3",
"title": "A3 DISPATCH · AKTYWNE — ten sam IRQ, inny odbiorca",
"content_tex": "Linia 16 przechodzi przez ten sam dispatcher co Task02, lecz wpis tablicy wskazuje \\texttt{task03\\_uart\\_handler}. Dynamiczny wybór kończy się pośrednim jalr; decyzja accepted/drop odbywa się dopiero wewnątrz handlera na podstawie danych."
},
{
"kind": "block",
"id": "task03.a4",
"title": "A4 APPLICATION · AKTYWNE — A przyjęte, B odrzucone, C przyjęte",
"content_tex": "Po A skrzynka jest pełna i accepted=1. B wywołuje drugie IRQ, DATA zostaje opróżnione, lecz payload A pozostaje, a dropped rośnie do 1. Main pobiera A. Po C pusta skrzynka znów przyjmuje dane; main pobiera C."
},
{
"kind": "block",
"id": "task03.a5",
"title": "A5 FLOW · AKTYWNE — drain przed decyzją publish/drop",
"content_tex": "ISR najpierw odczytuje DATA, dzięki czemu usuwa źródło poziomowe niezależnie od stanu skrzynki. Następnie zwiększa \\texttt{irq\\_count} i wybiera publikację albo drop. Main czeka na konkretną liczbę obsług, a nie na sam upływ pętli."
},
{
"kind": "block",
"id": "task03.a6",
"title": "A6 STATE · AKTYWNE — EMPTY, FULL(A), FULL(A), EMPTY, FULL(C), EMPTY",
"content_tex": "Pełny ślad skrzynki to \\texttt{EMPTY -> FULL(A) -> FULL(A) -> EMPTY -> FULL(C) -> EMPTY}. Drugie przejście nie zmienia payloadu, ale zmienia licznik dropped; dlatego stan domenowy i telemetria muszą być czytane razem."
},
{
"kind": "block",
"id": "task03.a7",
"title": "A7 RUNTIME · AKTYWNE — trzy wejścia i trzy mret",
"content_tex": "Checkpoint ma pokazać irq=3, accepted=2, dropped=1, 65, 67 i full=0. W listingu wskaż trzy klasy operacji: MMIO DATA, zapisy globali przez ISR oraz odtworzenie kontekstu i mret w dispatcherze."
},
{
"kind": "block",
"id": "task03.a8",
"title": "A8 PATTERNS · AKTYWNE — bounded mailbox z jawną utratą",
"content_tex": "Jednokomórkowa skrzynka ogranicza czas i pamięć ISR. Jej ważną częścią jest polityka przeciążenia i licznik strat. Nie należy nazywać jej kolejką; nie zachowuje serii zdarzeń i nie zastępuje synchronizacji wielordzeniowej ani RTOS."
},
{
"kind": "exercise",
"id": "task03.proof",
"title": "Przewidywanie → wykonanie → wniosek",
"prompt_tex": "Prześledź A, B i C. Dla każdego bajtu zapisz stan FIFO, \\texttt{mailbox\\_full}, decyzję ISR i późniejszy odczyt main. Wyjaśnij, dlaczego B jest odrzucone, a mimo to DATA musi zostać odczytane.",
"evidence_tex": "Tabela trzech zdarzeń A/B/C, liczniki ISR, dwie wartości odebrane przez main, stan końcowy skrzynki oraz kod wyjścia Hazard3.",
"criterion": "Hazard3: irq_count=3, accepted=2, dropped=1, first_consumed='A'=65, second_consumed='C'=67, mailbox_full=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. Ślad ISR dla A, B i C}\\par\\noindent\\dotfill\\par\\noindent\\dotfill\\par\\textbf{3. Konsumpcja main, liczniki 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": [
"C12.WE01"
],
"learning_effect_refs": [
"C12.EN01",
"C12.EK01"
],
"assessment_criterion_ref": "C12.KW01"
}
},
"tasks_order": [
"task01",
"task02",
"task03"
]
}