task.h

説明を見る。
00001 /*
00002  *  TOPPERS/JSP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Just Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  *  Copyright (C) 2005 by Embedded and Real-Time Systems Laboratory
00009  *              Graduate School of Information Science, Nagoya Univ., JAPAN
00010  * 
00011  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00012  *  によって公表されている GNU General Public License の Version 2 に記
00013  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00014  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00015  *  利用と呼ぶ)することを無償で許諾する.
00016  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00017  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00018  *      スコード中に含まれていること.
00019  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00020  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00021  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00022  *      の無保証規定を掲載すること.
00023  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00024  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00025  *      と.
00026  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00027  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00028  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00029  *        報告すること.
00030  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00031  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00032  * 
00033  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00034  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00035  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00036  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00037  * 
00038  *  @(#) $Id: task.h,v 1.10 2005/11/15 06:42:04 hiro Exp $
00039  */
00040 
00041 /*
00042  *      タスク管理モジュール
00043  */
00044 
00045 #ifndef _TASK_H_
00046 #define _TASK_H_
00047 
00048 #include "queue.h"
00049 #include "time_event.h"
00050 
00051 /*
00052  *  タスク優先度の内部表現・外部表現変換マクロ
00053  */
00054 #define INT_PRIORITY(x)         ((UINT)((x) - TMIN_TPRI))
00055 #define EXT_TSKPRI(x)           ((PRI)(x) + TMIN_TPRI)
00056 
00057 /*
00058  *  タスク状態の内部表現
00059  *
00060  *  TCB 中のタスク状態では,実行状態(RUNNING)と実行可能状態(READY)
00061  *  は区別しない.両状態を総称して,実行できる状態(RUNNABLE)と呼ぶ.
00062  *  二重待ち状態は,(TS_WAITING | TS_SUSPENDED) で表す.TS_WAIT_???? 
00063  *  は,待ち状態に伴う付属状態を表し,待ち状態(二重待ち状態を含む)の
00064  *  場合にのみ設定される.
00065  */
00066 #define TS_DORMANT      0x00u   /* 休止状態 */
00067 #define TS_RUNNABLE     0x01u   /* 実行できる状態 */
00068 #define TS_WAITING      0x02u   /* 待ち状態 */
00069 #define TS_SUSPENDED    0x04u   /* 強制待ち状態 */
00070 
00071 #define TS_WAIT_SLEEP   0x08u   /* 起床待ち状態 */
00072 #define TS_WAIT_WOBJ    0x10u   /* 同期・通信オブジェクトに対する待ち状態 */
00073 #define TS_WAIT_WOBJCB  0x20u   /* 共通部分の待ちキューにつながっている */
00074 
00075 /*
00076  *  タスク状態判別マクロ
00077  *
00078  *  TSTAT_DORMANT はタスクが休止状態であるかどうかを,TSTAT_RUNNABLE 
00079  *  はタスクが実行できる状態であるかどうかを判別する.TSTAT_WAITING は
00080  *  待ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDED 
00081  *  は強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
00082  */
00083 #define TSTAT_DORMANT(tstat)    ((tstat) == TS_DORMANT)
00084 #define TSTAT_RUNNABLE(tstat)   (((tstat) & TS_RUNNABLE) != 0)
00085 #define TSTAT_WAITING(tstat)    (((tstat) & TS_WAITING) != 0)
00086 #define TSTAT_SUSPENDED(tstat)  (((tstat) & TS_SUSPENDED) != 0)
00087 
00088 /*
00089  *  待ち情報ブロック(WINFO)の定義
00090  *
00091  *  タスクが待ち状態の間は,TCB およびそこから指される WINFO を次のよ
00092  *  うに設定しなければならない.
00093  *
00094  *  (a) TCB のタスク状態を待ち状態にする.その際に,待ち状態に伴う付属
00095  *  状態(TS_WAIT_????)も設定する.
00096  *
00097  *  (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
00098  *  登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
00099  *  のローカル変数として確保し,それへのポインタを WINFO の tmevtb に
00100  *  記憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
00101  *  tmevtb を NULL にする.
00102  *
00103  *  同期・通信オブジェクトに対する待ち状態の場合には,標準の WINFO に 
00104  *  wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.h で定義)を使
00105  *  い,タスク状態に TS_WAIT_WOBJ を設定する.また,以下の (c)〜(e) の
00106  *  設定を行う必要がある.同期・通信オブジェクトに関係しない待ち(起床
00107  *  待ち,時間経過待ち)の場合には,(c)〜(e) は必要ない.
00108  *
00109  *  (c) TCB を待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
00110  *  ちキューにつなぐために,task_queue を使う.TCB を同期・通信オブジェ
00111  *  クトの管理ブロックの共通部分(WOBJCB)の待ちキューにつないだ場合に
00112  *  は,タスク状態に TS_WAIT_WOBJCB を設定する.
00113  *
00114  *  (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
00115  *  WINFO_WOBJ の wobjcb に記憶する.
00116  *  JSPカーネルで wobjcb を使うのは,優先度順の待ちキューにつながれて
00117  *  いるタスクの優先度が変更された場合のみであるが,デバッグ情報を取り
00118  *  出しやすいように,待ちキューが優先度順でない場合にも wobjcb を設定
00119  *  する.
00120  *
00121  *  (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
00122  *  情報がある場合には,WINFO_WOBJ に必要な情報のためのフィールドを追加
00123  *  した構造体を定義し,WINFO_WOBJ の代わりに用いる.
00124  *
00125  *  待ち状態を解除する際には,待ち解除したタスクからの返値を WINFO の
00126  *  wercd に設定する.wercd を使うのは待ち解除以降であるのに対して,
00127  *  tmevtb は待ち解除後は使わないため,メモリ節約のために共用体(union)
00128  *  を使っている.
00129  */
00130 typedef union waiting_information { 
00131         ER      wercd;          /* 待ち解除時のエラーコード */ 
00132         TMEVTB  *tmevtb;        /* 待ち状態用のタイムイベントブロック */
00133 } WINFO;
00134 
00135 /*
00136  *  タスク初期化ブロック
00137  *
00138  *  タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
00139  *  初期化ブロック)と,値が変化するためにRAMに置かなければならない部
00140  *  分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
00141  *  ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
00142  *  TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
00143  *  が,実行効率が悪くなるために採用していない.他のオブジェクトについ
00144  *  ても同様に扱う.
00145  *  タスク初期化ブロックには,DEF_TEX で定義されるタスク例外処理ルーチ
00146  *  ンに関する情報も含む.
00147  */
00148 typedef struct task_initialization_block { 
00149         ATR     tskatr;         /* タスク属性 */ 
00150         VP_INT  exinf;          /* タスクの拡張情報 */ 
00151         FP      task;           /* タスクの起動番地 */ 
00152         UINT    ipriority;      /* タスクの起動時優先度(内部表現) */ 
00153         SIZE    stksz;          /* スタック領域のサイズ(丸めた値) */ 
00154         VP      stk;            /* スタック領域の先頭番地 */
00156         ATR     texatr;         /* タスク例外処理ルーチン属性 */ 
00157         FP      texrtn;         /* タスク例外処理ルーチンの起動番地 */
00158 } TINIB;
00159 
00160 /*
00161  *  TCB 中のフィールドのビット幅の定義
00162  *
00163  *  TCB 中のフィールドの配置は,性能に大きく影響すると思われるため,ター
00164  *  ゲット依存にフィールドのビット幅を変更することを許している.
00165  */
00166 #ifndef TBIT_TCB_TSTAT
00167 #define TBIT_TCB_TSTAT          6       /* tstat フィールドのビット幅 */
00168 #endif /* TBIT_TCB_TSTAT */
00169 
00170 #ifndef TBIT_TCB_PRIORITY
00171 #define TBIT_TCB_PRIORITY       4       /* priority フィールドのビット幅 */
00172 #endif /* TBIT_TCB_PRIORITY */
00173 
00174 /*
00175  *  タスク管理ブロック(TCB)
00176  *
00177  *  JSPでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)と起
00178  *  動要求キューイング数の最大値(TMAX_WUPCNT)は 1 に固定されているた
00179  *  め,キューイングされているかどうかの真偽値で表現することができる.
00180  *  また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が 1 に固定されて
00181  *  いるので,強制待ち要求ネスト数(suscnt)は必要ない.
00182  */
00183 typedef struct task_control_block { 
00184         QUEUE   task_queue;     /* タスクキュー */ 
00185         const TINIB *tinib;     /* タスク初期化ブロックへのポインタ */
00187         UINT    tstat : TBIT_TCB_TSTAT;         /* タスク状態(内部表現)*/ 
00188         UINT    priority : TBIT_TCB_PRIORITY;   /* 現在の優先度(内部表現)*/ 
00189         unsigned int    actcnt : 1;             /* 起動要求キューイング */ 
00190         unsigned int    wupcnt : 1;             /* 起床要求キューイング */ 
00191         unsigned int    enatex : 1;             /* タスク例外処理許可状態 */
00193         TEXPTN  texptn;         /* 保留例外要因 */ 
00194         WINFO   *winfo;         /* 待ち情報ブロックへのポインタ */ 
00195         CTXB    tskctxb;        /* タスクコンテキストブロック */
00196 } TCB;
00197 
00198 /*
00199  *  実行状態のタスク
00200  *
00201  *  実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
00202  *  TCB を指すポインタ.実行状態のタスクがない場合は NULL にする.
00203  *  サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
00204  *  ク)に関する情報を参照する場合は runtsk を使う.runtsk を書き換え
00205  *  るのは,ディスパッチャ(と初期化処理)のみである.
00206  */
00207 extern TCB      *runtsk;
00208 
00209 /*
00210  *  最高優先順位のタスク
00211  *
00212  *  実行できるタスクの中で最高優先順位のタスクの TCB を指すポインタ.実
00213  *  行できるタスクがない場合は NULL にする.
00214  *  ディスパッチ禁止状態など,ディスパッチが保留されている間は,runtsk
00215  *  と一致しているとは限らない.
00216  */
00217 extern TCB      *schedtsk;
00218 
00219 /*
00220  *  ディスパッチ/タスク例外処理ルーチン起動要求フラグ
00221  *
00222  *  割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたは
00223  *  タスク例外処理ルーチンの起動を要求することを示すフラグ.
00224  */
00225 extern BOOL     reqflg;
00226 
00227 /*
00228  *  ディスパッチ許可状態
00229  *
00230  *  ディスパッチ許可状態である(すなわち,ディスパッチ禁止状態でない)
00231  *  ことを示すフラグ.
00232  */
00233 extern BOOL     enadsp;
00234 
00235 /*
00236  *  レディキュー
00237  *
00238  *  レディキューは,実行できる状態のタスクを管理するためのキューである.
00239  *  実行状態のタスクも管理しているため,レディ(実行可能)キューという
00240  *  名称は正確ではないが,レディキューという名称が定着しているため,こ
00241  *  の名称で呼ぶことにする.
00242  *
00243  *  レディキューは,優先度ごとのタスクキューで構成されている.タスクの
00244  *  TCBは,該当する優先度のキューに登録される.
00245  */
00246 extern QUEUE    ready_queue[TNUM_TPRI];
00247 
00248 /*
00249  *  レディキューサーチのためのビットマップ
00250  *
00251  *  レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
00252  *  にタスクが入っているかどうかを示すビットマップを用意している.ビッ
00253  *  トマップを使うことで,メモリアクセスの回数を減らすことができるが,
00254  *  ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
00255  *  場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
00256  *  る可能性もある.
00257  */
00258 extern UINT     ready_primap;
00259 
00260 /*
00261  *  タスクIDの最大値(kernel_cfg.c)
00262  */
00263 extern const ID tmax_tskid;
00264 
00265 /*
00266  *  タスク初期化ブロックのエリア(kernel_cfg.c)
00267  */
00268 extern const TINIB      tinib_table[];
00269 
00270 /*
00271  *  タスク生成順序テーブル(kernel_cfg.c)
00272  */
00273 extern const ID torder_table[];
00274 
00275 /*
00276  *  TCBのエリア(kernel_cfg.c)
00277  */
00278 extern TCB      tcb_table[];
00279 
00280 /*
00281  *  タスクの数
00282  */
00283 #define TNUM_TSK        ((UINT)(tmax_tskid - TMIN_TSKID + 1))
00284 
00285 /*
00286  *  タスクIDからTCBを取り出すためのマクロ
00287  */
00288 #define INDEX_TSK(tskid)        ((UINT)((tskid) - TMIN_TSKID))
00289 #define get_tcb(tskid)          (&(tcb_table[INDEX_TSK(tskid)]))
00290 #define get_tcb_self(tskid)     ((tskid) == TSK_SELF ? runtsk : get_tcb(tskid))
00291 
00292 /*
00293  *  TCBからタスクIDを取り出すためのマクロ
00294  */
00295 #define TSKID(tcb)      ((ID)(((tcb) - tcb_table) + TMIN_TSKID))
00296 
00297 /*
00298  *  タスク管理モジュールの初期化
00299  */
00300 extern void     task_initialize(void);
00301 
00302 /*
00303  *  最高優先順位タスクのサーチ
00304  *
00305  *  レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
00306  *  を返す.レディキューが空の場合には,この関数を呼び出してはならない.
00307  */
00308 extern TCB      *search_schedtsk(void);
00309 
00310 /*
00311  *  実行できる状態への移行
00312  *
00313  *  tcb で指定されるタスクの状態を実行できる状態とし,レディキューに挿
00314  *  入する.実行できる状態になったタスクの優先度が,最高優先順位のタス
00315  *  クの優先度よりも高い場合は,最高優先順位のタスクを更新し,ディスパッ
00316  *  チ許可状態であれば TRUE を返す.そうでない場合は FALSE を返す.
00317  */
00318 extern BOOL     make_runnable(TCB *tcb);
00319 
00320 /*
00321  *  実行できる状態から他の状態への移行
00322  *
00323  *  tcb で指定されるタスクをレディキューから削除する.tcb で指定したタ
00324  *  スクが最高優先順位のタスクであった場合には,最高優先順位のタスクを
00325  *  設定しなおし,ディスパッチ許可状態であれば TRUE を返す.そうでない
00326  *  場合は FALSE を返す.タスクの状態は更新しない.
00327  */
00328 extern BOOL     make_non_runnable(TCB *tcb);
00329 
00330 /*
00331  *  休止状態への移行
00332  *
00333  *  tcb で指定されるタスクの状態を休止状態とする.また,タスクの起動時
00334  *  に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設定
00335  *  する.
00336  */
00337 extern void     make_dormant(TCB *tcb);
00338 
00339 /*
00340  *  休止状態から実行できる状態への移行
00341  *
00342  *  tcb で指定されるタスクの状態を休止状態から実行できる状態とする.実
00343  *  行できる状態に移行したタスクへのディスパッチが必要な場合は TRUE,
00344  *  そうでない場合は FALSE を返す.
00345  */
00346 extern BOOL     make_active(TCB *tcb);
00347 
00348 /*
00349  *  実行状態のタスクの終了
00350  *
00351  *  exit_task を ext_tsk に埋め込まずに別の関数にしているのは,
00352  *  create_context と activate_context が自タスクの終了処理で使用する
00353  *  スタックを破壊しないようにするための対策の一環である.ext_tsk とは
00354  *  別関数にしておくことで,ローカル変数も含めて,使用するスタック領域
00355  *  が重ならないようにできる.また,コンパイラが自動的にインライン展開
00356  *  するのを避けるために,ext_tsk とは別のファイルに入れている.
00357  */
00358 extern void     exit_task(void);
00359 
00360 /*
00361  *  レディキュー中のタスクの優先度の変更
00362  *
00363  *  tcb で指定されるレディキュー中のタスクの優先度を newpri(内部表現)
00364  *  に変更する.また,必要な場合には最高優先順位のタスクを更新し,ディ
00365  *  スパッチ許可状態であれば TRUE を返す.そうでない場合は FALSE を返
00366  *  す.
00367  */
00368 extern BOOL     change_priority(TCB *tcb, UINT newpri);
00369 
00370 /*
00371  *  レディキューの回転
00372  *
00373  *  レディキュー中の,pri で指定される優先度のタスクキューを回転させる.
00374  *  また,必要な場合には最高優先順位のタスクを変更し,ディスパッチが保
00375  *  留されていなければ TRUE を返す.そうでない場合は FALSE を返す.
00376  */
00377 extern BOOL     rotate_ready_queue(UINT pri);
00378 
00379 /*
00380  *  タスク例外処理ルーチンの呼出し
00381  *
00382  *  タスク例外処理ルーチンを呼び出す.呼び出す前に,実行状態のタスクの
00383  *  保留例外要因をクリアし,タスク例外処理禁止状態にし,CPUロックを解
00384  *  除する.
00385  *  タスク例外処理ルーチンから戻ると,まずCPUロック状態に戻し,その間
00386  *  に保留例外要因が 0 でなくなっていれば,再びタスク例外処理ルーチン
00387  *  を呼び出す.保留例外要因が 0 の場合には,例外処理許可状態にして関
00388  *  数からリターンする.
00389  *  この関数は,実行状態のタスクが,タスク例外処理許可状態(enatex が 
00390  *  TRUE)で,保留例外要因が 0 でない(texptn が 0 でない)場合に呼び
00391  *  出すことを想定している.この関数は,CPUロック状態で呼び出さなけれ
00392  *  ばならない.
00393  */
00394 extern void     call_texrtn(void);
00395 
00396 /*
00397  *  タスク例外処理ルーチンの起動
00398  *
00399  *  実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば,
00400  *  タスク例外処理ルーチンを呼び出す.CPU例外処理ルーチンを呼び出す時
00401  *  は,一時的にCPUロックを解除する.
00402  *  この関数は,ディスパッチャや割込みハンドラ/CPU例外ハンドラの出口
00403  *  処理から呼び出されることを想定しているが,同等の処理をターゲット依
00404  *  存部で記述してもよい.その場合には,OMIT_CALLTEX をマクロ定義すれ
00405  *  ばよい.
00406  */
00407 extern void     calltex(void);
00408 
00409 #endif /* _TASK_H_ */
00410 

Copyright © 2006 by TAKAGI Nobuhisa.
Copyright © 2006 by Kijineko Inc..
このページは Mon Dec 18 17:18:41 2006 に Doxygen によって生成されました。
データ入力からプログラム開発まで!様々なスキルを持ったメンバーが登録しています【@SOHO】