Nitro-OSを作った!
前回はシスコンの原理基板の動作確認まで終わりました。
なので、次はシスコン用の軽量OSをせっかくなので1から作ろうと思います。
まずは名前は……ニトリは値段以上にお得ってことで、ニトリの通称の一つニトロからあやかって、「Nitro-OS」にします。
いくらAVRの上位機種のチップとはいえ、ROM 64kB、RAM4kBしかないので、大掛かりなOSは載せられません。
でも、楽にプログラムできて、OS部分は他の電子工作にも使いまわせたらいいな、というのを考えて、以下のようなコンセプトにしました。
-
非プリエンプティブなマルチタスク。各タスクが自分からOSに「仕事がなくなりました」と自己申告すると、タスクが切り替わる方式。最近のWindowsみたいにタイマーで自動に切り替えはしない。タスク切り替えのコストもばかにならないし、プログラムも作りやすいし。
-
積極的に省エネモードを利用。仕事をしているタスクがなくなり次第、省エネモードに入る。消費電力を極限まで抑えることで、シスコンボードに載せたパスコンに蓄えられた電力だけでも動作することを狙っていく。こうすれば、シスコンブロックが他のブロックに電源汚染や輻射汚染するのをなくせるので、音質などに悪影響を及ぼさない。ついでに、将来、バッテリとかで使うこともあるかもしれないし。
-
上記の省エネモードを実現するため、(1秒間休みます!みたいな)時間待機、RS232C、I2Cなどは割り込みで駆動する。割り込みが来るまで、そのタスクは休む。タイムアウトあり。
-
各ハードウェアリソースの調停を行うため、セマフォを実装。セマフォを獲得できなかったタスクは、獲得できるまでやっぱり休む。
-
不可解なバグを簡単に検出できるように各タスクが使用するスタックをチェック。現在使用している量、今までで使った最大量、スタック領域を超えたアクセスの3種類をタスク切り替え時にチェック。
-
全てのタスクが終了したら、タスクスケジューラを起動した場所へ戻ってくること。
とまぁ、長々と書いたものの、要は「省エネモードの積極的利用」「スタックチェック」「全タスク終了時に元のプログラム位置に戻る」以外はそこらへんに転がってるような簡単な組み込みOSと同じです。
車輪の再開発です。
この程度のOSなら、フリーのOSをゲットして説明書を読んで理解するよりも、自作して自分の用途にあった特化したものを作ったほうが早いってことで。
ま、一号機だし、OSから特化って響きがかっこいいよね!
ガンダムだね!(SEED的な意味の
で、あまりに単純なので夏コミ作業の息抜きでさくっとできちゃったので、このOSを利用するとこんな感じでマルチタスクなコントローラプログラムが記述できますというサンプルでも。
#include "nitro.h"
TaskData taskA;
uint8_t stackA[256];
void taskEntryA(void)
{
for (int i = 0; i < 10; i++) {
uartTxLockSendLine("taskA");
taskYield();
}
}
TaskData taskB;
uint8_t stackB[256];
void taskEntryB(void)
{
for (int i = 0; i < 10; i++) {
uartTxLockSendLine("taskB");
taskSleep(250); // 1秒待機
taskSleep(250);
taskSleep(250);
taskSleep(250);
}
}
TaskData taskC;
uint8_t stackC[256];
void taskEntryC(void)
{
for (int i = 0; i < 10; i++) {
uartTxLockSendLine("taskC");
taskSleep(250); // 1.5秒待機
taskSleep(250);
taskSleep(250);
taskSleep(250);
taskSleep(250);
taskSleep(250);
}
}
int main(void)
{
nitroInitModule();
sei();
uartTxRawSendLine("create tasks");
taskCreate(&taskA, taskEntryA, stackA, sizeof(stackA));
taskCreate(&taskB, taskEntryB, stackB, sizeof(stackB));
taskCreate(&taskC, taskEntryC, stackC, sizeof(stackC));
uartTxRawSendLine("excute tasks");
taskExecute(&taskA);
taskExecute(&taskB);
taskExecute(&taskC);
uartTxRawSendLine("run scheduler");
taskRunScheduler();
return 0;
}
ま、なんとなく見れば簡単さがわかると思うけど、taskA、taskB、taskCの3つがマルチタスクで強調動作します。
その強調動作の結果が、トップに張ってあるスクショです。
RS232CでパソコンのTeraTermと通信してる結果です。
これから、このOS上にヘッドフォンアンプNTR000用のコントローラプログラムを実装していきたいと思います。
さて、夏コミ作品にバグがないか、テストプレイの続きをやるかー。
トラックバックURL:http://www.cubetype.com/cgi/mt/mt-tb.cgi/117
コメントをいただけるとスタッフが喜びます。同人ゲームのサポートはメールフォームからお願いします。