|
|
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】 |