# 第10章: FreeRTOSで同じことをやってみる 自作 OS と同じ課題を FreeRTOS で書き、設計の違いを比べます。 ## サンプルコード - ディレクトリ: `docs/os-on-arduino/code/10_freertos` - ビルドと書き込み: ```bash uv run pio run -d 10_freertos -t upload uv run pio device monitor -b 115200 ``` 本物の FreeRTOS の例は `10_freertos_real` にあり、例ごとに環境(`-e` で選ぶビルド設定)が 分かれています。`integrated` を `basic`・`preemptive`・`task_control`・`semaphore`・ `queue` に替えると、ほかの例になります。 ```bash uv run pio run -d 10_freertos_real -e integrated -t upload ``` コードを見る: [docs/os-on-arduino/code/10_freertos](https://github.com/iory/learning-os-from-arduino/tree/main/docs/os-on-arduino/code/10_freertos) ## ソースコード この章のスケッチです。ファイル名をクリックすると開きます。コードは原稿リポジトリから自動で同期されているので、ここに出ているものが常に最新です。 ### `docs/os-on-arduino/code/10_freertos` :::{dropdown} `src/main.cpp` — 229 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos/src/main.cpp) ```{literalinclude} ../../../../code/10_freertos/src/main.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `include/servo_pwm.h` — 61 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos/include/servo_pwm.h) ```{literalinclude} ../../../../code/10_freertos/include/servo_pwm.h :language: cpp :linenos: ``` ::: ### `docs/os-on-arduino/code/10_freertos_real` :::{dropdown} `src/basic.cpp` — 35 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos_real/src/basic.cpp) ```{literalinclude} ../../../../code/10_freertos_real/src/basic.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/integrated.cpp` — 103 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos_real/src/integrated.cpp) ```{literalinclude} ../../../../code/10_freertos_real/src/integrated.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/preemptive.cpp` — 48 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos_real/src/preemptive.cpp) ```{literalinclude} ../../../../code/10_freertos_real/src/preemptive.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/queue.cpp` — 54 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos_real/src/queue.cpp) ```{literalinclude} ../../../../code/10_freertos_real/src/queue.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/semaphore.cpp` — 44 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos_real/src/semaphore.cpp) ```{literalinclude} ../../../../code/10_freertos_real/src/semaphore.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/task_control.cpp` — 62 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/10_freertos_real/src/task_control.cpp) ```{literalinclude} ../../../../code/10_freertos_real/src/task_control.cpp :language: cpp :linenos: ``` ::: ## 実機での出力 Arduino UNO R4 WiFi の実機で実際に取得した出力です(macOS / Windows の 両方で同じ結果を確認しています)。手元の出力と見比べてください。 ```text [FreeRTOS Task] Count: 2 [FreeRTOS Task] Count: 3 [FreeRTOS Task] Count: 4 [FreeRTOS Task] Count: 5 [FreeRTOS Task] Count: 6 [FreeRTOS Task] Count: 7 [FreeRTOS Task] Count: 8 [FreeRTOS Task] Count: 9 [FreeRTOS Task] Count: 10 [FreeRTOS Task] Count: 11 ... ``` ```{figure} ../_static/ch10_freertos.gif :name: fig-ch10-freertos :width: 100% `10_freertos` を書き込んでモニタを開いたところ。FreeRTOS 風の API(`xTaskCreate` など)で作ったタスクを `loop()` の中の簡易スケジューラが回していて、`[FreeRTOS Task]` のタスクが 1 秒ごとに `Count` を増やしていきます ``` ### 本物の FreeRTOS(`integrated` 例) ```text === FreeRTOS Status === Tick: 4014 Free heap: 3640 Pot value: 205 === FreeRTOS Status === Tick: 6020 Free heap: 3640 Pot value: 204 ... ``` ```{figure} ../_static/ch10_freertos_real.gif :name: fig-ch10-freertos-real :width: 100% `uv run pio run -d 10_freertos_real -e integrated -t upload`(`-e` は platformio.ini の中の環境(ビルド設定)の名前)で書き込んでモニタを開いたところ。 本物の FreeRTOS の上で、2 秒ごとに `Tick`(FreeRTOS のティック数)・`Free heap`・ A0 の読み値を出します。A0 に何もつないでいないと `Pot value` は 200 前後の定まらない 値になります(可変抵抗をつなぐと、回した位置に応じて 0〜1023 で変わります) ``` ## つまずきやすいポイント (読者からの質問に応じて随時追記します。質問は [GitHub Issues](https://github.com/iory/build-your-own-arduino-rtos/issues) へどうぞ)