4 (Release 1.4対応,最終更新: 15-Mar-2005)
6 ------------------------------------------------------------------------
8 Toyohashi Open Platform for Embedded Real-Time Systems/
9 Just Standard Profile Kernel
11 Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
12 Toyohashi Univ. of Technology, JAPAN
14 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
15 によって公表されている GNU General Public License の Version 2 に記
16 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
17 を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
19 (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
20 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
22 (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
23 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
24 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
26 (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
29 (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
30 作権表示,この利用条件および下記の無保証規定を掲載すること.
31 (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
33 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
36 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
37 よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
38 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
39 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
41 @(#) $Id: design.txt,v 1.1 2009/01/31 05:27:37 suikan Exp $
42 ------------------------------------------------------------------------
49 JSPカーネルは,名前の通りスタンダードプロファイルに含まれる機能のみを
50 サポートする.スタンダードプロファイル外の機能は,原則としてサポートし
53 内部構造の設計にあたっては,スタンダードプロファイル外の機能をサポート
54 するための拡張性は考慮せず,スタンダードプロファイルに含まれる機能を効
59 JSPカーネルでは,サービスコールはすべて割込み禁止で実行する.スタンダー
60 ドプロファイルの機能の範囲内では,この方法で十分と考えられるが,拡張機
61 能を追加する時には設計を見直すべきである.具体的には,非タスクコンテキ
62 ストから呼び出されたサービスコールを遅延実行する方法が有力である.
64 (3) CPU例外ハンドラの実行コンテキスト
66 JSPカーネルでは,CPU例外ハンドラは非タスクコンテキストで実行する.
68 参考: μITRON4.0仕様では,タスクコンテキストで発生したCPU例外に対する
69 CPU例外ハンドラを,タスクコンテキストで実行するか非タスクコンテキスト
77 実行コンテキストは,タスクコンテキストと非タスクコンテキストのいずれか
80 実行コンテキストの管理はターゲット依存部で行う.具体的には,タスクコン
81 テキストと非タスクコンテキストを判別する関数(sense_context)を,ター
84 また,タスクコンテキストと非タスクコンテキストの間の遷移も,ターゲット
85 依存部の責任である.具体的には,割込みハンドラ/CPU例外ハンドラが起動
86 されると非タスクコンテキストに切り換わり,割込みハンドラ/CPU例外ハン
87 ドラからリターンすると元の実行コンテキストに戻るよう,ターゲット依存部
92 システムは,CPUロック状態か,CPUロック解除状態のいずれかにある.CPUロッ
93 ク状態では,すべての割込み(カーネルの管理外のものを除く.以下同じ)が
96 CPUロック状態の管理はターゲット依存部で行う.具体的には,CPUロック状態/
97 CPUロック解除状態のいずれの状態であるかを判別する関数(sense_lock,
98 t_sense_lock,i_sense_lock)と,CPUロック状態とCPUロック解除状態の間を
99 遷移させる関数(t_lock_cpu,t_unlock_cpu,i_lock_cpu,i_unlock_cpu)を,
100 ターゲット依存部で用意する.これらの関数を呼び出す以外の方法で,CPUロッ
101 ク状態とCPUロック解除状態の間を遷移することはない.
104 3.ディスパッチとタスク例外処理ルーチン起動の方法
108 ディスパッチを行う必要があるのは,以下のタイミングである.
110 (a) サービスコール内での明示的なタスクディスパッチ要求
112 タスクコンテキストから呼び出されたサービスコール処理において,明示的に
113 タスクディスパッチが要求された場合.具体的には,実行状態のタスクよりも
114 優先順位の高く実行できる状態のタスクが生じる場合と,実行状態のタスク
115 (自タスク)を待ち状態にする場合がある.いずれの場合にも,サービスコー
116 ル処理内でディスパッチャを明示的に呼び出すことで,ディスパッチを行う.
118 (b) 割込みハンドラ/CPU例外ハンドラの出口
120 割込みハンドラ/CPU例外ハンドラ(以下,ハンドラと総称する)から呼び出
121 されたサービスコールでタスクディスパッチが要求された場合,ハンドラの出
122 口でタスクディスパッチが必要かチェックし,必要であればタスクディスパッ
123 チを行う.ハンドラが多重に起動されている場合,最も外側のハンドラの出口
126 ※ プロセッサによっては,CPU例外ハンドラの入口処理の先頭では,非タスク
127 コンテキストであると認識させられない場合がある.このような場合,入口処
128 理の途中でハンドラが多重に起動されても,内側のハンドラでさらに外側のハ
129 ンドラがあることを認識できず,内側のハンドラでタスクディスパッチを行う
130 ことになる.この場合でも,入口処理の非タスクコンテキストであると認識さ
131 れない部分は,ハンドラの一部ではないと解釈すれば,上記の原則は守られて
132 いることになる.この注記は,以下の記述にも同様にあてはまる.
134 (2) タスク例外処理ルーチンの起動が必要なタイミング
136 タスク例外処理ルーチンを起動するのは,仕様書によると,「タスク例外処理
137 許可状態」「保留例外要因が 0 でない」「タスクが実行状態である」「非タ
138 スクコンテキストまたはCPU例外ハンドラが実行されていない」の四つの条件
139 が揃った場合である.このことから,タスク例外処理ルーチンの起動を行う必
144 タスクディスパッチにより,実行状態のタスク(runtsk)が変化する.新しく
145 実行状態になったタスクが起動条件を満たしていれば,タスク例外処理ルーチ
148 (b) 割込みハンドラ/CPU例外ハンドラの出口
150 割込みハンドラ/CPU例外ハンドラ(以下,ハンドラと総称する)の出口では,
151 タスクディスパッチを行う場合がある.その場合には,(a) の理由で必要なら,
154 ハンドラの出口でタスクディスパッチを行わない場合でも,ハンドラ内で実行
155 状態のタスクに対してタスク例外処理が要求された場合には,ハンドラの出口
156 で起動条件をチェックし,起動条件を満たしていればタスク例外処理ルーチン
157 を起動する.ハンドラが多重に起動されている場合,最も外側のハンドラの出
160 (c) 自タスクに対するタスク例外処理の要求
162 自タスクに対してタスク例外処理を要求した結果,自タスクが起動条件を満た
163 すようになれば,タスク例外処理ルーチンを起動する.
167 タスク例外処理許可状態に移行した結果,自タスクが起動条件を満たすように
168 なれば,タスク例外処理ルーチンを起動する.タスク例外処理許可状態への移
169 行は,ena_tex の呼出しによって起こる.
171 (3) サービスコール処理内での明示的なディスパッチャの呼出し
173 タスクコンテキストから呼び出されたサービスコール処理においてディスパッ
174 チが必要になった場合,サービスコールの処理を中断すべきタイミングで
175 dispatch を呼び出す.dispatch を呼び出すと,その時点で最も優先順位の高
176 いタスクが実行される.dispatch は,呼び出したタスクが次に実行状態にな
177 るとタスク例外処理ルーチンの起動条件をチェックし,起動条件を満たしてい
180 そのため,dispatch を呼び出したサービスコールへ処理が戻ってくるのは,
181 呼び出したタスクが次に実行状態となり,起動すべきタスク例外処理ルーチン
184 なお,dispatch の処理は,ターゲット依存部で提供される.
186 (4) 割込みハンドラ/CPU例外ハンドラの出口での処理
188 割込みハンドラ/CPU例外ハンドラ(以下,ハンドラと総称する)の出口処理
189 では,ディスパッチが必要か,タスク例外処理ルーチンの起動が必要かをチェッ
190 クし,必要な処理を行う.ハンドラが多重に起動されている場合,最も外側の
193 具体的には,ディスパッチとタスク例外処理ルーチンの起動のいずれかの処理
194 が必要な場合には reqflg を TRUE にすることとし,最も外側のハンドラの出
195 口で reqflg が TRUE になっていれば,まずディスパッチが必要かチェックし,
196 必要ならディスパッチを行う.ディスパッチにより新たに実行状態になったタ
197 スクがタスク例外処理ルーチンの起動条件を満たしていれば,タスク例外処理
198 ルーチンを起動する.ディスパッチが必要なかった場合には,実行中のタスク
199 がタスク例外処理ルーチンの起動条件を満たしているかチェックし,満たして
200 いればタスク例外処理ルーチンを起動する.二つのタスク例外処理ルーチンの
201 起動処理は,意味的には異なるものだが,ルーチン的には共通化できる可能性
204 なお,ハンドラの出口処理は,ターゲット依存部で提供される.
208 タスク起動時のレジスタ復帰と,タスク終了時のレジスタ保存は,ターゲット
211 タスクの起動は,create_context と activate_context によって,次にその
212 タスクへのディスパッチが起こった時に,タスクの起動番地から実行するよう
213 にタスクコンテキストを設定することで行う.
215 タスク終了時には,unlock_cpu に代えて,exit_and_dispatch を呼び出す.
216 exit_and_dispatch は,現在実行中のコンテキストを保存せずに,ディスパッ
219 なお,create_context,activate_context,exit_and_dispatch の処理は,ター
222 (6) 実行できる状態のタスクがない場合の扱い
224 実行できる状態のタスクがない場合の対策として,アイドルタスクを導入する
225 方法がある.アイドルタスクを導入すると,ディスパッチャの途中で割込み待
226 ちをする必要がないので,ソフトウェアの構造的にはエレガントになる.また,
227 ディスパッチャ中での条件分岐も減る.逆に,RAM の使用量がどうしても増え
228 てしまうという問題がある.このことから,アイドルタスクは使わない方針と
233 ディスパッチが保留されるのは,次のいずれかの場合である.
238 CPU例外ハンドラは非タスクコンテキストで実行するとしたため,CPU例外ハン
239 ドラ実行中は,非タスクコンテキスト実行中に含めて考えることができる.ま
240 た,サービスコールはすべて割込み禁止で実行するため,サービスコール実行
243 この中で,非タスクコンテキスト実行中は,sense_context() で判定できる.
244 そこで,ディスパッチ禁止状態を表すBOOL型の変数を用意すれば,ディスパッ
245 チ保留状態が保持できることになる.実際には,ディスパッチ許可状態を表す
246 BOOL型の変数 enatex を導入した.
248 ※ サービスコール実行中に割込みを許可する(ディスパッチは許可しない)
249 場合には,サービスコール処理の途中で起動された割込みハンドラの出口では,
250 ディスパッチもタスク例外処理ルーチンの起動も行ってはならない.参照する
251 場所が違うことから,両者の禁止を別々の変数にする方法も考えられるが,設
252 定する方の効率を考えると,一つの変数で両方禁止できる方が良いと思われる.
253 すなわち,ディスパッチ禁止状態とサービスコール実行中状態を,同じ変数を
254 ビットフィールドに分けて記憶するのが妥当と考えられる.さらに,CPU例外
255 ハンドラをタスクコンテキストで実行する実装では,同じ変数にCPU例外ハン
256 ドラのネスト回数も記憶したくなる.例えば,次のような変数 pndflg を導入
261 ・下から2ビットめ … ディスパッチ禁止状態
263 ・残りのビット … CPU例外ハンドラのネスト回数
271 sns_ctx,sns_loc,sns_dsp,sns_tex は,サービスコール内部でクリティカ
274 (2) タスクコンテキスト専用のサービスコール
276 ※ CPUロック状態で呼ばれるとエラーになることに注意.
278 (2-1) タスク切換えを起こさないもの(例: get_pri)
287 (2-2) タスク切換えを起こす可能性のあるもの(例: act_tsk)
294 if (タスクディスパッチが必要 && enadsp) {
295 /* 自タスクを待ち状態にするサービスコールでは,
296 上で enadsp をチェックする必要はない.*/
301 (2-3) 自タスクを終了するもの(ext_tsk)
313 tcb = get_tcb_self(tskid);
318 tcb->texptn |= rasptn;
319 if (tcb == runtsk && runtsk->enatex) {
320 texptn = runtsk->texptn;
321 runtsk->enatex = FALSE;
325 (*runtsk->tinib->texrtn)(texptn, runtsk->tinib->exinf);
327 /* CPUロック状態のままリターンした場合を対策 */
328 if (!t_sense_lock()) {
332 タスク例外処理ルーチンの起動条件を再度チェック&起動
333 (runtsk->texptn が 0 になるまで上の処理を繰り返す)
335 runtsk->enatex = TRUE;
346 runtsk->enatex = TRUE;
347 if (runtsk->texptn != 0) {
348 texptn = runtsk->texptn;
349 runtsk->enatex = FALSE;
353 (*runtsk->tinib->texrtn)(texptn, runtsk->tinib->exinf);
355 /* CPUロック状態のままリターンした場合を対策 */
356 if (!t_sense_lock()) {
360 タスク例外処理ルーチンの起動条件を再度チェック&起動
361 (runtsk->texptn が 0 になるまで上の処理を繰り返す)
363 runtsk->enatex = TRUE;
367 (3) 非タスクコンテキスト専用のサービスコール
369 ※ CPUロック状態で呼ばれるとエラーになることに注意.
379 (3-2) タスク切替えを起こす可能性のあるもの(例: iact_tsk)
385 * タスクディスパッチが必要な場合には,reqflg を TRUE にする.
386 * ただし,enadsp が FALSE の時は,reqflg を TRUE にしない.
393 tcb = get_tcb(tskid);
398 tcb->texptn |= rasptn;
399 if (tcb == runtsk && runtsk->enatex) {