\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}{13} \newcommand{\CardCount}{16} \newcommand{\CardSlug}{event-group} \newcommand{\CardVersion}{v00.01} \newcommand{\DocumentUUID}{5fbcd7c6-3a73-4cd2-b76c-bdb016d1daaa} \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{K13 · FreeRTOS C++ · EventGroup}}\rhead{\small L12 · typed coordinated state} \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 Typed \texttt{EventBits} i koordynacja stanu}\par \vspace{.25em}{\large wait any/all, keep/clear-on-exit i timeout snapshot}\par \end{center} \noindent\begin{tabularx}{\textwidth}{@{}p{1.65cm}Xp{1.75cm}X@{}} \toprule Karta & K13 / \CardCount & Czas & 30 minut \\ Platforma & Hazard3 / RV32I & Bity & UART/GPIO/APP \\ Maska all & \texttt{0x7} & Storage & static, heap delta 0 \\ Wersja & \CardVersion & UUID karty & \texttt{5fbcd7c6-...} \\ \bottomrule \end{tabularx} \section*{Typowana maska} \begin{lstlisting} enum class ReadyBit : EventBits_t { uart = 1u << 0, gpio = 1u << 1, app = 1u << 2 }; auto all = Mask{ReadyBit::uart} | Mask{ReadyBit::gpio} | Mask{ReadyBit::app}; \end{lstlisting} \noindent\fcolorbox{accent}{accentlight}{\begin{minipage}{.94\textwidth} \textbf{Kontrakt K13.} Bit opisuje stan true/false. Ponowne set nie zwiększa licznika. Wynik wait jest snapshotem; trzeba oddzielnie sprawdzić, czy spełnia politykę any/all. Clear-on-exit jest jawną decyzją współdzieloną z waiterami. \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 & masks & enum 1,2,4; all=7 \\ 5--10 & publish & coordinator Blocked; trzy taski set \\ 10--15 & all/keep & snapshot i current = 7 \\ 15--20 & clear & tylko GPIO: 7--5 \\ 20--25 & timeout & all false po 3 tickach, snapshot 5 \\ 25--30 & any/clear & UART|APP true; snapshot 5, final 0 \\ \bottomrule \end{tabularx} \section*{Predykcja} \texttt{UART|GPIO|APP} = \blank{2cm}. Czy dwukrotne set UART da maskę 2? \blank{2cm}. Dlaczego? \blank{7cm} \newpage \section{Trzech publisherów, jeden wait all} \begin{center} \texttt{coordinator wait ALL(0x7), keep -- Blocked}\\ $\downarrow$ \texttt{UART set 0x1}\\ $\downarrow$ \texttt{GPIO set 0x2}\\ $\downarrow$ \texttt{APP set 0x4 -- mask 0x7 -- coordinator Ready} \end{center} \noindent\begin{tabularx}{\textwidth}{@{}p{4.5cm}p{3.3cm}X@{}} \toprule Pomiar & Predykcja & Odczyt \\ \midrule coordinator przy first set & Blocked & \blank{2.5cm} \\ UART first set result & \texttt{0x1} & \blank{2.5cm} \\ UART repeated set & \texttt{0x1} & \blank{2.5cm} \\ wait all snapshot & \texttt{0x7} & \blank{2.5cm} \\ all satisfied & true & \blank{2.5cm} \\ current po keep & \texttt{0x7} & \blank{2.5cm} \\ \bottomrule \end{tabularx} \section*{Dlaczego repeated set nie liczy zdarzeń?} Set wykonuje logiczne OR. Jeśli UART musi policzyć pięć ramek, EventGroup nie przechowa tej liczby. Potrzebny jest counter, queue albo notification count. Podaj przykład poprawnego stanu bitowego i błędnego licznika bitowego:\\[.5em] \blank{16cm}\\[1em]\blank{16cm} \section{Jawne clear jednego bitu} \begin{lstlisting} auto before = group.clear(Mask{ReadyBit::gpio}); // returns 0x7 auto after = group.bits(); // now 0x5 \end{lstlisting} Clear return: \blank{2.5cm}. Maska po clear: \blank{2.5cm}. Które subsystemy pozostają ready? \blank{5cm}. \newpage \section{Timeout jest snapshotem, nie osobnym błędem} Po usunięciu GPIO maska \texttt{0x5} nie spełnia ALL(\texttt{0x7}). \noindent\begin{tabularx}{\textwidth}{@{}p{5cm}p{3.3cm}X@{}} \toprule Pomiar & Predykcja & Odczyt \\ \midrule timeout & 3 ticki & \blank{2.5cm} \\ returned snapshot & \texttt{0x5} & \blank{2.5cm} \\ ALL satisfied & false & \blank{2.5cm} \\ current po keep & \texttt{0x5} & \blank{2.5cm} \\ \bottomrule \end{tabularx} Nie testuj timeoutu przez \texttt{result==0}: częściowa maska może być niezerowa. Poprawny test porównuje \texttt{result \& wanted} według any/all. \section{Any i clear-on-exit} \begin{lstlisting} auto wanted = Mask{ReadyBit::uart} | Mask{ReadyBit::app}; auto result = group.wait(wanted, WaitMode::any, ClearMode::clear_on_exit, 0); \end{lstlisting} \noindent\begin{tabularx}{\textwidth}{@{}p{5cm}p{3.3cm}X@{}} \toprule Pomiar & Predykcja & Odczyt \\ \midrule snapshot before clear & \texttt{0x5} & \blank{2.5cm} \\ ANY satisfied & true & \blank{2.5cm} \\ bits cleared & UART i APP & \blank{2.5cm} \\ final current mask & \texttt{0x0} & \blank{2.5cm} \\ \bottomrule \end{tabularx} \section*{Race do omówienia} Dwóch waiterów czeka na ten sam bit z clear-on-exit. Który zobaczy stan i czy drugi ma gwarancję sukcesu?\\[.5em]\blank{16cm}\\[1em]\blank{16cm} \section*{ISR boundary} \texttt{xEventGroupSetBitsFromISR} nie edytuje grupy bezpośrednio: odkłada operację do timer service task. To wymaga działającego daemon taska i jawnej analizy opóźnienia; K13 mierzy wyłącznie task-context API. \newpage \section{Hazard3/GDB i zaliczenie} \begin{lstlisting}[language=bash] make check riscv64-unknown-elf-gdb build/task01_event_group/prog.elf b event_group_debug_checkpoint \end{lstlisting} \begin{lstlisting} p g_coordinator_state_seen p g_worker_set_result p/x g_uart_repeat_mask p/x g_all_snapshot p/x g_mask_after_gpio_clear p/x g_timeout_snapshot p g_timeout_satisfied p g_timeout_ticks p/x g_any_snapshot p/x g_final_mask p g_event_group_pass \end{lstlisting} \section*{Zaliczenie} \begin{itemize} \item $\square$ buduję typed maskę UART/GPIO/APP = 0x7; \item $\square$ pokazuję Blocked, wait all/keep i snapshot 0x7; \item $\square$ repeated UART set zostaje 0x1, więc nie jest counterem; \item $\square$ clear GPIO zmienia 0x7 na 0x5; \item $\square$ timeout 3 zwraca snapshot 0x5 i unsatisfied; \item $\square$ any/clear zwraca 0x5 i pozostawia final 0x0. \end{itemize} \section*{Wyjście} Dlaczego \texttt{result!=0} nie dowodzi spełnienia wait all?\\[.5em] \blank{16cm}\\[1em] Kiedy clear-on-exit może zgubić informację drugiemu waiterowi?\\[.5em] \blank{16cm} \vfill \noindent\textbf{Następna karta K14:} software timer, daemon task, one-shot, auto-reload, callback context oraz bezpieczna granica lifetime. \end{document}