source: UsbWattMeter/trunk/asp_dcre/kernel/task.h

Last change on this file was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr; charset=SHIFT_JIS
File size: 16.7 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-2010 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: task.h 167 2016-03-08 11:37:45Z coas-nagasima $
41 */
42
43/*
44 * タスク管理モジュール
45 */
46
47#ifndef TOPPERS_TASK_H
48#define TOPPERS_TASK_H
49
50#include <queue.h>
51#include "time_event.h"
52
53/*
54 * トレースログマクロのデフォルト定義
55 */
56#ifndef LOG_TSKSTAT
57#define LOG_TSKSTAT(p_tcb)
58#endif /* LOG_TSKSTAT */
59
60/*
61 * タスク優先度の内部表現・外部表現変換マクロ
62 */
63#define INT_PRIORITY(x) ((uint_t)((x) - TMIN_TPRI))
64#define EXT_TSKPRI(x) ((PRI)(x) + TMIN_TPRI)
65
66/*
67 * タスク状態の内部表現
68 *
69 * TCB中のタスク状態では,実行状態(RUNNING)と実行可能状態(READY)
70 * は区別しない.両状態を総称して,実行できる状態(RUNNABLE)と呼ぶ.
71 * 二重待ち状態は,(TS_WAITING | TS_SUSPENDED)で表す.TS_WAIT_???は待
72 * ち要因を表し,待ち状態(二重待ち状態を含む)の場合にのみ設定する.
73 */
74#define TS_DORMANT 0x00U /* 休止状態 */
75#define TS_RUNNABLE 0x01U /* 実行できる状態 */
76#define TS_WAITING 0x02U /* 待ち状態 */
77#define TS_SUSPENDED 0x04U /* 強制待ち状態 */
78
79#define TS_WAIT_DLY (0x00U << 3) /* 時間経過待ち */
80#define TS_WAIT_SLP (0x01U << 3) /* 起床待ち */
81#define TS_WAIT_RDTQ (0x02U << 3) /* データキューからの受信待ち */
82#define TS_WAIT_RPDQ (0x03U << 3) /* 優先度データキューからの受信待ち */
83#define TS_WAIT_SEM (0x04U << 3) /* セマフォ資源の獲得待ち */
84#define TS_WAIT_FLG (0x05U << 3) /* イベントフラグ待ち */
85#define TS_WAIT_SDTQ (0x06U << 3) /* データキューへの送信待ち */
86#define TS_WAIT_SPDQ (0x07U << 3) /* 優先度データキューへの送信待ち */
87#define TS_WAIT_MBX (0x08U << 3) /* メールボックスからの受信待ち */
88#define TS_WAIT_MPF (0x09U << 3) /* 固定長メモリブロックの獲得待ち */
89
90/*
91 * タスク状態判別マクロ
92 *
93 * TSTAT_DORMANTはタスクが休止状態であるかどうかを,TSTAT_RUNNABLEは
94 * タスクが実行できる状態であるかどうかを判別する.TSTAT_WAITINGは待
95 * ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDEDは
96 * 強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
97 */
98#define TSTAT_DORMANT(tstat) ((tstat) == TS_DORMANT)
99#define TSTAT_RUNNABLE(tstat) (((tstat) & TS_RUNNABLE) != 0U)
100#define TSTAT_WAITING(tstat) (((tstat) & TS_WAITING) != 0U)
101#define TSTAT_SUSPENDED(tstat) (((tstat) & TS_SUSPENDED) != 0U)
102
103/*
104 * タスク待ち要因判別マクロ
105 *
106 * TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを,TSTAT_WAIT_WOBJ
107 * はタスクが同期・通信オブジェクトに対する待ちであるか(言い換えると,
108 * 同期通信オブジェクトの待ちキューにつながれているか)どうかを判別す
109 * る.また,TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェクトの管理
110 * ブロックの共通部分(WOBJCB)の待ちキューにつながれているかどうかを
111 * 判別する.
112 *
113 * TSTAT_WAIT_SLPは,任意のタスク状態の中から,タスクが起床待ちである
114 * ことを判別できる.すなわち,TSTAT_WAITINGにより待ち状態であることを
115 * 判別せずに,TSTAT_SLPだけを用いて起床待ち状態であることを判別できる.
116 * これを効率的に実現するために,TS_WAIT_SLPの値を,(0x00U << 3)ではな
117 * く(0x01U << 3)としている.そのため,タスクが時間経過待ち状態である
118 * ことを判別するためのTSTAT_WAIT_DLYを,TSTAT_WAIT_SLPと同様の方法で
119 * 実現することはできない.
120 */
121#define TS_WAIT_MASK (0x0fU << 3) /* 待ち要因の取出しマスク */
122
123#define TSTAT_WAIT_SLP(tstat) (((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
124#define TSTAT_WAIT_WOBJ(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
125#define TSTAT_WAIT_WOBJCB(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
126
127/*
128 * 待ち情報ブロック(WINFO)の定義
129 *
130 * タスクが待ち状態の間は,TCBおよびそのp_winfoで指されるWINFOを次の
131 * ように設定しなければならない.
132 *
133 * (a) TCBのタスク状態を待ち状態(TS_WAITING)にする.その際に,待ち
134 * 要因(TS_WAIT_???)も設定する.
135 *
136 * (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
137 * 登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
138 * のローカル変数として確保し,それへのポインタをWINFOのp_tmevtbに記
139 * 憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
140 * p_tmevtbをNULLにする.
141 *
142 * 同期・通信オブジェクトに対する待ち状態の場合には,標準のWINFOに
143 * p_wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.hで定義)を使
144 * う.また,以下の(c)〜(e)の設定を行う必要がある.同期・通信オブジェ
145 * クトに関係しない待ち(起床待ち,時間経過待ち)の場合には,(c)〜(e)
146 * は必要ない.
147 *
148 * (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
149 * ちキューにつなぐために,task_queueを使う.
150 *
151 * (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
152 * WINFO_WOBJのp_wobjcbに記憶する.
153 *
154 * (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
155 * 情報がある場合には,WINFO_WOBJに必要な情報のためのフィールドを追加
156 * した構造体を定義し,WINFO_WOBJの代わりに用いる.
157 *
158 * 待ち状態を解除する際には,待ち解除したタスクに対する返値をWINFOの
159 * wercdに設定する.wercdが必要なのは待ち解除以降であるのに対して,
160 * p_tmevtbは待ち解除後は必要ないため,メモリ節約のために共用体を使っ
161 * ている.そのため,wercdへエラーコードを設定するのは,タイムイベント
162 * ブロックを登録解除した後にしなければならない.
163 */
164typedef union waiting_information {
165 ER wercd; /* 待ち解除時のエラーコード */
166 TMEVTB *p_tmevtb; /* 待ち状態用のタイムイベントブロック */
167} WINFO;
168
169/*
170 * タスク初期化ブロック
171 *
172 * タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
173 * 初期化ブロック)と,値が変化するためにRAMに置かなければならない部
174 * 分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
175 * ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
176 * TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
177 * が,実行効率が悪くなるために採用していない.他のオブジェクトについ
178 * ても同様に扱う.
179 *
180 * タスク初期化ブロックには,DEF_TEXで定義されるタスク例外処理ルーチ
181 * ンに関する情報も含む.
182 */
183typedef struct task_initialization_block {
184 ATR tskatr; /* タスク属性 */
185 intptr_t exinf; /* タスクの拡張情報 */
186 TASK task; /* タスクの起動番地 */
187 uint_t ipriority; /* タスクの起動時優先度(内部表現) */
188
189#ifdef USE_TSKINICTXB
190 TSKINICTXB tskinictxb; /* タスク初期化コンテキストブロック */
191#else /* USE_TSKINICTXB */
192 SIZE stksz; /* スタック領域のサイズ(丸めた値) */
193 void *stk; /* スタック領域の先頭番地 */
194#endif /* USE_TSKINICTXB */
195
196 ATR texatr; /* タスク例外処理ルーチン属性 */
197 TEXRTN texrtn; /* タスク例外処理ルーチンの起動番地 */
198} TINIB;
199
200/*
201 * TCB中のフィールドのビット幅の定義
202 *
203 * プロセッサによっては,TCB中のフィールドのビット幅でメモリ使用量と
204 * 性能がトレードオフになるため,ターゲット依存にフィールドのビット幅
205 * を変更することを許している.
206 */
207#ifndef TBIT_TCB_PRIORITY
208#define TBIT_TCB_PRIORITY 8 /* priorityフィールドのビット幅 */
209#endif /* TBIT_TCB_PRIORITY */
210
211/*
212 * タスク管理ブロック(TCB)
213 *
214 * ASPカーネルでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)
215 * と起床要求キューイング数の最大値(TMAX_WUPCNT)は1に固定されている
216 * ため,キューイングされているかどうかの真偽値で表現することができる.
217 * また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が1に固定されてい
218 * るので,強制待ち要求ネスト数(suscnt)は必要ない.
219 *
220 * TCBのいくつかのフィールドは,特定のタスク状態でのみ有効な値を保持し,
221 * それ以外の場合は値が保証されない(よって,参照してはならない).各
222 * フィールドが有効な値を保持する条件は次の通り.
223 *
224 * ・初期化後は常に有効:
225 * p_tinib,tstat,actque
226 * ・休止状態以外で有効(休止状態では初期値になっている):
227 * priority,wupque,enatex,texptn
228 * ・待ち状態(二重待ち状態を含む)で有効:
229 * p_winfo
230 * ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効:
231 * task_queue
232 * ・実行可能状態,待ち状態,強制待ち状態,二重待ち状態で有効:
233 * tskctxb
234 */
235typedef struct task_control_block {
236 QUEUE task_queue; /* タスクキュー */
237 const TINIB *p_tinib; /* 初期化ブロックへのポインタ */
238
239#ifdef UINT8_MAX
240 uint8_t tstat; /* タスク状態(内部表現)*/
241#else /* UINT8_MAX */
242 BIT_FIELD_UINT tstat : 8; /* タスク状態(内部表現)*/
243#endif /* UINT8_MAX */
244#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
245 uint8_t priority; /* 現在の優先度(内部表現)*/
246#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
247 BIT_FIELD_UINT priority : TBIT_TCB_PRIORITY;
248 /* 現在の優先度(内部表現)*/
249#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
250 BIT_FIELD_BOOL actque : 1; /* 起動要求キューイング */
251 BIT_FIELD_BOOL wupque : 1; /* 起床要求キューイング */
252 BIT_FIELD_BOOL enatex : 1; /* タスク例外処理許可状態 */
253
254 TEXPTN texptn; /* 保留例外要因 */
255 WINFO *p_winfo; /* 待ち情報ブロックへのポインタ */
256 TSKCTXB tskctxb; /* タスクコンテキストブロック */
257} TCB;
258
259/*
260 * 実行状態のタスク
261 *
262 * 実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
263 * TCBを指すポインタ.実行状態のタスクがない場合はNULLにする.
264 *
265 * サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
266 * ク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き換え
267 * るのは,ディスパッチャ(と初期化処理)のみである.
268 */
269extern TCB *p_runtsk;
270
271/*
272 * 最高優先順位のタスク
273 *
274 * 実行できるタスクの中で最高優先順位のタスクのTCBを指すポインタ.実
275 * 行できるタスクがない場合はNULLにする.
276 *
277 * ディスパッチ禁止状態など,ディスパッチが保留されている間はp_runtsk
278 * と一致しているとは限らない.
279 */
280extern TCB *p_schedtsk;
281
282/*
283 * ディスパッチ/タスク例外処理ルーチン起動要求フラグ
284 *
285 * 割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたは
286 * タスク例外処理ルーチンの起動を要求することを示すフラグ.
287 */
288extern bool_t reqflg;
289
290/*
291 * 割込み優先度マスク全解除状態
292 *
293 * 割込み優先度マスク全解除状態であることを示すフラグ.
294 */
295extern bool_t ipmflg;
296
297/*
298 * ディスパッチ禁止状態
299 *
300 * ディスパッチ禁止状態であることを示すフラグ.
301 */
302extern bool_t disdsp;
303
304/*
305 * タスクディスパッチ可能状態
306 *
307 * 割込み優先度マスク全解除状態であり,ディスパッチ許可状態である(ディ
308 * スパッチ禁止状態でない)ことを示すフラグ.
309 */
310extern bool_t dspflg;
311
312/*
313 * レディキュー
314 *
315 * レディキューは,実行できる状態のタスクを管理するためのキューである.
316 * 実行状態のタスクも管理しているため,レディ(実行可能)キューという
317 * 名称は正確ではないが,レディキューという名称が定着しているため,こ
318 * の名称で呼ぶことにする.
319 *
320 * レディキューは,優先度ごとのタスクキューで構成されている.タスクの
321 * TCBは,該当する優先度のキューに登録される.
322 */
323extern QUEUE ready_queue[TNUM_TPRI];
324
325/*
326 * レディキューサーチのためのビットマップ
327 *
328 * レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
329 * にタスクが入っているかどうかを示すビットマップを用意している.ビッ
330 * トマップを使うことで,メモリアクセスの回数を減らすことができるが,
331 * ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
332 * 場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
333 * る可能性もある.
334 *
335 * 優先度が16段階であることを仮定しているため,uint16_t型としている.
336 */
337extern uint16_t ready_primap;
338
339/*
340 * 使用していないTCBのリスト
341 */
342extern QUEUE free_tcb;
343
344/*
345 * タスクIDの最大値(kernel_cfg.c)
346 */
347extern const ID tmax_tskid;
348extern const ID tmax_stskid;
349
350/*
351 * タスク初期化ブロックのエリア(kernel_cfg.c)
352 */
353extern const TINIB tinib_table[];
354extern TINIB atinib_table[];
355
356/*
357 * タスク生成順序テーブル(kernel_cfg.c)
358 */
359extern const ID torder_table[];
360
361/*
362 * TCBのエリア(kernel_cfg.c)
363 */
364extern TCB tcb_table[];
365
366/*
367 * タスクの数
368 */
369#define tnum_tsk ((uint_t)(tmax_tskid - TMIN_TSKID + 1))
370#define tnum_stsk ((uint_t)(tmax_stskid - TMIN_TSKID + 1))
371
372/*
373 * タスクIDからTCBを取り出すためのマクロ
374 */
375#define INDEX_TSK(tskid) ((uint_t)((tskid) - TMIN_TSKID))
376#define get_tcb(tskid) (&(tcb_table[INDEX_TSK(tskid)]))
377#define get_tcb_self(tskid) ((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
378
379/*
380 * TCBからタスクIDを取り出すためのマクロ
381 */
382#define TSKID(p_tcb) ((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
383
384/*
385 * タスク管理モジュールの初期化
386 */
387extern void initialize_task(void);
388
389/*
390 * 最高優先順位タスクのサーチ
391 *
392 * レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
393 * を返す.レディキューが空の場合には,この関数を呼び出してはならない.
394 */
395extern TCB *search_schedtsk(void);
396
397/*
398 * 実行できる状態への遷移
399 *
400 * p_tcbで指定されるタスクをレディキューに挿入する.レディキューに挿入
401 * したタスクの優先度が,最高優先順位のタスクの優先度よりも高い場合は,
402 * 最高優先順位のタスクを更新し,ディスパッチ許可状態であればtrueを返
403 * す.そうでない場合はfalseを返す.
404 */
405extern bool_t make_runnable(TCB *p_tcb);
406
407/*
408 * 実行できる状態から他の状態への遷移
409 *
410 * p_tcbで指定されるタスクをレディキューから削除する.p_tcbで指定した
411 * タスクが最高優先順位のタスクであった場合には,最高優先順位のタスク
412 * を設定しなおし,ディスパッチ許可状態であればtrueを返す.そうでない
413 * 場合はfalseを返す.タスクの状態は更新しない.
414 */
415extern bool_t make_non_runnable(TCB *p_tcb);
416
417/*
418 * 休止状態への遷移
419 *
420 * p_tcbで指定されるタスクの状態を休止状態とする.また,タスクの起動
421 * 時に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設
422 * 定する.
423 */
424extern void make_dormant(TCB *p_tcb);
425
426/*
427 * 休止状態から実行できる状態への遷移
428 *
429 * p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする.
430 * 実行できる状態に遷移したタスクへのディスパッチが必要な場合はtrue,
431 * そうでない場合はfalseを返す.
432 */
433extern bool_t make_active(TCB *p_tcb);
434
435/*
436 * タスクの優先度の変更
437 *
438 * p_tcbで指定されるタスクの優先度をnewpri(内部表現)に変更する.また,
439 * 必要な場合には最高優先順位のタスクを更新し,ディスパッチ許可状態で
440 * あればtrueを返す.そうでない場合はfalseを返す.
441 */
442extern bool_t change_priority(TCB *p_tcb, uint_t newpri);
443
444/*
445 * レディキューの回転
446 *
447 * レディキュー中の,priで指定される優先度のタスクキューを回転させる.
448 * また,必要な場合には最高優先順位のタスクを変更し,ディスパッチが保
449 * 留されていなければtrueを返す.そうでない場合はfalseを返す.
450 */
451extern bool_t rotate_ready_queue(uint_t pri);
452
453/*
454 * タスク例外処理ルーチンの呼出し
455 *
456 * タスク例外処理ルーチンを呼び出す.呼び出す前に,実行状態のタスクの
457 * 保留例外要因をクリアし,タスク例外処理禁止状態にし,CPUロックを解
458 * 除する.
459 *
460 * タスク例外処理ルーチンから戻ると,まずCPUロック状態に戻し,その間
461 * に保留例外要因が0でなくなっていれば,再びタスク例外処理ルーチンを
462 * 呼び出す.保留例外要因が0の場合には,例外処理許可状態にして関数か
463 * らリターンする.
464 *
465 * この関数は,実行状態のタスクが,タスク例外処理許可状態(enatexが
466 * true)で,保留例外要因が0でない(texptnが0でない)場合に呼び出すこ
467 * とを想定している.この関数は,CPUロック状態で呼び出さなければなら
468 * ない.
469 */
470extern void call_texrtn(void);
471
472/*
473 * タスク例外処理ルーチンの起動
474 *
475 * 実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば,
476 * タスク例外処理ルーチンを呼び出す.CPU例外処理ルーチンを呼び出す時
477 * は,一時的にCPUロックを解除する.
478 *
479 * この関数は,ディスパッチャや割込みハンドラ/CPU例外ハンドラの出口
480 * 処理から呼び出されることを想定している.この関数は,CPUロック状態
481 * で呼び出さなければならない.
482 *
483 * 実行効率を上げるために,この関数をターゲット依存部で記述してもよい.
484 * その場合には,OMIT_CALLTEXをマクロ定義する.
485 */
486extern void calltex(void);
487
488#endif /* TOPPERS_TASK_H */
Note: See TracBrowser for help on using the repository browser.