SSブログ

Smalight OSを使おう 3タスク目 タスクの生成 [Smalight OS]

この記事は、某SNSで書いているものを転載しています。

どうにもこうにも優先度の設定方法を、マニュアルの中にその具体的な記述を見つける事が出来なかったので、一部こちらの想像で語っています。あまり信用しないように。
※完全版のマニュアルは、製品版なり、評価版なりのsmalight osを入手しないと手に入れられないかもしれない。
以下のリンク先からゲストユーザーで入って、サンプル版のマニュアルを取得して下さい。
http://www.kitasemi.renesas.com/outside/cgi-bin/esdd/smadl.cgi?user=guest

「図2-3 タスクのスケジューリング」はsmalight osのスケジューリングの解説していますが、これを見る限り優先度タスクはそれぞれの優先度に1つ。優先度タスクの下に同一優先度のローテーションタスクがキューに繋がれて存在している形となっています。

μITRONの場合は、各優先度毎にREADY(実行待ちのタスク)キューが存在し、その中でローテーションが行われます。つまり一つの優先度に複数のタスクが存在しても構わないのです。それと比較して優先度別には1つのタスクしか存在し得ないsmalight osは、随分割り切った設計と言える部分です。

この事を踏まえてsmalight osのタスク優先度の設定なのですが、μITRONの場合は、ユーザーが任意のタスクの優先度を、例えばコンフィギュレーションファイルの中で設定しますが、どうもはっきりとは言えないのですが、このsmalight osはタスク生成情報の記述の仕方で優先度やタスクIDが決まってしまう様な感じです。

例えばtsk01、tsk02、tsk03をそれぞれ優先度1、2、3とするなら、config.cの中のタスク生成情報の記述順序もこの順番で記述します。
また3つのタスクをプライオリティタスクとして登録するには、やはりconfig.cのKNL_TCB_PRI_NUM定義を3以上、KNL_TCB_NUM以下に設定します。
タスクがこの3つしか存在しないなら、例として

/*------ TCB Number ------------------------------------------*/
#define KNL_TCB_NUM 3
#ifdef KNL_BB_PRIORITY
#define KNL_TCB_PRI_NUM 3
#endif

/*------ TCB Stack Size --------------------------------------*/
#define TCB1_SIZE 0x80u
#define TCB2_SIZE 0x80u
#define TCB3_SIZE 0x80u


H tcb_stack1[(TCB1_SIZE/sizeof(H))];
H tcb_stack2[(TCB2_SIZE/sizeof(H))];
H tcb_stack3[(TCB3_SIZE/sizeof(H))];
/*------ TCB Stack addr --------------------------------------*/
const TCBSP knl_tcbSpInit[KNL_TCB_NUM] = {
  { (H *)&tcb_stack1[TCB1_SIZE/sizeof(H)] }, /* TCB1 */
  { (H *)&tcb_stack2[TCB2_SIZE/sizeof(H)] }, /* TCB2 */
  { (H *)&tcb_stack3[TCB3_SIZE/sizeof(H)] }, /* TCB3 */
};

/*------ TCB Start addr Init ---------------------------------*/
/*** Refer to exterior ***/
extern void tsk01(void); /* TCB1 */
extern void tsk02(void); /* TCB2 */
extern void tsk03(void); /* TCB3 */
/*** Table for start addr init ***/

const TCBADDR knl_tcbAddrInit[KNL_TCB_NUM] = {
  { tsk01 }, /* TCB1 */
  { tsk02 }, /* TCB2 */
  { tsk03 }, /* TCB3 */
};

/*------ TCB Status Init -------------------------------------*/
/*
* Task status Init : CTCB_ST_RDY | CTCB_ST_SLP | ...
* ("slos.h" Refer to for details.)
*/
const UB knl_tcbStInit[KNL_TCB_NUM] = {
  CTCB_ST_RDY, /* TCB1 */
  CTCB_ST_RDY, /* TCB2 */
  CTCB_ST_RDY, /* TCB3 */
};


とするようです。

ではローテーションタスクへの登録方法ですが、先に出た定義のKNL_TCB_NUMで定義された全タスク数からKNL_TCB_PRI_NUMを引き算した数がローテーションタスクとして扱われるタスクの数であり、プライオリティタスクの生成情報の次にローテーションタスクの生成情報を記述する事となるかと思います。

