タスクシステム2
ダミータスク
タスクは双方向リストとなるわけですが、
先頭と末尾のタスクに「NULL」をいちいち設定するのは大変です。
ということで、先頭と末尾のタスクは、
ダミーとして空のタスクを用意しておきます。
これにより、タスクの追加・削除の処理が楽になります。
ワークエリアの使い方
ワークエリアは、キャストして使用します。
ただし、サイズオーバーしたワークエリアを設定すると、
深刻なバグが発生します。
そのため、assert関数でサイズを必ずチェックします。
サンプルは以下のようになります。
#include <iostream> //#define NDEBUG // こいつでassertは消える #include <assert.h> using namespace std; // TCB #define WORK_AREA_SIZE 256 struct TCB { char work[WORK_AREA_SIZE]; void (*EXEC)(TCB *tcb); }; // ワシのワークエリアや struct MY_WORK { char work[512]; }; void main() { TCB tcb; // ワークエリアを使う MY_WORK *work = (MY_WORK*)tcb.work; // その前にチェック assert(sizeof(MY_WORK) <= WORK_AREA_SIZE); cout << "check end" << endl; }
こうすると、assertマクロがチェックエラー時に、
abortしてくれるのでとても便利です。
あと念のためですが、普通はメイン関数で、タスクの生成などのTCBの操作は行いません。
メイン関数に、どば〜っと処理を書かないための仕組みが「タスクシステム」なのです。
「じゃあ、どう書くの?」
という感じなのですが、それは後で説明します。
タスクリスト
続いて、タスクリストです。
タスクの領域は、プログラム起動時に全て確保します。
実行途中で確保したりはしません。
で、その確保した領域を、「フリータスクリスト」と呼びます。
フリーという名前のように、その中身は空っぽです。
そして、タスクを生成するときには、この領域から実行領域に移します。
この実行領域を「アクティブタスクリスト」と呼びます。
まあ、、ただ双方向リストのつなぎ目を移すだけなので、
領域を移すというのは、正確には違うかもしれませんが…(´Д`;
最後に、使わなくなったタスクは「アクティブタスクリスト」から切り離し、
「フリータスクリスト」につなぎなおします。
このように、
- 領域を使いまわす
のがタスクリストです。
(つづく)