AVRでOS

AVRで動くOSを作ってみようと思う。


組み込みOSというものには昔から興味を抱きつつも、ついぞ手を出すことがなかった。それは結局のところ、今までマイコンでOSを使う必要性に迫られなかったからだと思う。シングルタスク的なmain関数と割り込みだけの簡単なシステムなら、あまりOSを使うメリットが感じられない。


マルチタスク的な処理だってOS無しで書くことは不可能ではない。各々のタスクの関数をステートマシン形式で記述して、main関数で順番に呼んでやればよいのだ。タスクの待ちは、条件が成立するまで素通りするステートを設けてやれば実現できる。


しかし複雑なシステムになってくると、この方法でマルチタスクを実現するとタスクが巨大なswitch文のお化けと化してしまう。ソースが肥大化し、見通しが悪く、書くのが面倒くさく、保守性が悪くなる。そういう経験をしてはじめて思ったのだ。「OSが欲しい!」と。探してみるとAVRマイコンで動くフリーのOSというはけっこうたくさんあるんだけど、ここは自作してみようと思う。他人が書いたソースと英語を読むのだって一仕事だし、それなら自作したほうが理解が深まってよいだろう。


というわけで、OSを作ってみよう。さしあたり必要に思う基本機能だけにしぼり、AVRマイコンでも動くような小さなOSを。カーネルのROMサイズはできれば1キロバイト以下にしたい。(ROMが8キロバイト以上のマイコンでの使用を想定。)


ちょっと検討してみて、まず思ったのはコンテキストスイッチの問題。タスクの数だけスタック領域を確保して、レジスタを待避しないといけないわけだけど、AVRって汎用レジスタが32本もあるんだよねぇ。プリエンプティブなOSだと全レジスタをPUSH/POPしないといけない。PUSH/POP命令はそれぞれ2クロックなので、例えば8MHzクロックだと全レジスタのPUSH/POPには16usもかかってしまう。オーバーヘッドでかすぎだ。ノンプリエンプティブなOSにして、タスクの自主的なシステムコールでのみコンテキストスイッチが起こるとすれば、r2〜r17,r28,r29の18本のみ保存すればよいことになるだろうけど、それでも9usかかる。致し方ないところか?