タスクシステム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の操作は行いません。
メイン関数に、どば〜っと処理を書かないための仕組みが「タスクシステム」なのです。
 
「じゃあ、どう書くの?」
 
という感じなのですが、それは後で説明します。

タスクリスト

続いて、タスクリストです。
 
タスクの領域は、プログラム起動時に全て確保します。
実行途中で確保したりはしません。
 
で、その確保した領域を、「フリータスクリスト」と呼びます。
フリーという名前のように、その中身は空っぽです。
 
そして、タスクを生成するときには、この領域から実行領域に移します。
この実行領域を「アクティブタスクリスト」と呼びます。
 
まあ、、ただ双方向リストのつなぎ目を移すだけなので、
領域を移すというのは、正確には違うかもしれませんが…(´Д`;
 
最後に、使わなくなったタスクは「アクティブタスクリスト」から切り離し、
「フリータスクリスト」につなぎなおします。
 
このように、

  • 領域を使いまわす

のがタスクリストです。
(つづく)