# Checking every chapter on your own board The sample code ships with a script that **builds every chapter, uploads it to the board and automatically compares the serial output with what the book says**. It checks in one go that your board gives the same results as the book. The same commands work on Linux, macOS and Windows. ## Usage ```bash # already in docs/os-on-arduino/code if you followed the chapters page uv sync # first time only uv run python scripts/verify_chapters.py --list # chapters and their expectations uv run python scripts/verify_chapters.py --build-only # build only, no board needed uv run python scripts/verify_chapters.py # every chapter on the board ``` The serial port is found automatically from the Arduino USB vendor ID. If other USB serial devices are connected, pass it with `--port` (`COM3` / `/dev/ttyACM0` / `/dev/cu.usbmodem...`). Example output (the script prints its messages in Japanese): ```text OS: Darwin 25.5.0 Python: 3.14.2 ボード: /dev/cu.usbmodemXXXXXXXXXXXXX === 01_boot ===================================================== -> PASS (13.4s) OK === Boot Sequence Check === OK BSS がゼロクリアされている OK DATA が Flash からコピーされている OK ベクタテーブルが RAM 上にある OK If you see this, boot sequence completed! ``` What it checks is not the output text itself but **the properties the book claims**. For chapter 1, for example, it confirms from the printed values that BSS (the area for global variables with no initial value) was zeroed and DATA (the area for global variables with an initial value) was copied from Flash; chapter 1 explains both. Values that depend on the environment, such as addresses and times, are matched with regular expressions that allow for the variation. Three checks cannot be written as regular expressions: | Check | What it verifies | Where in the book | |---|---|---| | `cpu_sum` | The CPU% column of `ps` (a command of the shell built in chapter 5) does not add up to more than 100% | Chapter 4, 4.7 ("the total is close to 100%") | | `preemption` | The 1-second task keeps its period while a heavy computation runs | The point of chapter 4 itself | | `philosophers` | All five philosophers keep eating (the dining philosophers problem is covered in Advanced 1) | Deadlock avoidance in Advanced 1 | ## Stepping through the chapters while watching the LEDs `-i` switches to interactive mode. It uploads one chapter at a time and **moves on when you press Enter, so you can watch the LEDs on the board**. The automatic checks cannot see the LEDs or the matrix, so use this mode for visual checks. ```bash uv run python scripts/verify_chapters.py -i ``` | Input | Action | |---|---| | Enter alone | Next chapter | | Any text | Sent to the board as is (`ps`, `kill 1`, ...; commands of the shell built in chapter 5) | | `!` | Sends the chapter's "things to try" in order | | `r` / `b` / `q` | Re-upload / previous chapter / quit | Each chapter shows what to look for (in Japanese): ```text ======================================================================== [7/20] 07_led_matrix 本編 第7章 LEDマトリクス可視化 ======================================================================== 目で見るポイント: ・マトリクス上半分に CPU 負荷グラフ(左が古い、右が新しい) ・マトリクス下半分にタスクごとの実行状況 ・kill 3 で Heavy を止めると、負荷グラフが目に見えて下がる 試せること: ps / kill 3 / ps / exec 3 ``` ## Throwing bad input at the shell `scripts/fuzz_shell.py` sends badly behaved input (lines that are too long, task IDs that do not exist, control characters, unclosed brackets and so on) to the shells and REPLs and checks that **the OS survives**. The shell is what you type commands into over serial, built in chapter 5; a REPL is an interactive environment that reads your input, runs it and prints the result, over and over, such as chapter 11's TinyPython. The script checks the board is still alive after every input, so you can tell which input made it hang. ```bash uv run python scripts/fuzz_shell.py ``` ## Tested environments | | | |---|---| | macOS (Apple Silicon) | All 20 projects PASS | | Windows 11 (ARM64) | All 20 projects PASS | | Ubuntu | Build checked in CI | The output of chapter 1 and of chapter 13's `iktest` (a command that checks the quadruped's leg-angle calculation with a round trip) was byte-for-byte identical on macOS and Windows.