feat: add lab-rv32i-freertos-isr-drivers card

This commit is contained in:
user
2026-07-21 19:14:19 +02:00
commit e923e1c3b0
174 changed files with 56091 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
# K15 — Explicit FromISR, UART and GPIO wrappers
## Position
- Series: FreeRTOS C++
- Lesson: L14, card K15
- Duration: 30 minutes
- Real machine-external interrupt on Hazard3
- Queue capacity 1 with drop-newest overflow
## Outcome
The student distinguishes task and ISR driver views, publishes UART/GPIO events
only through explicit FromISR APIs, accumulates one wake decision, yields once,
and proves backpressure plus immediate high-priority task execution.
## Lesson plan
| Time | Mode | Evidence |
| --- | --- | --- |
| 05 | ISR contract | task/ISR views and one IsrContext |
| 510 | real IRQ | mcause=0x8000000b and separate ISR stack |
| 1015 | UART queue | 0x41 queued, 0x42 drop-newest |
| 1520 | GPIO notify | edge 1→0, notification count 1 |
| 2025 | wake/yield | accumulated wake=true, exactly one yield |
| 2530 | context switch | receiver at tick 1 before stimulus resumes |
## Acceptance
- the interrupt is a real machine-external IRQ through the FreeRTOS trap path;
- Uart and GpioPin expose distinct task and ISR views;
- only xQueueSendFromISR and vTaskNotifyGiveFromISR are used in the handler;
- one IsrContext accumulates both wake requests;
- RX queue capacity 1 accepts 0x41 and drop-newest rejects/counts 0x42;
- UART ready and GPIO edge MMIO-model state clear from 1 to 0;
- higherPriorityTaskWoken is true and yield_if_needed is called once;
- receiver gets byte 0x41 and notification count 1 at tick 1;
- receiver sees stimulus_after=0; stimulus later sees receiver_done=1;
- static storage has heap delta zero and target exits with PASS.
## Main traps
1. Calling an ordinary blocking API from an ISR.
2. Automatically guessing execution context instead of explicit views.
3. Yielding after each primitive rather than once at handler exit.
4. Ignoring queue overflow or silently overwriting data.
5. Performing parsing, debounce or long GPIO policy in the handler.
+344
View File
@@ -0,0 +1,344 @@
% Generated from json/card_source.json by tools/render_card.py.
% Do not edit manually; update the JSON and regenerate.
\documentclass[12pt,a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[polish]{babel}
\usepackage{csquotes}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{xcolor}
\usepackage[a4paper,left=2.15cm,right=2.15cm,top=0.5cm,bottom=0.5cm,headheight=24mm,headsep=3mm,includehead]{geometry}
\usepackage{eso-pic}
\usepackage{marginnote}
\usepackage{array}
\usepackage{tabularx}
\usepackage{graphicx}
\usepackage{pdflscape}
\usepackage{float}
\usepackage{silence}
\WarningFilter{soulutf8}{This package is obsolete}
\usepackage{pdfcomment}
\usepackage{enumitem}
\usepackage{needspace}
\usepackage{fancyhdr}
\usepackage{lastpage}
\usepackage{microtype}
\usepackage[most]{tcolorbox}
\usepackage{qrcode}
\IfFileExists{references.bib}{%
\usepackage[backend=biber,style=numeric,sorting=none]{biblatex}%
\addbibresource{references.bib}%
}{}
\hypersetup{hidelinks}
\IfFileExists{build-meta.tex}{%
\input{build-meta.tex}%
}{%
\newcommand{\BuildCommit}{lokalna}%
}
\newcommand{\DocumentAuthor}{M. Pabiszczak}
\newcommand{\DocumentYear}{2026}
\newcommand{\CardSeries}{freertos-cpp}
\newcommand{\CardNumber}{15}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{isr-drivers}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{02f6cd71-5c85-4883-a237-1d4ba08d9469}
\newcommand{\EmptyCheck}{\(\square\)}
\newcommand{\EscAnswerLines}[1][3]{\par\noindent\dotfill\par\noindent\dotfill\par\noindent\dotfill}
\newcommand{\EscWriteRow}[1][2.8em]{\rule{0pt}{#1}}
\setlength{\parindent}{0pt}
\setlength{\parskip}{0.45em}
\setlength{\headheight}{24mm}
\setlength{\headsep}{3mm}
\setlength{\footskip}{8mm}
\setlength{\marginparwidth}{1.5cm}
\setlength{\marginparsep}{0.25cm}
\renewcommand{\arraystretch}{1.22}
% Margin separator lines disabled for layout trial.
\newcommand{\ESCPageResourceHeader}{%
\begingroup%
\setlength{\parskip}{0pt}%
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0.35pt}%
\setlength{\arrayrulewidth}{0.35pt}%
\noindent\fbox{%
\begin{minipage}[c][23.5mm][c]{\dimexpr\textwidth-2\fboxrule\relax}%
\begin{minipage}[c][23mm][c]{\dimexpr\linewidth-24mm-0.35pt\relax}%
\setlength{\tabcolsep}{0pt}%
\renewcommand{\arraystretch}{0}%
\begin{tabularx}{\linewidth}{@{}p{\dimexpr0.50000000\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.15126050\linewidth-\arrayrulewidth\relax}|X@{}}%
\parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries TITLE}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{7.7}{7.9}\selectfont\ttfamily\bfseries Explicit FromISR, UART and GPIO Wrappers}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries VER.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.6}{6.8}\selectfont\ttfamily\bfseries v00.01}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries DATETIME}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries 2026-07-19T00:00:00+02:00}\hspace{0.45mm}}\par} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}p{\dimexpr0.50000000\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.25210084\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.14285714\linewidth-\arrayrulewidth\relax}|X@{}}%
\parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries PROJECT}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{7.7}{7.9}\selectfont\ttfamily\bfseries Freestanding C++ nad FreeRTOS}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries SERIES}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries FreeRTOS C++}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries CARD}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries 15/16}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries SHEET}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries \thepage/\pageref{LastPage}}\hspace{0.45mm}}\par} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}p{\dimexpr0.05882353\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.05042017\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.14705882\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.09243697\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.07563025\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.07563025\linewidth-\arrayrulewidth\relax}|X@{}}%
\parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries SUBJ.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries Inf.}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries PROG.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries CORE}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries SCOPE}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries LEVEL}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries POS.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hbox to\linewidth{\hspace{0.35mm}{\fontsize{3.4}{3.75}\selectfont\ttfamily\bfseries GITEA UUID}\hfill{\fontsize{3.4}{3.75}\selectfont\ttfamily 02f6cd71-5c85-4883-a237-1d4ba08d9469}\hspace{0.35mm}}\par\nointerlineskip\hbox to\linewidth{\hspace{0.35mm}{\fontsize{3.4}{3.75}\selectfont\ttfamily\bfseries CARD UUID} {\fontsize{3.4}{3.75}\selectfont\ttfamily 02f6cd71-5c85-4883-a237-1d4ba08d9469}\hfill{\fontsize{3.4}{3.75}\selectfont\ttfamily\bfseries AUTHOR M. Pabiszczak}\hspace{0.35mm}}} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}X@{}}%
\parbox[c][3.46276mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{4.5}{4.85}\selectfont\ttfamily\bfseries GITEA} {\fontsize{4.5}{4.85}\selectfont\ttfamily\href{https://zsl-gitea.mpabi.pl/edu-freertos-cpp/lab-rv32i-freertos-isr-drivers}{\nolinkurl{https://zsl-gitea.mpabi.pl/edu-freertos-cpp/lab-rv32i-freertos-isr-drivers}}}} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}X@{}}%
\parbox[c][3.46276mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{4.5}{4.85}\selectfont\ttfamily\bfseries HTML} {\fontsize{4.5}{4.85}\selectfont\ttfamily\href{}{\nolinkurl{}}}} \\%
\end{tabularx}%
\end{minipage}%
\vrule width0.35pt%
\begin{minipage}[c][23mm][c]{24mm}\centering%
{\tiny QR wyłączony}%
\end{minipage}%
\end{minipage}%
}%
\endgroup%
}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[C]{\ESCPageResourceHeader}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
\newcommand{\ESCMarginTag}[4]{%
\hspace*{#1}\textcolor{#2}{#3~#4}%
}
\newcommand{\ESCSectionBlockStart}{%
\Needspace{8\baselineskip}%
\par\vspace{0.35em}%
\noindent\textcolor{black!28}{\rule{\textwidth}{0.35pt}}%
\par\vspace{0.15em}%
}
\newcommand{\ESCSectionBlockEnd}{%
\par\vspace{0.25em}%
\noindent\textcolor{black!18}{\rule{\textwidth}{0.25pt}}%
\par\vspace{0.45em}%
}
\newcommand{\ESCTinyStepSeparator}{%
\par\vspace{0.10em}%
\noindent{\color{black!18}\leaders\hbox{\rule{0.60em}{0.22pt}\hspace{0.38em}}\hfill\kern0pt}%
\par\vspace{0.10em}%
}
\newtcolorbox{ESCTaskFrame}[1]{enhanced,breakable,arc=0pt,boxrule=0.35pt,colback=white,colframe=black,boxsep=0pt,left=1.4mm,right=1.4mm,top=0.8mm,bottom=0.8mm,colbacktitle=black!7,coltitle=black,title={\ttfamily\bfseries TASK\quad #1}}
\newtcolorbox{ESCBlockFrame}[1]{enhanced,breakable,arc=0pt,boxrule=0.35pt,colback=white,colframe=black!55,boxsep=0pt,left=1.0mm,right=1.0mm,top=0.6mm,bottom=0.6mm,colbacktitle=black!4,coltitle=black,title={\ttfamily\bfseries BLOCK\quad #1}}
\newtcolorbox{ESCStepFrame}[1]{enhanced,breakable,arc=0pt,boxrule=0.35pt,colback=white,colframe=black!28,boxsep=0pt,left=0.8mm,right=0.8mm,top=0.45mm,bottom=0.45mm,colbacktitle=black!2,coltitle=black,title={\ttfamily STEP\quad #1}}
\newtcolorbox{ESCConclusionFrame}{enhanced,breakable,arc=0pt,boxrule=0.45pt,colback=blue!2,colframe=blue!45!black,boxsep=0pt,left=1.2mm,right=1.2mm,top=0.7mm,bottom=0.7mm,colbacktitle=blue!7,coltitle=black,title={\ttfamily\bfseries WNIOSEK}}
\newcommand{\ESCLearningTreeWidget}{%
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\hspace*{0.28em}\textcolor{orange!85!black}{EK~LOCAL~DBG.ISR}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Mierzy mcause, register transitions, queued/dropped bytes, wake flag i order.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~DBG.ISR}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Pokazuje 0x41/0x42, wake 1, yield 1, receiver-before-resume i PASS.}}\par%
\end{minipage}%
}%
\end{minipage}%
]{}
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\hspace*{0.28em}\textcolor{green!50!black}{EN~LOCAL~EN~RTOS.ISR}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Analizuje ograniczenia ISR, overflow i delegowanie pracy.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~KW~RTOS.ISR}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Nie wywołuje blocking API, definiuje drop-newest i przenosi parsing/debounce do taska.}}\par%
\end{minipage}%
}%
\end{minipage}%
}
}
\begin{document}
\sloppy
\vspace{1.0em}
\noindent{\Large\bfseries Cel karty}\par
\vspace{0.35em}
Uczeń publikuje UART RX i GPIO edge z realnego external IRQ przez jawne FromISR views, akumuluje wake i wykonuje jeden yield.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\vspace{0.7em}
\noindent{\Large\bfseries Zakres karty}\par
\vspace{0.35em}
ISR nie wykonuje blocking API, parsowania ani debounce. Queue overflow jest jawnym drop-newest z licznikiem, a ciężka praca przechodzi do taska.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\clearpage
\ESCSectionBlockStart
\section{Realny IRQ i explicit views}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K15.WE01.TECH.LOCAL.DBG.ISR.01 | WE 01: Explicit FromISR drivers. Implementacja jawnej,\textCR bounded granicy między IRQ a taskami dla UART i GPIO. | EK LOCAL DBG.ISR.01: Mierzy mcause,\textCR register transitions, queued/dropped bytes, wake flag i order. | KW LOCAL DBG.ISR.01:\textCR Pokazuje 0x41/0x42, wake 1, yield 1, receiver-before-resume i PASS.}\par
\vspace{0.10em}%
\noindent K1: Zmierz mcause i status UART/GPIO 1 do 0.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Potwierdź ISR stack różny od task stacks.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Wyzwól machine-external IRQ, porównaj task oraz ISR views UART/GPIO i potwierdź osobny ISR stack oraz clear sources.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{UART backpressure i GPIO notification}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K15.WE01.TECH.LOCAL.DBG.ISR.01 | WE 01: Explicit FromISR drivers. Implementacja jawnej,\textCR bounded granicy między IRQ a taskami dla UART i GPIO. | EK LOCAL DBG.ISR.01: Mierzy mcause,\textCR register transitions, queued/dropped bytes, wake flag i order. | KW LOCAL DBG.ISR.01:\textCR Pokazuje 0x41/0x42, wake 1, yield 1, receiver-before-resume i PASS.}\par
\vspace{0.10em}%
\noindent K1: Pokaż queued 0x41 i dropped 0x42.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Pokaż notification sent/taken 1.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Wyślij dwa bajty do queue capacity 1, policz drop-newest, a GPIO edge opublikuj jako notification tego samego receivera.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Wake accumulation, one yield i bounded work}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K15.WE01.OG.LOCAL.RTOS.ISR.01 | WE 01: Explicit FromISR drivers. Implementacja jawnej,\textCR bounded granicy między IRQ a taskami dla UART i GPIO. | EN LOCAL RTOS.ISR.01: Analizuje\textCR ograniczenia ISR, overflow i delegowanie pracy. | KW LOCAL RTOS.ISR.01: Nie wywołuje\textCR blocking API, definiuje drop-newest i przenosi parsing/debounce do taska.}\par
\vspace{0.10em}%
\noindent K1: Potwierdź wake true, yield calls 1 i tick receivera 1.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Uzasadnij overflow oraz granicę ISR/task.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Połącz local wake flags w jednym IsrContext, wykonaj yield raz, dowiedź receiver-before-resume i przypisz parsing/debounce do taska.
\ESCSectionBlockEnd
\end{document}
+198
View File
@@ -0,0 +1,198 @@
\documentclass[10pt]{article}
\usepackage[T1]{fontenc}\usepackage[utf8]{inputenc}\usepackage[polish]{babel}
\usepackage[a4paper,margin=1.55cm]{geometry}
\usepackage{array,tabularx,booktabs,amsmath,amssymb,xcolor,listings,hyperref,fancyhdr,lastpage,enumitem}
\definecolor{accent}{HTML}{16324A}\definecolor{accentlight}{HTML}{EEF3F7}\definecolor{rulegray}{HTML}{D7DEE5}
\hypersetup{colorlinks=true,linkcolor=accent,urlcolor=blue}
\IfFileExists{build-meta.tex}{\input{build-meta.tex}}{\newcommand{\BuildCommit}{local}}
\newcommand{\PublisherDomain}{mpabi}
\newcommand{\CardArea}{inf}
\newcommand{\CardSeries}{freertos-cpp}
\newcommand{\CardNumber}{15}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{isr-drivers}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{02f6cd71-5c85-4883-a237-1d4ba08d9469}
\newcommand{\blank}[1]{\rule{#1}{.2pt}}
\lstset{language=C++,basicstyle=\ttfamily\scriptsize,columns=fullflexible,keepspaces=true,frame=single,breaklines=true,showstringspaces=false,numbers=none,backgroundcolor=\color{accentlight},rulecolor=\color{rulegray}}
\pagestyle{fancy}\fancyhf{}
\lhead{\textbf{K15 · FreeRTOS C++ · FromISR}}\rhead{\small L14 · UART + GPIO}
\lfoot{\scriptsize commit \BuildCommit}\cfoot{\scriptsize \thepage/\pageref{LastPage}}\rfoot{\scriptsize V11.3.0 / \CardVersion}
\setlength{\headheight}{14pt}\setlength{\footskip}{19pt}
\setlist[itemize]{nosep,leftmargin=1.45em}\setlist[enumerate]{nosep,leftmargin=1.65em}
\begin{document}\sloppy
\begin{center}
{\LARGE\bfseries Jawne FromISR: UART RX i GPIO edge}\par
\vspace{.25em}{\large jeden IsrContext, jedna decyzja yield, jawny backpressure}\par
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.65cm}Xp{1.75cm}X@{}}
\toprule
Karta & K15 / \CardCount & Czas & 30 minut \\
Platforma & Hazard3 / RV32I & IRQ & machine external \\
RX queue & capacity 1 & Overflow & drop-newest \\
Wersja & \CardVersion & UUID karty & \texttt{02f6cd71-...} \\
\bottomrule
\end{tabularx}
\section*{Jawny kontrakt handlera}
\begin{lstlisting}
IsrContext isr;
auto byte = uart.isr_view().read_rx_from_isr();
rx.send_from_isr(byte, isr);
notify.give_from_isr(isr);
isr.yield_if_needed(); // dokladnie raz
\end{lstlisting}
\noindent\fcolorbox{accent}{accentlight}{\begin{minipage}{.94\textwidth}
\textbf{Kontrakt K15.} ISR view nie ma timeoutu ani blocking API. Każde
\texttt{...FromISR} dokłada żądanie wake do jednego contextu. Handler czyści
źródła, publikuje bounded dane i dopiero na końcu raz podejmuje decyzję yield.
\end{minipage}}
\section*{Plan 30 minut}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.35cm}p{3.1cm}X@{}}
\toprule Czas & Tryb & Dowód \\
\midrule
0--5 & views & task view kontra ISR view \\
5--10 & IRQ & \texttt{mcause=0x8000000b}, ISR stack \\
10--15 & UART & 0x41 queued, 0x42 dropped \\
15--20 & GPIO & edge 1--0, notification=1 \\
20--25 & wake & flag true, yield calls=1 \\
25--30 & order & receiver przed resume stimulus \\
\bottomrule
\end{tabularx}
\section*{Predykcja}
Czy drugi bajt zmieści się w pełnej kolejce capacity 1? \blank{2cm}.
Ile razy handler powinien wywołać yield dla dwóch publikacji? \blank{2cm}.
\newpage
\section{Realny external IRQ i bounded handler}
\begin{center}
\texttt{stimulus: UART[41,42] + GPIO edge + SET\_IRQ}\\
$\downarrow$ \texttt{machine external trap / ISR stack}\\
$\downarrow$ \texttt{queue FromISR + notify FromISR + clear sources}\\
$\downarrow$ \texttt{one yield -- rx-worker -- resume stimulus}
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{5.3cm}p{3.1cm}X@{}}
\toprule Pomiar & Predykcja & Odczyt \\
\midrule
\texttt{mcause} & \texttt{0x8000000b} & \blank{2.5cm} \\
ISR SP różny od task SP & true & \blank{2.5cm} \\
external IRQ state po clear & 0 & \blank{2.5cm} \\
UART ready przed / po ISR & 1 / 0 & \blank{2.5cm} \\
GPIO edge przed / po ISR & 1 / 0 & \blank{2.5cm} \\
\bottomrule
\end{tabularx}
\section{UART RX i backpressure}
Dwa bajty czekają w modelu rejestrów, lecz queue ma jedno miejsce. Handler ma
limit dwóch odczytów; nie wykonuje parsowania ani oczekiwania.
\noindent\begin{tabularx}{\textwidth}{@{}p{5.3cm}p{3.1cm}X@{}}
\toprule Pomiar & Predykcja & Odczyt \\
\midrule
queued count / byte & 1 / \texttt{0x41} & \blank{2.5cm} \\
dropped count / byte & 1 / \texttt{0x42} & \blank{2.5cm} \\
overflow policy & drop-newest & \blank{2.5cm} \\
receiver byte & \texttt{0x41} & \blank{2.5cm} \\
\bottomrule
\end{tabularx}
Porównaj drop-newest, drop-oldest i overwrite dla UART:\\[.4em]
\blank{16cm}\\[.8em]\blank{16cm}
\newpage
\section{Task view i ISR view}
\noindent\begin{tabularx}{\textwidth}{@{}p{3.2cm}XX@{}}
\toprule Wrapper & Task view & ISR view \\
\midrule
\texttt{Uart} & enable/configure, test inject & ready/read, bez wait \\
\texttt{GpioPin} & direction/write output & edge pending/clear \\
\texttt{Queue} & receive(timeout) & send\_from\_isr \\
\texttt{Notification} & task odbiera & give\_from\_isr \\
\bottomrule
\end{tabularx}
\section{Akumulacja wake i jeden yield}
\begin{lstlisting}
BaseType_t local = pdFALSE;
xQueueSendFromISR(queue, &byte, &local); isr.merge(local);
local = pdFALSE;
vTaskNotifyGiveFromISR(worker, &local); isr.merge(local);
isr.yield_if_needed();
\end{lstlisting}
\noindent\begin{tabularx}{\textwidth}{@{}p{5.3cm}p{3.1cm}X@{}}
\toprule Pomiar & Predykcja & Odczyt \\
\midrule
notification sent/taken & 1 / 1 & \blank{2.5cm} \\
higher priority task woken & true & \blank{2.5cm} \\
yield requested & true & \blank{2.5cm} \\
\texttt{yield\_if\_needed} calls & 1 & \blank{2.5cm} \\
receiver tick & 1 & \blank{2.5cm} \\
\bottomrule
\end{tabularx}
\section*{Dowód natychmiastowego przełączenia}
\begin{itemize}
\item receiver widzi \texttt{stimulus\_after=0};
\item po powrocie z IRQ stimulus widzi \texttt{receiver\_done=1};
\item receiver ustawia GPIO output z bitu 0 bajtu \texttt{0x41}: data=1.
\end{itemize}
Co zmieniłby brak yield przy wake=true?\\[.4em]
\blank{16cm}\\[.8em]\blank{16cm}
\section*{Granica ISR}
Parsing, debounce, logowanie i retry są pracą taska. ISR tylko odczytuje bounded
FIFO, czyści źródło i publikuje. Static queue/task storage daje heap delta 0.
\newpage
\section{Hazard3/GDB i zaliczenie}
\begin{lstlisting}[language=bash]
make check
riscv64-unknown-elf-gdb build/task01_isr_drivers/prog.elf
b isr_drivers_debug_checkpoint
\end{lstlisting}
\begin{lstlisting}
p/x g_mcause
p g_uart_status_before_isr
p g_uart_status_after_isr
p g_gpio_edge_before_isr
p g_gpio_edge_after_isr
p g_rx_queued
p/x g_queued_byte
p g_rx_dropped
p/x g_dropped_byte
p g_notification_taken
p g_higher_priority_task_woken
p g_isr_yield_calls
p g_stimulus_after_seen_by_receiver
p g_receiver_done_at_stimulus_resume
p g_isr_drivers_pass
\end{lstlisting}
\section*{Zaliczenie}
\begin{itemize}
\item $\square$ pokazuję realny external IRQ i osobny ISR stack;
\item $\square$ używam wyłącznie jawnych metod \texttt{from\_isr};
\item $\square$ kolejkuję 0x41 i jawnie liczę drop-newest 0x42;
\item $\square$ clear UART/GPIO zmienia status 1 na 0;
\item $\square$ akumuluję wake=true i wywołuję yield dokładnie raz;
\item $\square$ receiver działa przed resume stimulus i ustawia GPIO=1.
\end{itemize}
\section*{Wyjście}
Dlaczego automatyczne zgadywanie task/ISR contextu osłabia API?\\[.5em]
\blank{16cm}\\[1em]
Gdzie zaimplementujesz parsing i debounce, i dlaczego?\\[.5em]
\blank{16cm}
\vfill
\noindent\textbf{Następna karta K16:} integracja usług RTOS, end-to-end trace,
memory/stack report, pressure injection i uzasadnienie każdej granicy.
\end{document}