例えばtsk01のみプライオリティタスクとし、残りのtsk02、tsk03をローテーションタスクとするなら、

/*------ TCB Number ------------------------------------------*/
#define KNL_TCB_NUM 3
#ifdef KNL_BB_PRIORITY
#define KNL_TCB_PRI_NUM 1
#endif

/*------ TCB Stack Size --------------------------------------*/
#define TCB1_SIZE 0x80u
#define TCB2_SIZE 0x80u
#define TCB3_SIZE 0x80u


H tcb_stack1[(TCB1_SIZE/sizeof(H))];
H tcb_stack2[(TCB2_SIZE/sizeof(H))];
H tcb_stack3[(TCB3_SIZE/sizeof(H))];
/*------ TCB Stack addr --------------------------------------*/
const TCBSP knl_tcbSpInit[KNL_TCB_NUM] = {
  { (H *)&tcb_stack1[TCB1_SIZE/sizeof(H)] }, /* TCB1 */
  { (H *)&tcb_stack2[TCB2_SIZE/sizeof(H)] }, /* TCB2 */
  { (H *)&tcb_stack3[TCB3_SIZE/sizeof(H)] }, /* TCB3 */
};

/*------ TCB Start addr Init ---------------------------------*/
/*** Refer to exterior ***/
extern void tsk01(void); /* TCB1 */
extern void tsk02(void); /* TCB2 */
extern void tsk03(void); /* TCB3 */
/*** Table for start addr init ***/

const TCBADDR knl_tcbAddrInit[KNL_TCB_NUM] = {
  { tsk01 }, /* TCB1 */
  { tsk02 }, /* TCB2 */
  { tsk03 }, /* TCB3 */
};

/*------ TCB Status Init -------------------------------------*/
/*
* Task status Init : CTCB_ST_RDY | CTCB_ST_SLP | ...
* ("slos.h" Refer to for details.)
*/
const UB knl_tcbStInit[KNL_TCB_NUM] = {
  CTCB_ST_RDY, /* TCB1 */
  CTCB_ST_RDY, /* TCB2 */
  CTCB_ST_RDY, /* TCB3 */
};


です。

しかしこの仕様はイマイチですね。ITRONの場合、μITRON4.0仕様からはこう言ったオブジェクトの生成情報はコンフィギュレータが自動的に生成する事を必須としており、ユーザーは決まった書式で必要な情報を入力するだけです。
以下はITRON4.0仕様のタスク生成静的APIの記述例。一見なんのこっちゃと思えるかもしれませんが、仕様書を読めばすぐに理解できます。

CRE_TSK(TSKID_1, {TA_HLNG, 1, Task1, 1, 256, NULL});
CRE_TSK(TSKID_2, {TA_HLNG, 1, Task2, 2, 256, NULL});
CRE_TSK(TSKID_3, {TA_HLNG, 1, Task3, 3, 256, NULL});

静的に生成できるオブジェクトの生成情報みたいな物は、容易に、しかも入力ミスを防ぐ意味でもこのコンフィギュレータの利用は有効だと思います。
何よりもコンフィギュレータの実行は、ターゲット側で行われるのではなく開発側で行われますので、コンフィギュレータが有ろうが、無かろうが、ターゲット側の負担は変わりません。

しかしsmalight osの場合は、config.c内のユーザーの配列の書き方に大きく依存してしまうので、うっかりミスが有ると、もうその時点でバグ決定です。
明らかにμITRON4.0仕様の後に開発したと思われるsmalight osでコンフィギュレータを取り入れないのは、なんとも手抜きに感じます。

smalight osを理解するには、結局のところITRON仕様も知っておく方がより理解も進むので、以下の本もどうぞ!。あのHOS本では上手く解説し切れなかった所も、上手に解説されています。(営業モード)

SuperHで学ぶμITRON仕様OS―リアルタイムOSの動作原理と実装法がわかる!

SuperHで学ぶμITRON仕様OS―リアルタイムOSの動作原理と実装法がわかる!

  • 作者: 鹿取 祐二
  • 出版社/メーカー: 電波新聞社
  • 発売日: 2005/12
  • メディア: 単行本


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。