source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/kernel/task.h@ 337

Last change on this file since 337 was 337, checked in by coas-nagasima, 6 years ago

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 19.5 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2015 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * $Id$
41 */
42
43/*
44 * タスク管理モジュール
45 */
46
47#ifndef TOPPERS_TASK_H
48#define TOPPERS_TASK_H
49
50#include "kernel_impl.h"
51#include <queue.h>
52#include "time_event.h"
53
54/*
55 * トレースログマクロのデフォルト定義
56 */
57#ifndef LOG_TSKSTAT
58#define LOG_TSKSTAT(p_tcb)
59#endif /* LOG_TSKSTAT */
60
61/*
62 * タスク優先度の内部表現・外部表現変換マクロ
63 */
64#define INT_PRIORITY(x) ((uint_t)((x) - TMIN_TPRI))
65#define EXT_TSKPRI(x) ((PRI)(x) + TMIN_TPRI)
66
67/*
68 * タスク状態の内部表現
69 *
70 * TCB中のタスク状態のフィールドでは,タスクの状態と,タスクが待ち状態
71 * の時の待ち要因を表す.ただし,実行状態(RUNNING)と実行可能状態
72 * (READY)は区別せず,両状態をあわせて実行できる状態(RUNNABLE)とし
73 * て管理する.二重待ち状態は,(TS_WAITING_??? | TS_SUSPENDED)で表す.
74 *
75 * タスクが待ち状態(二重待ち状態を含む)の時は,TS_WAITING_???で待ち
76 * 要因を表す.待ち要因(5ビットで表現される)の上位2ビットで,同期・
77 * 通信オブジェクトの待ちキューにつながっているかどうかを表す.同期・
78 * 通信オブジェクトの待ちキューにつながらないものは上位2ビットを00,同
79 * 期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)の待ちキュー
80 * につながるものは10または11,それ以外の待ちキューにつながるものは01
81 * とする.
82 */
83#define TS_DORMANT 0x00U /* 休止状態 */
84#define TS_RUNNABLE 0x01U /* 実行できる状態 */
85#define TS_SUSPENDED 0x02U /* 強制待ち状態 */
86
87#define TS_WAITING_SLP (0x01U << 2) /* 起床待ち */
88#define TS_WAITING_DLY (0x02U << 2) /* 時間経過待ち */
89#define TS_WAITING_RDTQ (0x08U << 2) /* データキューからの受信待ち */
90#define TS_WAITING_RPDQ (0x09U << 2) /* 優先度データキューからの受信待ち */
91#define TS_WAITING_SEM (0x10U << 2) /* セマフォ資源の獲得待ち */
92#define TS_WAITING_FLG (0x11U << 2) /* イベントフラグ待ち */
93#define TS_WAITING_SDTQ (0x12U << 2) /* データキューへの送信待ち */
94#define TS_WAITING_SPDQ (0x13U << 2) /* 優先度データキューへの送信待ち */
95#define TS_WAITING_MTX (0x14U << 2) /* ミューテックスのロック待ち */
96#define TS_WAITING_MPF (0x15U << 2) /* 固定長メモリブロックの獲得待ち */
97
98#define TS_WAITING_MASK (0x1fU << 2) /* 待ち状態の判別用マスク */
99
100/*
101 * タスク状態判別マクロ
102 *
103 * TSTAT_DORMANTはタスクが休止状態であるかどうかを,TSTAT_RUNNABLEは
104 * タスクが実行できる状態であるかどうかを判別する.TSTAT_WAITINGは待
105 * ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDEDは
106 * 強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
107 */
108#define TSTAT_DORMANT(tstat) ((tstat) == TS_DORMANT)
109#define TSTAT_RUNNABLE(tstat) (((tstat) & TS_RUNNABLE) != 0U)
110#define TSTAT_WAITING(tstat) (((tstat) & TS_WAITING_MASK) != 0U)
111#define TSTAT_SUSPENDED(tstat) (((tstat) & TS_SUSPENDED) != 0U)
112
113/*
114 * タスク待ち要因判別マクロ
115 *
116 * TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを,TSTAT_WAIT_MTXは
117 * タスクがミューテックス待ちであるかどうかを判別する.
118 *
119 * また,TSTAT_WAIT_WOBJ はタスクが同期・通信オブジェクトに対する待ち
120 * であるか(言い換えると,同期・通信オブジェクトの待ちキューにつなが
121 * れているか)どうかを,TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェ
122 * クトの管理ブロックの共通部分(WOBJCB)の待ちキューにつながれている
123 * かどうかを判別する.
124 */
125#define TSTAT_WAIT_SLP(tstat) (((tstat) & ~TS_SUSPENDED) == TS_WAITING_SLP)
126#define TSTAT_WAIT_MTX(tstat) (((tstat) & ~TS_SUSPENDED) == TS_WAITING_MTX)
127
128#define TSTAT_WAIT_WOBJ(tstat) (((tstat) & (0x18U << 2)) != 0U)
129#define TSTAT_WAIT_WOBJCB(tstat) (((tstat) & (0x10U << 2)) != 0U)
130
131/*
132 * 待ち情報ブロック(WINFO)の定義
133 *
134 * タスクが待ち状態の間は,TCBおよびそのp_winfoで指されるWINFOを次の
135 * ように設定しなければならない.
136 *
137 * (a) TCBのタスク状態を待ち状態(TS_WAITING_???)にする.
138 *
139 * (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
140 * 登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
141 * のローカル変数として確保し,それへのポインタをWINFOのp_tmevtbに記
142 * 憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
143 * p_tmevtbをNULLにする.
144 *
145 * 同期・通信オブジェクトに対する待ち状態の場合には,標準のWINFOに
146 * p_wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.hで定義)に,
147 * 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な情報
148 * のためのフィールドを追加した構造体(WINFO_???)を定義し,WINFOの代
149 * わりに用いる.また,以下の(c)~(e)の設定を行う必要がある.同期・通
150 * 信オブジェクトに関係しない待ち(起床待ち,時間経過待ち)の場合には,
151 * これらは必要ない.
152 *
153 * (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
154 * ちキューにつなぐために,task_queueを使う.
155 *
156 * (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
157 * WINFO_WOBJのp_wobjcbに記憶する.
158 *
159 * (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
160 * 情報がある場合には,WINFO_???内のフィールドに記憶する.
161 *
162 * 待ち状態を解除する際には,待ち解除したタスクに対する返値をWINFOの
163 * wercdに設定する.wercdが必要なのは待ち解除以降であるのに対して,
164 * p_tmevtbは待ち解除後は必要ないため,メモリ節約のために共用体を使っ
165 * ている.そのため,wercdへエラーコードを設定するのは,タイムイベント
166 * ブロックを登録解除した後にしなければならない.
167 */
168typedef union waiting_information {
169 ER wercd; /* 待ち解除時のエラーコード */
170 TMEVTB *p_tmevtb; /* 待ち状態用のタイムイベントブロック */
171} WINFO;
172
173/*
174 * ミューテックス管理ブロックの型の前方参照
175 */
176typedef struct mutex_control_block MTXCB;
177
178/*
179 * タスク初期化ブロック
180 *
181 * タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
182 * 初期化ブロック)と,値が変化するためにRAMに置かなければならない部
183 * 分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
184 * ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
185 * TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
186 * が,実行効率が悪くなるために採用していない.他のオブジェクトについ
187 * ても同様に扱う.
188 *
189 * タスク初期化ブロックには,DEF_TEXで定義されるタスク例外処理ルーチ
190 * ンに関する情報も含む.
191 */
192typedef struct task_initialization_block {
193 ATR tskatr; /* タスク属性 */
194 intptr_t exinf; /* タスクの拡張情報 */
195 TASK task; /* タスクの起動番地 */
196 uint_t ipriority; /* タスクの起動時優先度(内部表現) */
197
198#ifdef USE_TSKINICTXB
199 TSKINICTXB tskinictxb; /* タスク初期化コンテキストブロック */
200#else /* USE_TSKINICTXB */
201 size_t stksz; /* スタック領域のサイズ(丸めた値) */
202 void *stk; /* スタック領域の先頭番地 */
203#endif /* USE_TSKINICTXB */
204} TINIB;
205
206/*
207 * タスク管理ブロック(TCB)
208 *
209 * ASPカーネルでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)
210 * と起床要求キューイング数の最大値(TMAX_WUPCNT)は1に固定されている
211 * ため,キューイングされているかどうかの真偽値で表現することができる.
212 * また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が1に固定されてい
213 * るので,強制待ち要求ネスト数(suscnt)は必要ない.
214 *
215 * TCBのいくつかのフィールドは,特定のタスク状態でのみ有効な値を保持し,
216 * それ以外の場合は値が保証されない(よって,参照してはならない).各
217 * フィールドが有効な値を保持する条件は次の通り.
218 *
219 * ・初期化後は常に有効:
220 * p_tinib,tstat,actque
221 * ・休止状態以外で有効(休止状態では初期値になっている):
222 * bpriority,priority,wupque,raster,enater,p_lastmtx
223 * ・待ち状態(二重待ち状態を含む)で有効:
224 * p_winfo
225 * ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効:
226 * task_queue
227 * ・実行可能状態,待ち状態,強制待ち状態,二重待ち状態で有効:
228 * tskctxb
229 */
230typedef struct task_control_block {
231 QUEUE task_queue; /* タスクキュー */
232 const TINIB *p_tinib; /* 初期化ブロックへのポインタ */
233
234#ifdef UINT8_MAX
235 uint8_t tstat; /* タスク状態(内部表現)*/
236 uint8_t bpriority; /* ベース優先度(内部表現)*/
237 uint8_t priority; /* 現在の優先度(内部表現)*/
238#else /* UINT8_MAX */
239 BIT_FIELD_UINT tstat : 8; /* タスク状態(内部表現)*/
240 BIT_FIELD_UINT bpriority : 8; /* ベース優先度(内部表現)*/
241 BIT_FIELD_UINT priority : 8 /* 現在の優先度(内部表現)*/;
242#endif /* UINT8_MAX */
243 BIT_FIELD_BOOL actque : 1; /* 起動要求キューイング */
244 BIT_FIELD_BOOL wupque : 1; /* 起床要求キューイング */
245 BIT_FIELD_BOOL raster : 1; /* タスク終了要求状態 */
246 BIT_FIELD_BOOL enater : 1; /* タスク終了許可状態 */
247
248 WINFO *p_winfo; /* 待ち情報ブロックへのポインタ */
249 MTXCB *p_lastmtx; /* 最後にロックしたミューテックス */
250 TSKCTXB tskctxb; /* タスクコンテキストブロック */
251} TCB;
252
253/*
254 * 実行状態のタスク
255 *
256 * 実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
257 * TCBを指すポインタ.実行状態のタスクがない場合はNULLにする.
258 *
259 * サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
260 * ク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き換え
261 * るのは,ディスパッチャ(と初期化処理)のみである.
262 */
263extern TCB *p_runtsk;
264
265/*
266 * 実行すべきタスク
267 *
268 * 実行すべきタスクのTCBを指すポインタ.実行できるタスクがない場合は
269 * NULLにする.
270 *
271 * p_runtskは,通常はp_schedtskと一致しているが,非タスクコンテキスト
272 * 実行中は,一致しているとは限らない.割込み優先度マスク全解除でない
273 * 状態の間とディスパッチ禁止状態の間(すなわち,dspflgがfalseである間)
274 * は,p_schedtskを更新しない.
275 */
276extern TCB *p_schedtsk;
277
278/*
279 * ディスパッチ許可状態
280 *
281 * ディスパッチ許可状態であることを示すフラグ.
282 */
283extern bool_t enadsp;
284
285/*
286 * タスクディスパッチ可能状態
287 *
288 * 割込み優先度マスク全解除状態であり,ディスパッチ許可状態である(ディ
289 * スパッチ禁止状態でない)ことを示すフラグ.ディスパッチ保留状態でな
290 * いことは,タスクコンテキスト実行中で,CPUロック状態でなく,dspflgが
291 * trueであることで判別することができる.
292 */
293extern bool_t dspflg;
294
295/*
296 * レディキュー
297 *
298 * レディキューは,実行できる状態のタスクを管理するためのキューである.
299 * 実行状態のタスクも管理しているため,レディ(実行可能)キューという
300 * 名称は正確ではないが,レディキューという名称が定着しているため,こ
301 * の名称で呼ぶことにする.
302 *
303 * レディキューは,優先度ごとのタスクキューで構成されている.タスクの
304 * TCBは,該当する優先度のキューに登録される.
305 */
306extern QUEUE ready_queue[TNUM_TPRI];
307
308/*
309 * レディキューサーチのためのビットマップ
310 *
311 * レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
312 * にタスクが入っているかどうかを示すビットマップを用意している.ビッ
313 * トマップを使うことで,メモリアクセスの回数を減らすことができるが,
314 * ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
315 * 場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
316 * る可能性もある.
317 *
318 * 優先度が16段階であることを仮定しているため,uint16_t型としている.
319 */
320extern uint16_t ready_primap;
321
322/*
323 * 使用していないTCBのリスト
324 */
325extern QUEUE free_tcb;
326
327/*
328 * タスクIDの最大値(kernel_cfg.c)
329 */
330extern const ID tmax_tskid;
331extern const ID tmax_stskid;
332
333/*
334 * タスク初期化ブロックのエリア(kernel_cfg.c)
335 */
336extern const TINIB tinib_table[];
337extern TINIB atinib_table[];
338
339/*
340 * タスク生成順序テーブル(kernel_cfg.c)
341 */
342extern const ID torder_table[];
343
344/*
345 * TCBのエリア(kernel_cfg.c)
346 */
347extern TCB tcb_table[];
348
349/*
350 * タスクの数
351 */
352#define tnum_tsk ((uint_t)(tmax_tskid - TMIN_TSKID + 1))
353#define tnum_stsk ((uint_t)(tmax_stskid - TMIN_TSKID + 1))
354
355/*
356 * タスクIDからTCBを取り出すためのマクロ
357 */
358#define INDEX_TSK(tskid) ((uint_t)((tskid) - TMIN_TSKID))
359#define get_tcb(tskid) (&(tcb_table[INDEX_TSK(tskid)]))
360
361/*
362 * TCBからタスクIDを取り出すためのマクロ
363 */
364#define TSKID(p_tcb) ((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
365
366/*
367 * タスク管理モジュールの初期化
368 */
369extern void initialize_task(void);
370
371/*
372 * 最高優先順位タスクのサーチ
373 *
374 * レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
375 * を返す.レディキューが空の場合には,この関数を呼び出してはならない.
376 */
377extern TCB *search_schedtsk(void);
378
379/*
380 * 実行できる状態への遷移
381 *
382 * p_tcbで指定されるタスクをレディキューに挿入する.レディキューに挿入
383 * したタスクの優先度が,実行すべきタスクの優先度よりも高い場合は,実
384 * 行すべきタスクを更新する.
385 */
386extern void make_runnable(TCB *p_tcb);
387
388/*
389 * 実行できる状態から他の状態への遷移
390 *
391 * p_tcbで指定されるタスクをレディキューから削除する.p_tcbで指定した
392 * タスクが実行すべきタスクであった場合には,実行すべきタスクを更新す
393 * る.
394 */
395extern void make_non_runnable(TCB *p_tcb);
396
397/*
398 * 休止状態への遷移
399 *
400 * p_tcbで指定されるタスクの状態を休止状態とする.また,タスクの起動
401 * 時に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設
402 * 定する.
403 */
404extern void make_dormant(TCB *p_tcb);
405
406/*
407 * 休止状態から実行できる状態への遷移
408 *
409 * p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする.
410 */
411extern void make_active(TCB *p_tcb);
412
413/*
414 * タスクの優先度の変更
415 *
416 * p_tcbで指定されるタスクの優先度をnewpri(内部表現)に変更する.また,
417 * 必要な場合には,実行すべきタスクを更新する.
418 *
419 * p_tcbで指定されるタスクの優先順位は,優先度が同じタスクの中で,
420 * mtxmodeがfalseの時は最低,mtxmodeがtrueの時は最高とする.
421 */
422extern void change_priority(TCB *p_tcb, uint_t newpri, bool_t mtxmode);
423
424/*
425 * レディキューの回転
426 *
427 * レディキュー中の,p_queueで指定されるタスクキューを回転させる.また,
428 * 必要な場合には,実行すべきタスクを更新する.
429 */
430extern void rotate_ready_queue(QUEUE *p_queue);
431
432/*
433 * タスクの終了処理
434 *
435 * p_tcbで指定されるタスクを終了させる処理を行う.タスクの起動要求キュー
436 * イング数が0でない場合には,再度起動するための処理を行う.
437 */
438extern void task_terminate(TCB *p_tcb);
439
440#endif /* TOPPERS_TASK_H */
Note: See TracBrowser for help on using the repository browser.