feat: add lab-rv32i-freertos-scheduler-states card

This commit is contained in:
user
2026-07-21 19:14:20 +02:00
commit 71ddd87301
66 changed files with 34187 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
# K04 — Scheduler states, priorities, time slicing and typed ticks
## Position in the series
- Series: FreeRTOS C++
- Lesson: L03, card K04
- Duration: 30 minutes
- Executables: exactly one
- Kernel: unchanged FreeRTOS V11.3.0 in C
- C++ mode: freestanding C++17, no exceptions, RTTI or hosted `libstdc++`
- New C++ surface: `Ticks`, `TickPoint`, non-owning `TaskRef`
K02 introduced task entry and lifecycle, while K03 established ownership and
RAII for a heap buffer. K04 deliberately does not build a large facade. It
first exposes the scheduler's raw evidence and adds only types that prevent a
duration, a tick point and an owning task object from being confused.
## Outcome
After 30 minutes the student can predict and verify `READY`, `RUNNING`,
`BLOCKED` and `DELETED`; distinguish a relative delay from a periodic wake
reference; explain time slicing for equal priorities; and use the order
`BEFORE -> HIGH -> AFTER` as proof of immediate priority preemption.
## Lesson plan — 30 minutes
| Time | Mode | Required evidence |
| --- | --- | --- |
| 04 | prediction | fill the first state/priority table without running code |
| 48 | typed time | distinguish `Ticks` from `TickPoint`; no assumption that tick means ms |
| 813 | time slicing | obtain `A,B,A` or `B,A,B` at equal priority 2 |
| 1319 | blocked state | show A=`eBlocked`, B=`eRunning`, elapsed exactly 3 ticks |
| 1925 | priority change | show B at priority 3 and marker order `1,2,3` |
| 2530 | interpretation | compare relative/periodic delay, state limits and stale `TaskRef` |
## Canonical experiment
```text
scheduler starts
-> startup probe: A READY, B READY
-> equal priority 2: A/B alternate on tick boundaries
-> A calls vTaskDelay(3)
-> A BLOCKED; B RUNNING
-> at start+3 A becomes READY and then RUNNING
-> A writes BEFORE=1 and raises B to priority 3
-> B preempts, writes HIGH=2, lowers itself to priority 2
-> A resumes inside/after vTaskPrioritySet and writes AFTER=3
-> workers delete themselves; verifier writes terminal snapshot and PASS
```
The test accepts either initial equal-priority order. It requires the
alternating relation `first == third && first != second`.
## Stable evidence contract
| Evidence | Required relation |
| --- | --- |
| `g_alternating_tasks[0..2]` | A,B,A or B,A,B |
| delay snapshot | A=`eBlocked`, B=`eRunning` |
| delay timestamps | `end - start == 3`, observation lies before end |
| priority snapshot | A=`eReady`, B=`eRunning`, B priority 3 |
| `g_priority_order` | exactly `1,2,3` |
| terminal snapshot | A/B recorded as `eDeleted`, handles no longer queried |
| `g_scheduler_states_pass` | 1 |
## Prediction table
The student completes state and priority before inspecting the executable:
| Event | A state / priority | B state / priority | Current task | Why? |
| --- | --- | --- | --- | --- |
| startup probe | | | | |
| A before delay | | | | |
| B while A delays | | | | |
| A after 3 ticks | | | | |
| before raise | | | | |
| B at p=3 | | | | |
| after API returns | | | | |
| verifier | | | | |
## Typed wrapper boundary
```cpp
freertos::Ticks duration{3};
const auto start = freertos::TickPoint::now();
vTaskDelay(duration.count());
const auto elapsed = freertos::TickPoint::now() - start;
freertos::TaskRef peer{handle}; // no ownership
peer.set_priority(3);
```
`TaskRef` is the size of one native handle and has no virtual dispatch. It
must not be used after the task is deleted. K04 uses raw scheduling calls on
purpose; a broad `Scheduler` facade is deferred until K09.
## Misconceptions to surface
1. Highest priority does not mean “always running”: a high-priority task can
be blocked and therefore ineligible.
2. `vTaskDelay(3)` does not promise three milliseconds unless the configured
tick rate makes that conversion true.
3. `vTaskDelay` is relative; repeated work plus relative delays can drift.
`xTaskDelayUntil` advances a periodic reference.
4. Equal priority does not establish a fixed first task; verify alternation,
not a guessed first ID.
5. A handle is not ownership. After deletion, `TaskRef` can dangle.
## Acceptance
- host test proves typed tick arithmetic, wrap-around and one-handle `TaskRef`;
- ELF contains no RTTI, vtable, exception/unwind or hosted C++ dependency;
- Hazard3 proves a three-entry alternating trace;
- the blocked snapshot and exactly-three-tick delay pass;
- priority markers are exactly `1,2,3` and B is priority 3 at marker 2;
- all eight snapshots match the intended state transition sequence;
- student explains why the startup snapshot is taken after scheduler start.
+391
View File
@@ -0,0 +1,391 @@
% 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}{04}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{scheduler-states}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{853a7dd7-b00b-4f4a-96e8-c160fc5bb04a}
\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 Scheduler: stany, priorytety i typowane ticki}\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 04/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 853a7dd7-b00b-4f4a-96e8-c160fc5bb04a}\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 853a7dd7-b00b-4f4a-96e8-c160fc5bb04a}\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-scheduler-states}{\nolinkurl{https://zsl-gitea.mpabi.pl/edu-freertos-cpp/lab-rv32i-freertos-scheduler-states}}}} \\%
\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.SCHED}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Koreluje snapshoty, ticki i kolejność wykonania z decyzjami kernela.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~DBG.SCHED}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Pokazuje X,Y,X; elapsed=3; A BLOCKED; B/p3 oraz porządek 1,2,3.}}\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.MODEL}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Analizuje gotowość, stan, priorytet i jednostkę czasu.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~KW~RTOS.MODEL}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Wyjaśnia BLOCKED mimo wysokiego priorytetu oraz relative delay kontra periodic reference.}}\par%
\end{minipage}%
}%
\end{minipage}%
}
}
\begin{document}
\sloppy
\vspace{1.0em}
\noindent{\Large\bfseries Cel karty}\par
\vspace{0.35em}
Uczeń przewiduje i odtwarza stany dwóch tasków, mierzy blokadę w tickach i dowodzi natychmiastowego wywłaszczenia porządkiem BEFORE--HIGH--AFTER.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\vspace{0.7em}
\noindent{\Large\bfseries Zakres karty}\par
\vspace{0.35em}
Jedno zadanie uruchamia prawdziwy scheduler FreeRTOS na Hazard3. Warstwa C++ dodaje tylko typy \texttt{Ticks}, \texttt{TickPoint} oraz nieposiadający \texttt{TaskRef}; pełna fasada schedulera i własność taska są poza zakresem.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\clearpage
\ESCSectionBlockStart
\section{Stan i gotowość do wykonania}
\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}{K04.WE01.OG.LOCAL.RTOS.MODEL.01 | WE 01: Stany, priorytety i ticki. Przewidzenie i\textCR udowodnienie decyzji schedulera FreeRTOS. | EN LOCAL RTOS.MODEL.01: Analizuje gotowość,\textCR stan, priorytet i jednostkę czasu. | KW LOCAL RTOS.MODEL.01: Wyjaśnia BLOCKED mimo wysokiego\textCR priorytetu oraz relative delay kontra periodic reference.}\par
\vspace{0.10em}%
\noindent K1: Wypełnij tabelę stanów przed uruchomieniem kodu.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Wyjaśnij, dlaczego BLOCKED/p4 przegrywa z READY/p2.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Zadanie o najwyższym priorytecie wygrywa tylko wtedy, gdy jest gotowe. Przewidź READY, RUNNING, BLOCKED i DELETED w ośmiu punktach.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Time slicing i blokada na trzy ticki}
\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}{K04.WE01.TECH.LOCAL.DBG.SCHED.01 | WE 01: Stany, priorytety i ticki. Przewidzenie i\textCR udowodnienie decyzji schedulera FreeRTOS. | EK LOCAL DBG.SCHED.01: Koreluje snapshoty, ticki\textCR i kolejność wykonania z decyzjami kernela. | KW LOCAL DBG.SCHED.01: Pokazuje X,Y,X;\textCR elapsed=3; A BLOCKED; B/p3 oraz porządek 1,2,3.}\par
\vspace{0.10em}%
\noindent K1: Sprawdź relację first==third i first!=second.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Zapisz snapshot BLOCKED/RUNNING oraz trzy ticki elapsed.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Dopuść A--B--A albo B--A--B, a następnie pokaż A jako BLOCKED i różnicę end-start równą 3 ticki.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Natychmiastowe wywłaszczenie po zmianie priorytetu}
\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}{K04.WE01.TECH.LOCAL.DBG.SCHED.01 | WE 01: Stany, priorytety i ticki. Przewidzenie i\textCR udowodnienie decyzji schedulera FreeRTOS. | EK LOCAL DBG.SCHED.01: Koreluje snapshoty, ticki\textCR i kolejność wykonania z decyzjami kernela. | KW LOCAL DBG.SCHED.01: Pokazuje X,Y,X;\textCR elapsed=3; A BLOCKED; B/p3 oraz porządek 1,2,3.}\par
\vspace{0.10em}%
\noindent K1: Pokaż B jako RUNNING/p3, gdy A jest READY/p2.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Udowodnij porządek markerów 1,2,3.\quad D1\par
\par\vspace{0.18em}%
\endgroup
A zapisuje BEFORE=1, podnosi B do p3 i dopiero po wznowieniu zapisuje AFTER=3. B musi zapisać HIGH=2 pomiędzy nimi.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Typy i granica nieposiadającej referencji}
\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}{K04.WE01.OG.LOCAL.RTOS.MODEL.01 | WE 01: Stany, priorytety i ticki. Przewidzenie i\textCR udowodnienie decyzji schedulera FreeRTOS. | EN LOCAL RTOS.MODEL.01: Analizuje gotowość,\textCR stan, priorytet i jednostkę czasu. | KW LOCAL RTOS.MODEL.01: Wyjaśnia BLOCKED mimo wysokiego\textCR priorytetu oraz relative delay kontra periodic reference.}\par
\vspace{0.10em}%
\noindent K1: Porównaj vTaskDelay z xTaskDelayUntil.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Uzasadnij brak odczytu przez TaskRef po delete.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Ticks opisuje czas trwania, TickPoint punkt licznika, a TaskRef tylko widok uchwytu. Po usunięciu taska widok może wisieć.
\ESCSectionBlockEnd
\end{document}
+284
View File
@@ -0,0 +1,284 @@
\documentclass[10pt]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[polish]{babel}
\usepackage[a4paper,margin=1.55cm]{geometry}
\usepackage{array,tabularx,booktabs}
\usepackage{amsmath,amssymb}
\usepackage{xcolor,listings}
\usepackage{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}{04}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{scheduler-states}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{853a7dd7-b00b-4f4a-96e8-c160fc5bb04a}
\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{K04 · FreeRTOS C++ · scheduler}}
\rhead{\small L03 · stany, priorytety, ticki}
\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 Scheduler: stany, priorytety i typowane ticki}\par
\vspace{.25em}
{\large przewidź przełączenie, potem udowodnij je śladem}\par
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.65cm}Xp{1.55cm}X@{}}
\toprule
Karta & K04 / \CardCount & Czas & 30 minut \\
Platforma & Hazard3 / RV32I & Język & freestanding C++17 \\
Scheduler & preemption + time slicing & Kernel & V11.3.0, bez zmian \\
Wersja & \CardVersion & UUID karty & \texttt{853a7dd7-...} \\
\bottomrule
\end{tabularx}
\section*{Cel i jedna sekwencja dowodowa}
Dwa zadania A i B mają priorytet 2. Najpierw scheduler dzieli CPU między
równych. Potem A blokuje się na 3 ticki. Na końcu A podnosi priorytet B do 3.
Nie zgadujemy kolejności --- zapisujemy stany, ticki oraz znaczniki wykonania.
\begin{center}
\texttt{READY} $\rightarrow$ \texttt{RUNNING} $\rightarrow$
\texttt{BLOCKED} $\rightarrow$ \texttt{READY} $\rightarrow$
\texttt{RUNNING} $\rightarrow$ \texttt{DELETED}
\end{center}
\noindent\fcolorbox{accent}{accentlight}{%
\begin{minipage}{.94\textwidth}
\textbf{Dwa warunki K04.} Zadanie o najwyższym priorytecie wygrywa tylko wtedy,
gdy jest gotowe. Tick jest jednostką schedulera, nie ukrytą nazwą milisekundy.
\end{minipage}}
\section*{Plan 30 minut}
\begin{tabularx}{\textwidth}{@{}p{1.35cm}p{3.0cm}X@{}}
\toprule
Czas & Tryb & Dowód ucznia \\
\midrule
0--4 & predykcja & tabela stanów i bieżącego zadania \\
4--8 & czas typowany & \texttt{Ticks} kontra \texttt{TickPoint} \\
8--13 & time slicing & A--B--A albo B--A--B przy priorytecie 2 \\
13--19 & blokada & A=BLOCKED, B=RUNNING, różnica ticków 3 \\
19--25 & priorytet & BEFORE--HIGH--AFTER ma wartości 1--2--3 \\
25--30 & wyjście & delay względny/okresowy i granica \texttt{TaskRef} \\
\bottomrule
\end{tabularx}
\section*{Najpierw przewidź}
Który identyfikator pojawi się pierwszy: A czy B? \blank{2cm}\quad
Czy test powinien wymagać właśnie tej odpowiedzi? \blank{5cm}
\newpage
\section{Stany są warunkiem kwalifikacji do CPU}
\begin{tabularx}{\textwidth}{@{}p{2.5cm}p{4.0cm}X@{}}
\toprule
Stan & Czy może teraz dostać CPU? & Typowa przyczyna \\
\midrule
\texttt{eRunning} & tak, jedno zadanie na rdzeń & scheduler właśnie je wybrał \\
\texttt{eReady} & tak, czeka na wybór & równy/niższy priorytet lub wywłaszczenie \\
\texttt{eBlocked} & nie & delay albo oczekiwanie na zdarzenie \\
\texttt{eSuspended} & nie & jawne zawieszenie, nie upływ czasu \\
\texttt{eDeleted} & nie & stan terminalny w śladzie tej karty \\
\bottomrule
\end{tabularx}
\subsection*{Pułapka „najwyższy zawsze działa”}
Jeżeli A ma priorytet 4, ale jest \texttt{BLOCKED}, a B ma priorytet 2 i jest
\texttt{READY}, scheduler wybierze \blank{2cm}, ponieważ
\blank{10cm}.
\subsection*{Równe priorytety i time slicing}
Przy \texttt{configUSE\_PREEMPTION=1} oraz
\texttt{configUSE\_TIME\_SLICING=1} tick może przenieść wykonanie do innego
gotowego zadania o tym samym priorytecie. Zalicza relacja:
\begin{center}
\texttt{first == third \&\& first != second}
\end{center}
Wpisz dwa dopuszczalne ślady: \blank{3cm}\quad lub \quad\blank{3cm}.
\section{Czas: wartość ma znaczenie dopiero z jednostką}
\begin{lstlisting}
freertos::Ticks duration{3};
const auto start = freertos::TickPoint::now();
vTaskDelay(duration.count());
const auto elapsed = freertos::TickPoint::now() - start;
\end{lstlisting}
\texttt{Ticks} jest czasem trwania. \texttt{TickPoint} jest punktem na
zawijającym się liczniku. Odejmowanie dwóch punktów daje czas trwania także
przy przejściu licznika przez maksimum typu bez znaku.
\noindent\begin{tabularx}{\textwidth}{@{}p{4.4cm}X@{}}
\toprule
API & Znaczenie \\
\midrule
\texttt{vTaskDelay(3)} & blokada względna: trzy ticki od chwili wywołania \\
\texttt{xTaskDelayUntil} (\texttt{\&next,3}) & kolejny termin względem zapamiętanej osi okresu \\
\bottomrule
\end{tabularx}
W laboratorium tick rate wynosi 1000 Hz, ale poprawne zdanie brzmi
„A było zablokowane przez \blank{1.5cm} ticki”. Przeliczenie na ms:
\blank{3cm}. Co zmieni się przy 250 Hz? \blank{5cm}
\newpage
\section{Tabela predykcji i obserwacji}
Najpierw wypełnij kolumnę „predykcja”. Dopiero potem uruchom program i wpisz
wartości z \texttt{g\_snapshots}. Priorytet zapisuj obok stanu, np.
\texttt{READY/p2}.
\renewcommand{\arraystretch}{1.32}
\noindent\begin{tabularx}{\textwidth}{@{}p{.7cm}p{2.3cm}p{3.2cm}p{3.2cm}p{1.8cm}X@{}}
\toprule
Nr & Zdarzenie & A: pred./odczyt & B: pred./odczyt & Current & Dlaczego? \\
\midrule
1 & startup & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
2 & przed delay & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
3 & A czeka & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
4 & A obudzone & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
5 & BEFORE & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
6 & HIGH & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
7 & AFTER & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
8 & verifier & \blank{2.7cm} & \blank{2.7cm} & \blank{1.3cm} & \blank{2.05cm} \\
\bottomrule
\end{tabularx}
\renewcommand{\arraystretch}{1}
\section*{Trzy znaczniki jako dowód wywłaszczenia}
Kod A zapisuje \texttt{BEFORE=1}, podnosi B do priorytetu 3, a po powrocie z
API zapisuje \texttt{AFTER=3}. Kod B zapisuje \texttt{HIGH=2} natychmiast po
uzyskaniu CPU.
\begin{lstlisting}
append_priority_order(BEFORE); // A: 1
peer.set_priority(3); // B staje sie wyzej priorytetowe
append_priority_order(AFTER); // A: 3, dopiero po powrocie
// B, zanim wywolanie w A zdazy wrocic:
append_priority_order(HIGH); // B: 2
\end{lstlisting}
Gdyby nie doszło do natychmiastowego wywłaszczenia, możliwa kolejność
wynosiłaby \blank{4cm}. Odczyt oczekiwany: \blank{4cm}.
\section*{Osiem rekordów, ale żadnego użycia wiszącego uchwytu}
Po usunięciu zadania jego TCB może zostać odzyskany przez idle task.
\texttt{TaskRef} nie posiada TCB i nie wydłuża jego życia. Dlatego terminalny
rekord zapisuje znany stan \texttt{DELETED}, ale nie wywołuje
\texttt{eTaskGetState()} przez stary uchwyt.
\newpage
\section{Uruchomienie i kontrakt dowodu}
\begin{lstlisting}[language=bash]
make check
riscv64-unknown-elf-gdb build/task01_scheduler_states/prog.elf
\end{lstlisting}
\begin{lstlisting}
p g_alternating_tasks
p g_alternating_ticks
p g_snapshots
p g_delay_start_tick
p g_delay_observed_tick
p g_delay_end_tick
p g_delay_elapsed
p g_priority_order
p g_scheduler_states_pass
\end{lstlisting}
\noindent\begin{tabularx}{\textwidth}{@{}p{5.2cm}X@{}}
\toprule
Warunek & Odczyt ucznia \\
\midrule
identyfikatory mają postać X,Y,X, $X\ne Y$ & \blank{6cm} \\
w zdarzeniu 3: A=BLOCKED, B=RUNNING & \blank{6cm} \\
\texttt{delay\_end - delay\_start == 3} & \blank{6cm} \\
obserwacja blokady jest przed końcem delay & \blank{6cm} \\
w zdarzeniu 6 B ma priorytet 3 & \blank{6cm} \\
\texttt{priority\_order == \{1,2,3\}} & \blank{6cm} \\
osiem snapshotów i \texttt{pass == 1} & \blank{6cm} \\
\bottomrule
\end{tabularx}
\section*{Minimalne wrappery C++}
\begin{lstlisting}
class TaskRef final {
public:
explicit TaskRef(TaskHandle_t h) : handle_{h} {}
eTaskState state() const { return eTaskGetState(handle_); }
UBaseType_t priority() const { return uxTaskPriorityGet(handle_); }
void set_priority(UBaseType_t p) const {
vTaskPrioritySet(handle_, p);
}
private:
TaskHandle_t handle_; // non-owning
};
\end{lstlisting}
Nie ma tu wirtualności, alokacji ani automatycznego delete. Rozmiar
\texttt{TaskRef} jest równy rozmiarowi uchwytu. Pełna polityka własności taska
pojawi się dopiero w K07--K09.
\section*{Wyjście — cztery krótkie odpowiedzi}
\begin{enumerate}
\item Dlaczego zadanie o priorytecie 4 może nie działać, gdy działa p2?\\[1em]
\item Dlaczego test nie wymaga, by A było pierwsze w śladzie time slicing?\\[1em]
\item Kiedy \texttt{vTaskDelay(3)} oznacza dokładnie 3 ms?\\[1em]
\item Co dokładnie dowodzi kolejność \texttt{1,2,3}?\\[1em]
\end{enumerate}
\section*{Zaliczenie}
\begin{itemize}
\item $\square$ rozróżniam READY, RUNNING, BLOCKED i DELETED;
\item $\square$ pokazuję X--Y--X, blokadę na 3 ticki i porządek 1--2--3;
\item $\square$ odróżniam delay względny od okresowego terminu;
\item $\square$ nie utożsamiam ticka z milisekundą bez konfiguracji;
\item $\square$ wiem, że \texttt{TaskRef} nie jest właścicielem TCB.
\end{itemize}
\vfill
\noindent\textbf{Następna karta K05:} most C++ do heapu, porównanie modeli
FreeRTOS oraz tylko-odczytowy \texttt{HeapStats}.
\end{document}