Arduino向マイクロカーネル

生成AIに実装させたArduino UNO R4向けプリエンプティブ・マイクロカーネル

概要

マイクロカーネルは以前から作ってみたかったものの、本職はハード技術者でカーネル周りは敷居が高く諦めていました。生成AIの力を借りて、Arduino UNO R4 Minima(ルネサスRA4M1・Arm Cortex-M4、FlashROM 256kB/RAM 32kB、48MHz)向けにプリエンプティブなマイクロカーネルを実装してみた記録です。

設計モデル

参考文献(Switzer, Robert『オペレーティングシステム:設計と実装』, 1994)のブロック図を土台に、FM(ファイルマネージャ)/MM(メモリマネージャ)/PM(プロセスマネージャ)/IPCM(プロセス間通信マネージャ)/DRIVER/Userという構成を検討しました。

ブロック図(設計モデル)

生成AIに与えた要求仕様は次の通りです。

  • メモリ管理はメモリマネージャで行う
  • ファイルシステムはファイルマネージャで行う(簡単でよいのでRAM上)
  • プロセス管理はプロセスマネージャとして行う
  • IPCもプロセス間通信マネージャで行う
  • ドライバを別タスク化
  • マイクロカーネルなのでメッセージパッシング方式とする
  • 簡単なシェルが欲しい
  • マルチタスクはプリエンプティブとする

AIごとのアプローチの違い

Grok(Grok 4)、Gemini(3 pro)、ChatGPT(GPT-5.2)の3種類に同じプロンプトを与えて比較しました。

  • Grok:実コードを出すが動かないことが多く、その割に自信満々
  • Gemini:実コードを出し、そこそこ動く。多少バグあり
  • ChatGPT:教育的すぎて丁寧に実装しようとし、なかなかコードが出てこない

今回は一番まともなコードを迅速に生成したGeminiを採用。最初はノンプリエンプティブな協調的マルチタスクで提示されましたが、「コンテキストスイッチ部分をアセンブリ言語で実装したプリエンプティブマルチタスクにしたい」と指示したところ、インラインアセンブラでコンテキストスイッチを吐いてくれました。Arduino IDEは基本1ファイルなので、インラインアセンブラで完結してくれるのは開発上ありがたいポイントです。

実装詳細

ブロック図(実装結果)
  • IPCMとPMは独立タスク化を狙いましたがこの規模では断念。カーネル自身がIPCマネージャとプロセスマネージャの役割を兼務しています(AI曰く「最も高速な実装」であり、スケジューラ自体がタスク化されてバグで停止するとOS全体がフリーズするため、最重要機能は特権モード内に置く設計とのこと)
  • サーバ:仮想ファイルシステム(RAMディスクの実体)、仮想メモリ管理(骨格のみで中身は未実装)
  • ドライバ:シリアル通信ドライバのみ(低レベル制御はArduinoライブラリを使用)
  • アプリケーション:ユーザーインターフェースとしてのシェル

システムコール

  • ipc_send() / ipc_receive():メッセージ送受信(マイクロカーネルの要)
  • sys_yield():自分の持ち時間を返上して他のタスクにCPUを譲る

シェル

コマンドは ls / touch <name> / write <name> / ps / blink(on|off) / sleep <ms>

コンソール画面(psコマンドでタスク状態を表示)

発展:sleepシステムコールとLチカ

実用性を持たせるため「Lチカドライバ」を実装。これにはsleepが必要になりますが、ブロッキングしないプリエンプティブなsys_sleep()は意外に手こずり、シリアル入力が効かなくなったりLEDが点灯しっぱなしになったりと迷走しました。そこでCopilotに「あたかも自分で作ったソースであるかのように」デバッグさせたところ、思いのほかうまく直してくれることが判明。ゼロから実装させると教育的になりすぎるAIも、デバッグ要員としては優秀という発見がありました。

Lチカの周期をオシロスコープで実測したところ、リアルタイムカーネルではないためジャスト1秒ではなく930msでした。

Lチカ周期の測定(930ms)

その後ファイル書き込み機能も追加し、最終的なサイズはFlash約52kB(約20%使用)、RAM使用率56%。ちなみにRAMディスクはわずか160バイトで「全く実用性が無い」とのこと。

おわりに

生成AIを使えば単純なマイクロカーネルはお手軽に実装できてしまいます。特にコンテキストスイッチまわりはCortex-M特有の配慮がされたコードが出てきており、ゼロから安全なタスク切り替えを実装するにはそれなりのノウハウが要ることを考えると驚異的でした。一方で、少しでも実用性を持たせようとすると途端に大変になることも実感(sleepのように時間制御が絡む要求は、最初からプロンプトに明示しておく必要がありそうです)。

今後はIPCMとPMの完全独立化、RAMディスクに代わるSDカード対応、そして他プラットフォーム(Super AKI80)への移植を予定しています。

ソースはGitHubで公開しています:kaya-z/Arduino_microkernel

参考文献:Switzer, Robert (1994)『オペレーティングシステム:設計と実装』