source: rubycfg_asp/trunk/asp_dcre/doc/design.txt@ 313

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

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain
File size: 80.6 KB
Line 
1
2 TOPPERS/ASPカーネル
3 設計メモ
4
5 対応バージョン: Release 1.9.3
6 最終更新: 2014年4月15日(作成中)
7
8このドキュメントは,TOPPERS/ASPカーネルの設計メモである.作成途中のもの
9であり,網羅
10的ではない.
11
12----------------------------------------------------------------------
13 TOPPERS/ASP Kernel
14 Toyohashi Open Platform for Embedded Real-Time Systems/
15 Advanced Standard Profile Kernel
16
17 Copyright (C) 2005-2014 by Embedded and Real-Time Systems Laboratory
18 Graduate School of Information Science, Nagoya Univ., JAPAN
19
20 上記著作権者
21は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
22 ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
23 変・再é…
24å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
25 (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
26 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
27 スコード中に含まれていること.
28 (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
29 用できる形で再é…
30å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
32 者
33マニュアルなど)に,上記の著作権表示,この利用条件および下記
34 の無保証規定を掲載すること.
35 (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
36 用できない形で再é…
37å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
38 と.
39 (a) 再é…
40å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
41マニュアルなど)に,上記の著
42 作権表示,この利用条件および下記の無保証規定を掲載すること.
43 (b) 再é…
44å¸ƒã®å½¢æ…
45‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
46 報告すること.
47 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
48 害からも,上記著作権者
49およびTOPPERSプロジェクトをå…
50è²¬ã™ã‚‹ã“と.
51 また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
52 由に基づく請求からも,上記著作権者
53およびTOPPERSプロジェクトを
54 å…
55è²¬ã™ã‚‹ã“と.
56
57 本ソフトウェアは,無保証で提供されているものである.上記著作権者
58お
59 よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
60 に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
61 アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
62 の責任を負わない.
63
64 $Id: design.txt 313 2017-07-23 04:50:32Z coas-nagasima $
65----------------------------------------------------------------------
66
67○目次
68
69・TOPPERS/ASPカーネルの実装
70設計方針
71・システム状æ…
72‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£…
73
74 - カーネル動作状æ…
75‹ã¨éžå‹•ä½œçŠ¶æ…
76‹
77 - タスクコンテキストと非タスクコンテキスト
78 - å…
79¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
80‹ã¨å…
81¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
82‹
83 - CPUロック状æ…
84‹ã¨CPUロック解除状æ…
85‹
86 - 割込み優å…
87ˆåº¦ãƒžã‚¹ã‚¯
88 - ディスパッチ禁止状æ…
89‹ã¨ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ…
90‹
91 - ディスパッチ保留状æ…
92‹
93・タスク状æ…
94‹ã®ç®¡ç†ã¨ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒªãƒ³ã‚°
95 - タスク状æ…
96‹ã®ç®¡ç†
97 - タスクスケジューラ
98・タスクディスパッチ処理の実装
99
100 - タスクディスパッチ処理の必
101要なタイミング
102 - タスクディスパッチャの構造
103 - タスクの終了時のタスクディスパッチ
104 - reqflgの導å…
105¥ç†ç”±
106・タスク例外処理機能の実装
107
108 - タスク例外処理ルーチンの実行開始条件とシステム状æ…
109‹ï¼ˆä»•æ§˜ã®ç¢ºèªï¼‰
110 - タスク例外処理ルーチンの呼出し処理
111 - タスク例外処理ルーチンの実行開始が必
112要なタイミング
113 - タスク例外処理ルーチンの実行開始処理
114 - call_texrtnからdispatchを呼び出す処理について
115・エラーのチェック順序
116 - エラーの3分類
117 - 静的エラーのチェック順序
118 - 準静的エラーのチェック順序
119・CHECKマクロとgoto文の使用
120 - CHECKマクロの定義とその使用法
121 - 設計意図
122 - CHECKマクロを使用してよい条件
123 - 問題を生じることがない根拠
124・ext_tsk,ext_kerの返り値
125・カーネルのデータ構造に対するvolatile宣言について
126・型キャストに伴う警告メッセージ
127・性能評価用システム時刻参ç…
128§æ©Ÿèƒ½
129 - 必
130要性と使途
131 - API仕様
132 - 実装
133
134・タスク例外処理禁止フラグをenatexで実装
135している理由
136
137
138○TOPPERS/ASPカーネルの実装
139設計方針
140
141TOPPERS/ASPカーネル(以下,ASPカーネル)は,TOPPERS新世代カーネルの出発
142点となるリアルタイムカーネルである.TOPPERS新世代カーネル仕様の設計方針
143と,ASPカーネルの適用対象領域と設計方針については,TOPPERS新世代カーネ
144ル統合仕様書に述べられている.
145
146以下では,ASPカーネルの実装
147設計方針について述べるが,仕様設計方針とも関
148連しており,明確に分離できない部分もある.
149
150TOPPERS/ASPカーネルの実装
151設計を行うにあたり,次の方針を設定する.
152
153(1) ソースコードの読みやすさ・改造しやすさを重視する
154
155ソースコードが読みやすいことは,オープンソースソフトウェアの品質を向上
156させる上で最も重要な特性である.ソースコードを理解している技術者
157が増え
158ることで,問題を早期に発見することができ,サポート体制もå…
159…
160実させること
161ができる.また,ソースコードが読みやすいことは,シンプルな設計がされて
162いることも意味しており,信頼性向上にもつながる.さらに,技術者
163教育のた
164めの教材とする観点からも,ソースコードが読みやすいことは重要となる.
165
166改造しやすいことは,システム毎の要求にあわせたチューニングが行いやすい
167ことを意味しており,擦り合わせ型の開発を支援する性質である.また,ASPカー
168ネルを基盤としてTOPPERS新世代カーネルシリーズを開発していく上でも,改造
169しやすいことは必
170須の条件である.
171
172(2) 新しいターゲットシステムへのポーティングが容易な構造とする
173
174組込みシステムには多様なハードウェアが用いられるため,それらに容易にポー
175ティングできることは重要な性質である.そのために,実行性能にé…
176æ…
177®ã—つつ
178ハードウェアを抽象化し,ターゲットシステムに依存する部分(ターゲット依
179存部)と依存しない部分(ターゲット非依存部)を明確に分離する.また,開
180発環境(コンパイラなど)に依存する部分も明確に分離する.
181
182(3) 検証が容易な構造とする
183
184信頼性を確保するために,検証が容易な構造とする.
185
186å…
187·ä½“的には,サービスコールのほとんどå…
188¨ä½“を割込み禁止で実行することとし,
189サービスコールの処理途中で割込みを許可しない.この構造は,読みやすく改
190造しやすいソースコードにするためにも有効である.これにより割込み応答性
191が犠牲になるが,それによって問題を生じるアプリケーションは少数であり,
192やむをえないものと考える.
193
194また,条件コンパイル等によりコンフィギュレーションできる箇所を増やすと,
195細かな最適化ができる一方で,検証すべき組合せが増えることから,コンフィ
196ギュレーションできる箇所は必
197要最低限とする.
198
199(4) 実行性能とメモリ使用量にé…
200æ…
201®ã™ã‚‹
202
203上記の方針を満たした上で,高い実行性能と小さいメモリ使用量を達成できる
204ような実装
205を行う.実行性能を向上させる際には,平均性能の向上よりも,最
206悪時性能の向上を重視する.
207
208ソースコードの読みやすさを重視すると言っても,実行性能の悪いアルゴリズ
209ムを安易に採用することはせず,高い実行性能を達成できるアルゴリズムを用
210いる.ただし,新しいターゲットシステムへのポーティングを容易にするため
211に大部分をC言語で実装
212しており,すべてをアセンブリ言語で記述した場合に比
213べて実行性能が落ちるのはやむをえない.
214
215メモリ使用量については,RAMの使用量を削減することに重点を置いた設計を行
216うが,上記の方針および実行性能とのトレードオフを考æ…
217®ã—,ぎりぎりまでの
218削減は行わない.
219
220(5) スケーラビリティにé…
221æ…
222®ã™ã‚‹
223
224様々
225な規模のシステムに適用できるスケーラビリティをもった構造とする.特
226に,小規模なシステムに適用する際に,使用しない機能をカーネルが持ってい
227ることによるメモリ使用量の増加が最小限になるようにé…
228æ…
229®ã™ã‚‹ï¼Ž
230
231å…
232·ä½“的には,アプリケーションとカーネルを1つのロードモジュールにリンクす
233る方法(1リンクモデル)を想定し,カーネルを関数単位でライブラリ化して,
234使用する関数のみをリンクできる構造とする.これは一種のコンフィギュレー
235ションであるが,この方法は,条件コンパイルによるコンフィギュレーション
236とは違い,検証工数に与える影響が小さい.
237
238また,固定的に使用するRAM領域を減らし,スタックに置ける情
239報はできる限り
240スタック上に置く.
241
242
243○システム状æ…
244‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£…
245
246
247この章では,「TOPPERS新世代カーネル統合仕様書」の「2.5 システム状æ…
248‹ã¨ã‚³
249ンテキスト」の節に規定されているシステム状æ…
250‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£…
251方法に
252ついて記述する.
253
254●カーネル動作状æ…
255‹ã¨éžå‹•ä½œçŠ¶æ…
256‹
257
258カーネルの動作状æ…
259‹ã‚’管理するために,カーネル動作状æ…
260‹ãƒ•ãƒ©ã‚°ï¼ˆkerflg)を
261用意する.kerflgは,スタートアップモジュールでfalse(=0)に初期化する.
262また,カーネル動作の開始時にtrueにし,カーネル動作の終了時にfalseにする.
263
264----------------------------------------
265bool_t kerflg = false;
266----------------------------------------
267
268kerflgは,sns_kerで参ç…
269§ã™ã‚‹ï¼Žã‚«ãƒ¼ãƒãƒ«éžå‹•ä½œçŠ¶æ…
270‹ã§sns_ker以外のサービス
271コールを呼び出した場合の動作は保証する必
272要がないため,他のサービスコー
273ルではkerflgを参ç…
274§ã—ない.
275
276●タスクコンテキストと非タスクコンテキスト
277
278タスクコンテキストと非タスクコンテキストの切換えは,ターゲットハードウェ
279アおよびターゲット依存部に委ねる.また,どちらのコンテキストで実行中で
280あるかを判別する関数(sense_context)も,ターゲット依存部で用意すること
281とする.
282
283●å…
284¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
285‹ã¨å…
286¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
287‹
288
289å…
290¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯ãƒ•ãƒ©ã‚°ã®ç®¡ç†ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ね,å…
291¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
292‹
293に遷移させるマクロ(SIL_LOC_INT)と,å…
294ƒã®çŠ¶æ…
295‹ã«æˆ»ã™ãƒžã‚¯ãƒ­ï¼ˆSIL_UNL_INT)
296は,SILのターゲット依存部で用意することとする.å…
297¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
298‹ã§ã‚ã‚‹
299か否かを判別する機能は,必
300要がないために用意していない.
301
302å…
303¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
304‹ã§sns_kerとext_ker以外のサービスコールを呼び出した場
305合の動作は保証する必
306要がないため,サービスコール中でå…
307¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
308‹
309であることを判別する必
310要はない.
311
312●CPUロック状æ…
313‹ã¨CPUロック解除状æ…
314‹
315
316CPUロックフラグの管理はターゲット依存部に委ね,CPUロック状æ…
317‹ã«é·ç§»ã•ã›
318る関数(t_lock_cpu/i_lock_cpu/x_lock_cpu)と,CPUロック解除状æ…
319‹ã«é·ç§»
320させる関数(t_unlock_cpu/i_unlock_cpu/x_unlock_cpu)は,ターゲット依
321存部で用意することとする.また,CPUロック状æ…
322‹ã§ã‚るか否かを判別する関数
323(t_sense_lock/i_sense_lock/x_sense_lock)も,ターゲット依存部で用意
324することとする.
325
326●割込み優å…
327ˆåº¦ãƒžã‚¹ã‚¯
328
329割込み優å…
330ˆåº¦ãƒžã‚¹ã‚¯ã®ç®¡ç†ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ね,割込み優å…
331ˆåº¦ãƒžã‚¹ã‚¯ã‚’
332設定する関数(t_set_ipm/i_set_ipm/x_set_ipm)と,それを参ç…
333§ã™ã‚‹é–¢æ•°
334(t_get_ipm/i_get_ipm/x_get_ipm)は,ターゲット依存部で用意することと
335する.
336
337ただし,タスクコンテキストの実行中に,割込み優å…
338ˆåº¦ãƒžã‚¹ã‚¯å…
339¨è§£é™¤çŠ¶æ…
340‹ã§ã‚
341ることを効率的に判断するために,割込み優å…
342ˆåº¦ãƒžã‚¹ã‚¯å…
343¨è§£é™¤çŠ¶æ…
344‹ã§ã‚ること
345を示すフラグ(ipmflg)を用意する.
346
347ipmflgは,カーネルの初期化時にfalseに初期化する.非タスクコンテキストで
348は,割込み優å…
349ˆåº¦ãƒžã‚¹ã‚¯å…
350¨è§£é™¤çŠ¶æ…
351‹ã«ãªã‚‹ã“とはないため,このフラグを用い
352る必
353要はなく,フラグの更新も行わない.
354
355----------------------------------------
356bool_t ipmflg;
357----------------------------------------
358
359●ディスパッチ禁止状æ…
360‹ã¨ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ…
361‹
362
363ディスパッチ禁止フラグを管理するために,フラグ(disdsp)を用意する.
364disdspは,カーネルの初期化時にfalseに初期化する.
365
366----------------------------------------
367bool_t disdsp;
368----------------------------------------
369
370※ disdspではなく,それを論理反転したenadspを用意した方が,ipmflgや
371dspflgとの整合性の観点からは良かった.
372
373●ディスパッチ保留状æ…
374‹
375
376ディスパッチ保留状æ…
377‹ã¯ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ï¼ŒCPUロック状æ…
378‹ï¼Œå‰²
379込み優å…
380ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
381¨è§£é™¤ã§ãªã„状æ…
382‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ…
383‹ã®ã„ずれか(ま
384たは,それらが重なった状æ…
385‹ï¼‰ã§ã‚る.
386
387タスクコンテキストの実行中に,ディスパッチ保留状æ…
388‹ã§ãªã„こと(つまり,
389ディスパッチできる状æ…
390‹ã§ã‚ること)を効率的に判別するために,割込み優å…
391ˆ
392度マスクå…
393¨è§£é™¤çŠ¶æ…
394‹ã§ã‚り,ディスパッチ許可状æ…
395‹ã§ã‚る(ディスパッチ禁止
396状æ…
397‹ã§ãªã„)ことを示すフラグ(dspflg)を用意する.すなわち,常に
398「dspflg == (ipmflg && !disdsp)」に設定する.
399
400dspflgは,カーネルの初期化時にtrueに初期化する.また,タスクコンテキス
401トにおいて割込み優å…
402ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ãŒå¤‰æ›´ã•ã‚Œã‚‹ã‹ï¼Œå‰²è¾¼ã¿ç¦æ­¢ãƒ•ãƒ©ã‚°ãŒå¤‰æ›´
403される度に更新する.非タスクコンテキストでは,常にディスパッチ保留状æ…
404‹
405であるため,このフラグを用いる必
406要はなく,フラグの更新も行わない.
407
408----------------------------------------
409bool_t dspflg;
410----------------------------------------
411
412
413○タスク状æ…
414‹ã®ç®¡ç†ã¨ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒªãƒ³ã‚°
415
416●タスク状æ…
417‹ã®ç®¡ç†
418
419タスク管理ブロック(TCB)中のタスク状æ…
420‹ã‚’管理するフィールド(tstat)で
421は,タスク状æ…
422‹ãŒæ¬¡ã®ã„ずれであるかを管理する.
423
424 ・実行できる状æ…
425‹
426 ・休止状æ…
427‹
428 ・(狭義の)待
429ち状æ…
430‹
431 ・強制待
432ち状æ…
433‹
434 ・二重待
435ち状æ…
436‹
437
438タスクが実行できる状æ…
439‹ã®æ™‚に,実行状æ…
440‹ã§ã‚るか実行可能状æ…
441‹ã§ã‚るかは,
442このフィールドでは管理せず,実行状æ…
443‹ã®ã‚¿ã‚¹ã‚¯ã®TCBを指すポインタ変数
444(p_runtsk)によって判別する.実行状æ…
445‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„場合は,p_runtskは
446NULLにする.
447
448----------------------------------------
449TCB *p_runtsk;
450----------------------------------------
451
452p_runtskは,カーネルの初期化時にNULLに初期化し,ディスパッチャにおいて
453更新する.サービスコールの処理の中で自タスクに関する情
454報を参ç…
455§ã™ã‚‹å ´åˆ
456は,p_runtskを用いる.
457
458●タスクスケジューラ
459
460タスクスケジューラは,実行できる状æ…
461‹ã®ã‚¿ã‚¹ã‚¯ã®ä¸­ã‹ã‚‰ï¼Œæœ€ã‚‚優å…
462ˆé †ä½ãŒé«˜
463いタスク(これを,最高優å…
464ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã¨å‘¼ã¶ï¼‰ã‚’決定し,そのタスクの
465TCBを指すポインタ変数(p_schedtsk)を設定する.
466
467----------------------------------------
468TCB *p_schedtsk;
469----------------------------------------
470
471タスクスケジューラに対しては,どのタスクが実行できる状æ…
472‹ã§ã‚るかを知ら
473せる必
474要がある.そのため,タスクスケジューラは,次の2つの関数を用意する.
475
476 ・タスクが実行できる状æ…
477‹ã«é·ç§»ã—たことを知らせる関数(make_runnable)
478 ・タスクが実行できる状æ…
479‹ã‹ã‚‰ä»–の状æ…
480‹ã¸é·ç§»ã—たことを知らせる関数
481 (make_non_runnable)
482
483また,処理の効率化のために,上の2つの関数を用いずにレディキューを直接操
484作してタスクスケジュールを行う関数として,次の2つの関数を用意する.
485
486 ・タスクの優å…
487ˆåº¦ã®å¤‰æ›´ï¼ˆchange_priority)
488 ・レディキューの回転(rotate_ready_queue)
489
490
491○タスクディスパッチ処理の実装
492
493
494●タスクディスパッチ処理の必
495要なタイミング
496
497タスクディスパッチは,実行状æ…
498‹ã®ã‚¿ã‚¹ã‚¯ï¼ˆp_runtsk)と最高優å…
499ˆé †ä½ã®ã‚¿ã‚¹
500ク(p_schedtsk)が一致しておらず,ディスパッチ保留状æ…
501‹ã§ãªã„場合に行う.
502このことから,タスクディスパッチ処理を行う必
503要があるのは,次の3つの場合
504である.
505
506(1) 実行状æ…
507‹ã®ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ…
508‹ã§ãªããªã‚‹
509
510自タスクを広義の待
511ち状æ…
512‹ã«é·ç§»ã•ã›ã‚‹ã‚µãƒ¼ãƒ“スコールや,自タスクを終了さ
513せるサービスコールにおいて,タスクディスパッチ処理を行う必
514要がある.
515
516(2) 最高優å…
517ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–する
518
519タスクの起動,タスクの待
520ち解除,タスクの強制待
521ちからの再開,タスクの優
522å…
523ˆåº¦ã®å¤‰æ›´ï¼Œã‚¿ã‚¹ã‚¯ã®å„ªå…
524ˆé †ä½ã®å›žè»¢ã‚’行うサービスコールにおいて,最高優
525å…
526ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–し,ディスパッチ保留状æ…
527‹ã§ãªã„場合には,タスクディ
528スパッチ処理を行う必
529要がある.
530
531(3) ディスパッチ保留状æ…
532‹ãŒè§£é™¤ã•ã‚Œã‚‹
533
534ディスパッチ保留状æ…
535‹ã¨ã¯ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ï¼ŒCPUロック状æ…
536‹ï¼Œ
537割込み優å…
538ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
539¨è§£é™¤ã§ãªã„状æ…
540‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ…
541‹ã®ç·ç§°ã§ã‚ã‚‹
542ため,これらの状æ…
543‹ã®ã„ずれかが遷移するタイミングで,タスクディスパッチ
544処理を行う必
545要がある.å…
546·ä½“的には,次のタイミングが該当する.
547
548(3-1) 非タスクコンテキストからタスクコンテキストに遷移する
549
550割込みハンドラまたはCPU例外ハンドラからタスクにリターンする際に,タスク
551ディスパッチ処理を行う必
552要がある.
553
554(3-2) CPUロック状æ…
555‹ãŒè§£é™¤ã•ã‚Œã‚‹
556
557CPUロック状æ…
558‹ã«ãŠã„ては,上記の(1)や(2)の状況を作り出すサービスコールを
559呼び出すことができない.そのため,CPUロック状æ…
560‹ã®è§£é™¤æ™‚には,タスクディ
561スパッチ処理を行う必
562要がない.
563
564(3-3) 割込み優å…
565ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
566¨è§£é™¤ã•ã‚Œã‚‹
567
568割込み優å…
569ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)により割込み優å…
570ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
571¨è§£é™¤ã•ã‚Œ
572る場合に,タスクディスパッチ処理を行う必
573要がある.
574
575また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
576ラからのリターン,割込みサービスルーチンからのリターン,タイムイベント
577ハンドラからのリターン,CPU例外ハンドラからのリターンによって,割込み優
578å…
579ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
580¨è§£é™¤ã•ã‚Œã‚‹å ´åˆãŒã‚り,その場合には,タスクディスパッチ処
581理を行う必
582要がある.ただし,割込みサービスルーチンおよびタイムイベント
583ハンドラからのリターンについては,リターン後も非タスクコンテキストであ
584り,タスクディスパッチ保留状æ…
585‹ãŒç¶™ç¶šã™ã‚‹ã“とから,タスクディスパッチ処
586理を行う必
587要がない.
588
589(3-4) ディスパッチ許可状æ…
590‹ã«ãªã‚‹
591
592ディスパッチの許可(ena_dsp)において,タスクディスパッチ処理を行う必
593要
594がある.
595
596また,タスクの終了とタスク例外処理ルーチンからのリターンによって,ディ
597スパッチ許可状æ…
598‹ã«ãªã‚‹å ´åˆãŒã‚り,その場合には,タスクディスパッチ処理
599を行う必
600要がある.
601
602以上に加えて,カーネルの動作開始時にも,タスクディスパッチ処理を呼び出
603す.
604
605●タスクディスパッチャの構造
606
607タスクディスパッチャの主な機能は,切換え前のタスクのコンテキスト(プロ
608セッサの汎用レジスタ等)をメモリ上に保存し,切換え後のタスクのコンテキ
609ストをメモリ上から復帰することである.ここで,保存/復帰しなければなら
610ないレジスタは,タスクディスパッチャが実行される状況によって,次のよう
611な違いがある.
612
613・タスクが割込み(または,CPU例外)によりプリエンプトされる場合には,す
614 べてのレジスタを保存しなければならない.また,その状æ…
615‹ã‹ã‚‰å®Ÿè¡Œå†é–‹ã™
616 る場合には,すべてのレジスタを復帰しなければならない.
617
618・タスクが自発的にタスクディスパッチャを呼び出す場合には,スクラッチレ
619 ジスタ(caller saved register)以外のレジスタを保存すればよい.また,
620 その状æ…
621‹ã‹ã‚‰å®Ÿè¡Œå†é–‹ã™ã‚‹å ´åˆã«ã¯ï¼Œã‚¹ã‚¯ãƒ©ãƒƒãƒãƒ¬ã‚¸ã‚¹ã‚¿ä»¥å¤–のレジスタを
622 復帰すればよい.
623
624・タスクが終了する場合には,どのレジスタも保存する必
625要がない.
626
627・タスクが実行開始する場合には,どのレジスタも復帰する必
628要がない.
629
630そこで,それぞれの状況で必
631要最低限のレジスタのみを保存/復帰するために,
632タスクディスパッチ処理を,(a) コンテキストの保存処理,(b) 実行するタス
633クの選択処理,(c) コンテキストの復帰処理の3つのステップで構成し,(a)と
634(c)のステップについては,タスクディスパッチャが実行される状況毎に用意す
635る.å…
636·ä½“的には,次の各処理を行うルーチンを用意する.
637
638(a) コンテキストの保存処理
639 (a-1) タスクが自発的に呼び出した場合の保存処理(dispatch)
640 (a-2) 割込みハンドラの出口で呼び出された場合の保存処理(ret_int)
641 (a-3) CPU例外ハンドラの出口で呼び出された場合の保存処理(ret_exc)
642 (a-4) タスクの終了時の処理(exit_and_dispatch)
643 (a-5) カーネルの動作開始時の処理(start_dispatch)
644(b) 実行するタスクの選択(ディスパッチャ本体,dispatcher)
645(c) コンテキストの復帰処理
646 (c-1) タスクが自発的に呼び出した場合の復帰処理(dispatch_r)
647 (c-2) 割込みハンドラの出口で呼び出された場合の復帰処理(ret_int_r)
648 (c-3) CPU例外ハンドラの出口で呼び出された場合の復帰処理(ret_exc_r)
649 (c-4) タスクの実行開始時の処理(start_r)
650
651●タスクの終了時のタスクディスパッチ
652
653ext_tskによるタスクの終了時に,起動要求がキューイングされていると,同じ
654タスクがすぐに起動される.この場合,タスクディスパッチャにとっては,同
655じタスクへの切換えに見え,タスクディスパッチ処理をスキップ可能に思える
656が,実際には,同じタスクの異なるインスタンスへの切換えであるため,タス
657クディスパッチ処理をスキップしてはならない.
658
659上述のタスクディスパッチャの構造により,タスクの終了時には,それ専用の
660処理(exit_and_dispatch)を呼び出す.この処理では,実行状æ…
661‹ã®ã‚¿ã‚¹ã‚¯ã‚’参
662ç…
663§ã›ãšï¼Œã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ä¿å­˜ã‚‚行わずに,次に事項
664するタスクの選択処理を行
665うため,タスクディスパッチ処理がスキップされることはない.
666
667なお,ter_tskによって実行状æ…
668‹ã®ã‚¿ã‚¹ã‚¯ã‚’終了させることはできないため,
669ter_tskではこのような状況は起こらない.
670
671●reqflgの導å…
672¥ç†ç”±
673
674割込みハンドラ/CPU例外ハンドラの出口処理に,タスクディスパッチまたはタ
675スク例外処理ルーチンの実行開始を要求することを示すフラグとして,reqflg
676を用意している.非タスクコンテキストにおいて,タスクディスパッチが必
677要
678になった場合や,タスク例外処理ルーチンの実行開始が必
679要になった場合には,
680このフラグをセットする.
681
682reqflgを導å…
683¥ã—た理由は,割込みハンドラ/CPU例外ハンドラの出口処理のå…
684¸åž‹
685的なケース(タスクディスパッチもタスク例外処理ルーチンの実行開始も必
686要
687ない場合)を高速化するためである.また,ディスパッチャ本体(dispatcher)
688のアイドル処理も高速化できる.
689
690しかし,割込みハンドラ/CPU例外ハンドラの出口処理å…
691¨ä½“のオーバヘッドを考
692えると,reqflgによる高速化の効果はそれほど大きくないものと思われる.
693
694
695○タスク例外処理機能の実装
696
697
698●タスク例外処理ルーチンの実行開始条件とシステム状æ…
699‹ï¼ˆä»•æ§˜ã®ç¢ºèªï¼‰
700
701タスク例外処理ルーチンは,次の6つの条件が揃った場合に実行が開始される.
702
703 ・タスク例外処理許可状æ…
704‹ã§ã‚ã‚‹
705 ・保留例外要因が0でない
706 ・タスクが実行状æ…
707‹ã§ã‚ã‚‹
708 ・タスクコンテキストが実行されている
709 ・割込み優å…
710ˆåº¦ãƒžã‚¹ã‚¯å…
711¨è§£é™¤çŠ¶æ…
712‹ã§ã‚ã‚‹
713 ・CPUロック状æ…
714‹ã§ãªã„
715
716また,タスク例外処理ルーチンの実行開始/リターン時のシステム状æ…
717‹ã«é–¢ã™
718る仕様は次の通りである.
719
720 CPUロック 割込み優å…
721ˆåº¦ ディスパッチ
722 フラグ マスク 禁止フラグ
723------------------------------------------------------------
724【タスク例外処理ルーチン】
725実行開始条件 解除 å…
726¨è§£é™¤ 任意
727実行開始時処理 そのまま そのまま そのまま
728リターン前 原則解除(*1) 原則å…
729¨è§£é™¤(*1) å…
730ƒã«æˆ»ã™
731リターン時処理 解除する å…
732¨è§£é™¤ã™ã‚‹ å…
733ƒã«æˆ»ã™(*4)
734------------------------------------------------------------
735
736●タスク例外処理ルーチンの呼出し処理
737
738タスク例外処理ルーチンを呼び出す処理は,次の流れとなる.この関数は,
739CPUロック状æ…
740‹ã§å‘¼ã³å‡ºã™ã“とを想定している.
741
742----------------------------------------
743void
744call_texrtn(void)
745{
746 TEXPTN texptn;
747
748 texptn = p_runtsk->texptn;
749 p_runtsk->texptn = 0U;
750
751 タスク例外処理禁止状æ…
752‹ã«ã™ã‚‹
753 ディスパッチ禁止フラグを保存する
754
755 CPUロック解除状æ…
756‹ã«ã™ã‚‹
757 タスク例外処理ルーチンを呼び出す
758 CPUロック状æ…
759‹ã«ã™ã‚‹
760
761 割込み優å…
762ˆåº¦ãƒžã‚¹ã‚¯å…
763¨è§£é™¤çŠ¶æ…
764‹ã«ã™ã‚‹
765 ディスパッチ禁止フラグをå…
766ƒã«æˆ»ã™
767 タスク例外処理禁止状æ…
768‹ã«ã™ã‚‹ … (*2)
769
770 必
771要な場合にはディスパッチを行う … (*1)
772
773 タスク例外処理許可状æ…
774‹ã«ã™ã‚‹
775}
776----------------------------------------
777
778(*1)において,必
779要な場合にタスク切換えを行うのは,割込み優å…
780ˆåº¦ãƒžã‚¹ã‚¯ã‚’
781å…
782¨è§£é™¤ã«ã—,ディスパッチ禁止フラグをå…
783ƒã«æˆ»ã—た結果,ディスパッチ保留状
784æ…
785‹ãŒè§£é™¤ã•ã‚Œï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチが必
786要になる場合があるためである.
787
788また,ディスパッチを行う前にタスク例外処理禁止状æ…
789‹ã«ã™ã‚‹(*2)理由につい
790ては,「call_texrtnからdispatchを呼び出す処理について」の節を参ç…
791§ã™ã‚‹ã“
792と.
793
794●タスク例外処理ルーチンの実行開始が必
795要なタイミング
796
797タスク例外処理ルーチンは,前述の6つの条件が揃った場合に実行開始すべきで
798あるため,6つの条件のいずれかを新たに満たすようになる可能性のあるタイミ
799ングで,タスク例外処理ルーチンの実行開始が必
800要になる.
801
802以下では,6つの条件のいずれかを新たに満たすようになるタイミングについて
803検討する.
804
805(1) タスク例外処理許可状æ…
806‹ã§ã‚ã‚‹
807
808タスク例外処理の許可(ena_tex)によって,タスク例外処理許可状æ…
809‹ã«ãªã‚‹ï¼Ž
810また,タスク例外処理ルーチンからのリターンによっても,タスク例外処理許
811可状æ…
812‹ã«ãªã‚‹ï¼Ž
813
814(2) 保留例外要因が0でない
815
816タスク例外処理の要求(ras_tex,iras_tex)によって,タスクの保留例外要因
817が0でなくなる.ただし,非タスクコンテキストからのタスク例外処理の要求
818(iras_tex)では,(4)の条件が満たされないため,タスク例外処理ルーチンの
819実行開始は必
820要ない.
821
822(3) タスクが実行状æ…
823‹ã§ã‚ã‚‹
824
825タスクディスパッチャにより,切換え後のタスクが実行状æ…
826‹ã«ãªã‚‹ï¼Ž
827
828(4) タスクコンテキストが実行されている
829
830割込みハンドラおよびCPU例外ハンドラからのリターンによって,タスクコンテ
831キストに戻る場合がある.
832
833(5) 割込み優å…
834ˆåº¦ãƒžã‚¹ã‚¯å…
835¨è§£é™¤çŠ¶æ…
836‹ã§ã‚ã‚‹
837
838割込み優å…
839ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)によって,割込み優å…
840ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
841¨è§£é™¤
842になる.
843
844また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
845ラからのリターン,CPU例外ハンドラからのリターンによっても,割込み優å…
846ˆåº¦
847マスクがå…
848¨è§£é™¤ã•ã‚Œã‚‹å ´åˆã‚‚ある.
849
850ただし,タスクの終了時については,タスクの終了後は別のタスクへ切り換わ
851るため,切り換わった後のタスクに対するタスク例外処理ルーチンの実行開始
852を,タスクディスパッチ後の処理で行えばよい.
853
854(6) CPUロック状æ…
855‹ã§ãªã„
856
857CPUロック状æ…
858‹ã®è§£é™¤ï¼ˆunl_cpu,iunl_cpu)によって,CPUロック状æ…
859‹ã§ãªããª
860る.ただし,非タスクコンテキストでのCPUロック状æ…
861‹ã®è§£é™¤ï¼ˆiunl_cpu)では,
862(4)の条件が満たされないため,タスク例外処理ルーチンの実行開始は必
863要ない.
864
865また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
866ラからのリターン,割込みサービスルーチンからのリターン,タイムイベント
867ハンドラからのリターン,CPU例外ハンドラからのリターンによって,CPUロッ
868ク状æ…
869‹ã§ãªããªã‚‹å ´åˆã‚‚ある.
870
871ただし,割込みサービスルーチンおよびタイムイベントハンドラからのリター
872ンについては,リターン後も非タスクコンテキストの実行が続き,(4)の条件が
873満たされないため,タスク例外処理ルーチンの実行開始は必
874要ない.
875
876タスクの終了時については,タスクの終了後は別のタスクへ切り換わるため,
877切り換わった後のタスクに対するタスク例外処理ルーチンの実行開始を,タス
878クディスパッチ後の処理で行えばよい.
879
880以上より,重複するケースを考æ…
881®ã™ã‚‹ã¨ï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始
882が必
883要になる可能性があるのは,以下の処理である.
884
885(a) タスク例外処理の許可(ena_tex)… (1)
886(b) タスク例外処理ルーチンの出口処理 … (1)(5)(6)
887(c) タスク例外処理の要求(ras_tex)… (2)
888(d) タスクディスパッチ後の処理 … (3)(5)(6)
889 (d-1) dispatch_r
890 (d-2) ret_int_r
891 (d-3) ret_exc_r
892 (d-4) start_r
893(e) 割込みハンドラの出口処理 … (4)(5)(6)
894(f) CPU例外ハンドラの出口処理 … (4)(5)(6)
895(g) 割込み優å…
896ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)… (5)
897(h) CPUロック状æ…
898‹ã®è§£é™¤ï¼ˆunl_cpu)… (6)
899
900この中で(d-4)に関しては,タスクの実行開始直後はタスク例外処理禁止状æ…
901‹ã§
902あり(自タスクがena_texするまでは,タスク例外が許可されない),(1)の条
903件が満たされないため,タスク例外処理ルーチンの実行開始は必
904要ない.
905
906また(h)に関しては,次に述べる理由により,CPUロック状æ…
907‹ãŒç¶™ç¶šã—ている間
908に他の5つの条件が新たに満たされることはないため,タスク例外処理ルーチン
909の実行開始は必
910要ない.
911
912CPUロック状æ…
913‹ã§ã¯ï¼Œã¾ãšï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理の許可(ena_tex),タスク例外処
914理の要求(ras_tex,iras_tex),割込み優å…
915ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)を行
916うことはできず,タスクディスパッチも起こらない.CPUロック状æ…
917‹ã§ã‚¿ã‚¹ã‚¯ä¾‹
918外処理ルーチンからリターンすることはできるが,この場合はCPUロック状æ…
919‹ã‚‚
920解除され,CPUロック状æ…
921‹ãŒç¶™ç¶šã—ない.CPUロック状æ…
922‹ã§å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰
923リターンした場合も,これと同様である.
924
925最後に,CPUロック状æ…
926‹ã§CPU例外ハンドラからリターンした場合が問題になる.
927これについては,CPU例外が発生した時に,CPUロック状æ…
928‹ã§ã‚った場合と,
929CPUロック解除状æ…
930‹ã§ã‚った場合に分けて考える.CPUロック解除状æ…
931‹ã§ã‚った
932場合には,CPU例外ハンドラからのリターンにより,CPUロック状æ…
933‹ãŒè§£é™¤ã•ã‚Œ
934るため,割込みハンドラからリターンした場合と同様である.CPUロック状æ…
935‹ã§
936あった場合には,起動されるCPU例外ハンドラはカーネル管理外のCPU例外ハン
937ドラであるため,その中で(1)~(3)と(5)の条件が新たに満たされることはない.
938CPU例外ハンドラの実行前後で(4)の条件は保存されることから,CPU例外ハンド
939ラからのリターンによって,(1)~(5)の条件はCPU例外の発生前に戻り,新たに
940満たされることはない.
941
942●タスク例外処理ルーチンの実行開始処理
943
944ここでは,前の節で検討したタスク例外処理ルーチンの実行開始が必
945要なタイ
946ミングのそれぞれについて,実行開始処理の実装
947方法について述べる.
948
949(a) タスク例外処理の許可(ena_tex)
950
951ena_texがタスクから呼び出された場合には,自タスクに対して「タスクが実行
952状æ…
953‹ã§ã‚る」「タスクコンテキストが実行されている」の2条件は満たされてお
954り,「タスク例外処理許可状æ…
955‹ã§ã‚る」の条件はena_texの処理により満たされ
956る.また,「CPUロック状æ…
957‹ã§ãªã„」の条件はena_texのå…
958¥å£ã§ãƒã‚§ãƒƒã‚¯ã—てい
959る.そのため,「保留例外要因が0でない」と「割込み優å…
960ˆåº¦ãƒžã‚¹ã‚¯å…
961¨è§£é™¤çŠ¶æ…
962‹
963である」の2条件が満たされている場合には,タスク例外処理ルーチンを呼び出
964す.
965
966ena_texの本体の処理(エラー処理を除く)は次の通り.
967
968----------------------------------------
969 p_runtsk->enatex = true;
970 if (p_runtsk->texptn != 0U && ipmflg) {
971 call_texrtn();
972 }
973----------------------------------------
974
975(b) タスク例外処理ルーチンの出口処理
976
977タスク例外処理ルーチンの出口処理(call_texrtnの後半)では,自タスクに対
978して「タスクが実行状æ…
979‹ã§ã‚る」「タスクコンテキストが実行されている」の
9802条件は満たされており,「タスク例外処理許可状æ…
981‹ã§ã‚る」「割込み優å…
982ˆåº¦ãƒž
983スクå…
984¨è§£é™¤çŠ¶æ…
985‹ã§ã‚る」「CPUロック状æ…
986‹ã§ãªã„」の3条件が出口処理で満たさ
987れる.そのため,「保留例外要因が0でない」が満たされている場合には,タス
988ク例外処理ルーチンを呼び出す必
989要がある.
990
991ただし,タスク例外処理ルーチンの出口処理で単純にcall_texrtnを呼び出すと,
992call_texrtnの中からcall_texrtnを呼び出すことになり,タスク例外処理が繰
993り返し要求された場合に,スタックの使用量に上限がなくなる.そこで,タス
994ク例外処理ルーチンの出口処理で「保留例外要因が0でない」場合には,
995call_texrtnの中でループさせる.
996
997修正したcall_texrtnの流れは次の通り.
998
999----------------------------------------
1000void
1001call_texrtn(void)
1002{
1003 TEXPTN texptn;
1004
1005 ディスパッチ禁止フラグを保存する … (*3)
1006 タスク例外処理禁止状æ…
1007‹ã«ã™ã‚‹ … (*6)
1008
1009 do {
1010 texptn = p_runtsk->texptn;
1011 p_runtsk->texptn = 0U;
1012
1013 CPUロック解除状æ…
1014‹ã«ã™ã‚‹
1015 タスク例外処理ルーチンを呼び出す
1016 CPUロック状æ…
1017‹ã«ã™ã‚‹
1018
1019 割込み優å…
1020ˆåº¦ãƒžã‚¹ã‚¯å…
1021¨è§£é™¤çŠ¶æ…
1022‹ã«ã™ã‚‹
1023 ディスパッチ禁止フラグをå…
1024ƒã«æˆ»ã™ … (*4)
1025 タスク例外処理禁止状æ…
1026‹ã«ã™ã‚‹ … (*2)
1027
1028 必
1029要な場合にはディスパッチを行う … (*1)
1030 } while (p_runtsk->texptn != 0U);
1031
1032 タスク例外処理許可状æ…
1033‹ã«ã™ã‚‹ … (*5)
1034}
1035----------------------------------------
1036
1037タスク例外処理ルーチンの呼出し前にディスパッチ禁止フラグを保存する処理
1038は,(*4)においてå…
1039ƒã®çŠ¶æ…
1040‹ã«æˆ»ã™ã“とから,ループの外(*3)で行うのが効率が
1041よい.
1042
1043タスク例外処理ルーチンの呼出し前にタスク例外処理禁止状æ…
1044‹ã«ã™ã‚‹å‡¦ç†ã¯ï¼Œ
1045(*2)においてタスク例外処理禁止状æ…
1046‹ã«ã™ã‚‹ã“とから,ループ外(*6)で行うの
1047が効率がよい.また,タスク例外処理ルーチンの呼出し後にタスク例外処理許
1048可状æ…
1049‹ã«ã™ã‚‹å‡¦ç†ã‚‚,ループの外(*5)で行う方が効率がよい.
1050
1051(c) タスク例外処理の要求(ras_tex)
1052
1053ras_texがタスクから呼び出された場合で,対象タスクが自タスクの場合には,
1054自タスクに対して「タスクが実行状æ…
1055‹ã§ã‚る」「タスクコンテキストが実行さ
1056れている」の2条件は満たされており,「保留例外要因が0でない」の条件は
1057ras_texの処理により満たされる(ras_texのパラメータrasptnが0の場合はエラー
1058となるため).また,「CPUロック状æ…
1059‹ã§ãªã„」の条件はras_texのå…
1060¥å£ã§ãƒã‚§ãƒƒ
1061クしている.そのため,対象タスクが自タスクであり,「タスク例外処理許可
1062状æ…
1063‹ã§ã‚る」と「割込み優å…
1064ˆåº¦ãƒžã‚¹ã‚¯å…
1065¨è§£é™¤çŠ¶æ…
1066‹ã§ã‚る」の2条件が満たされて
1067いる場合には,タスク例外処理ルーチンを呼び出す.
1068
1069ras_texの本体の処理(エラー処理を除く)は次の通り.
1070
1071----------------------------------------
1072 p_tcb->texptn |= rasptn;
1073 if (p_tcb == p_runtsk && p_runtsk->enatex && ipmflg) {
1074 call_texrtn();
1075 }
1076----------------------------------------
1077
1078(d-1) dispatch_r
1079
1080dispatch_rにおいては,dispatch_rからのリターンå…
1081ˆã®ã‚¿ã‚¹ã‚¯ã«å¯¾ã—て,「タ
1082スクが実行状æ…
1083‹ã§ã‚る」「タスクコンテキストが実行されている」の2条件は満
1084たされている.また,CPUロック状æ…
1085‹ã§dispatch_rに来ることはないため,
1086「CPUロック状æ…
1087‹ã§ãªã„」の条件も成立している.そのため,「タスク例外処理
1088許可状æ…
1089‹ã§ã‚る」「保留例外要因が0でない」「割込み優å…
1090ˆåº¦ãƒžã‚¹ã‚¯å…
1091¨è§£é™¤çŠ¶æ…
1092‹
1093である」の3条件が満たされている場合には,タスク例外処理ルーチンを呼び出
1094す必
1095要がある.
1096
1097これを実現するために,タスクコンテキストからのディスパッチ処理を次のよ
1098うに修正する.
1099
1100----------------------------------------
1101void
1102dispatch(void)
1103{
1104 ………
1105
1106 dispatch_r:
1107 スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
1108 calltex();
1109}
1110----------------------------------------
1111
1112ここでcalltexは,「タスク例外処理許可状æ…
1113‹ã§ã‚る」「保留例外要因が0でな
1114い」「割込み優å…
1115ˆåº¦ãƒžã‚¹ã‚¯å…
1116¨è§£é™¤çŠ¶æ…
1117‹ã§ã‚る」の3条件が満たされている場合に
1118call_texrtnを呼び出す関数である.
1119
1120----------------------------------------
1121void
1122calltex(void)
1123{
1124 if (p_runtsk->enatex && p_runtsk->texptn != 0U && ipmflg) {
1125 call_texrtn();
1126 }
1127}
1128----------------------------------------
1129
1130(d-2) ret_int_r
1131
1132ret_int_rは,割込みハンドラの出口処理でディスパッチを行ったタスクが,実
1133行を再開する際の処理である.そのため,ret_int_rからのリターンå…
1134ˆã®ã‚¿ã‚¹ã‚¯
1135に対して,「タスクが実行状æ…
1136‹ã§ã‚る」「タスクコンテキストが実行されてい
1137る」の2条件は満たされている.また,CPUロック状æ…
1138‹ã§ret_int_rに来ることは
1139ないため,「CPUロック状æ…
1140‹ã§ãªã„」の条件も成立している.そのため,「タス
1141ク例外処理許可状æ…
1142‹ã§ã‚る」「保留例外要因が0でない」「(割込みハンドラか
1143らのリターン後に)割込み優å…
1144ˆåº¦ãƒžã‚¹ã‚¯å…
1145¨è§£é™¤çŠ¶æ…
1146‹ã§ã‚る」の3条件が満たされ
1147ている場合には,タスク例外処理ルーチンを呼び出す必
1148要がある.
1149
1150これを実現するために,割込みハンドラの出å…
1151¥å£å‡¦ç†ã‚’次のように修正する.
1152
1153----------------------------------------
1154void
1155<割込みの出å…
1156¥å£å‡¦ç†>(void)
1157{
1158 ………
1159
1160 ret_int_r:
1161 スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
1162 calltex();
1163 }
1164 ………
1165}
1166----------------------------------------
1167
1168(d-3) ret_exc_r
1169
1170ret_exc_rは,CPU例外ハンドラの出口処理でディスパッチを行ったタスクが,
1171実行を再開する際の処理である.
1172
1173カーネル管理のCPU例外ハンドラの出口処理(ret_exc)は,割込みハンドラの
1174出口処理(ret_int)と同様である.これは,CPUロック状æ…
1175‹ã§CPU例外が発生し
1176た場合には,カーネル管理外のCPU例外ハンドラとなり,CPU例外ハンドラの出
1177口処理でディスパッチを行うことはなく,ret_excにも来ないためである.その
1178ため,ret_exc_rからのリターンå…
1179ˆã®ã‚¿ã‚¹ã‚¯ã«å¯¾ã—て,「CPUロック状æ…
1180‹ã§ãªã„」
1181の条件が成立している.
1182
1183このことから,CPU例外ハンドラの出å…
1184¥å£å‡¦ç†ã«ã¤ã„ても,割込みハンドラの出
1185å…
1186¥å£å‡¦ç†ã¨åŒæ§˜ã«ï¼Œæ¬¡ã®ã‚ˆã†ã«ä¿®æ­£ã™ã‚Œã°ã‚ˆã„.
1187
1188----------------------------------------
1189void
1190<CPU例外の出å…
1191¥å£å‡¦ç†>(void)
1192{
1193 ………
1194
1195 ret_exc_r:
1196 スクラッチレジスタを除くすべてのレジスタを
1197 スタックから復帰する
1198 calltex();
1199 }
1200 ………
1201}
1202----------------------------------------
1203
1204(e) 割込みハンドラの出口処理
1205
1206割込みハンドラからタスクへリターンする場合には,リターンå…
1207ˆã®ã‚¿ã‚¹ã‚¯ã«å¯¾
1208して,「タスクが実行状æ…
1209‹ã§ã‚る」「タスクコンテキストが実行されている」
1210の2条件は満たされている.また,CPUロック状æ…
1211‹ã§å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ãŒå®Ÿè¡Œã•ã‚Œ
1212ることはないため,「CPUロック状æ…
1213‹ã§ãªã„」の条件も成立している.そのため,
1214「タスク例外処理許可状æ…
1215‹ã§ã‚る」「保留例外要因が0でない」「(割込みハン
1216ドラからのリターン後に)割込み優å…
1217ˆåº¦ãƒžã‚¹ã‚¯å…
1218¨è§£é™¤çŠ¶æ…
1219‹ã§ã‚る」の3条件が満
1220たされている場合には,タスク例外処理ルーチンを呼び出す必
1221要がある.
1222
1223割込みハンドラの呼出し前と呼出し後でこれらの条件が変化するのは,実行状
1224æ…
1225‹ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–した時と,割込みハンドラ中でiras_texが呼び出された場合
1226である.割込みハンドラからはena_texとchg_ipmは呼び出せないため,「タス
1227ク例外処理許可状æ…
1228‹ã§ã‚る」と「(割込みハンドラからのリターン後に)割込
1229み優å…
1230ˆåº¦ãƒžã‚¹ã‚¯å…
1231¨è§£é™¤çŠ¶æ…
1232‹ã§ã‚る」の2条件が変化することはない.
1233
1234この2つの状況の内
1235,実行状æ…
1236‹ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–するケースは,ret_int_rで考æ…
1237®
1238済みである.割込みハンドラ中でiras_texが呼び出された場合には,reqflgが
1239trueになるため,タスク例外処理ルーチンの実行開始処理は,reqflgがtrueの
1240時にのみ行えばよい.
1241
1242これを実現するために,上で修正した割込みハンドラの出å…
1243¥å£å‡¦ç†ã‚’,さらに
1244次のように修正する.
1245
1246----------------------------------------
1247void
1248<割込みの出å…
1249¥å£å‡¦ç†>(void)
1250{
1251 ………
1252
1253 if (タスクコンテキストで割込み発生) {
1254 ………
1255 if (reqflg) {
1256 ………
1257
1258 ret_int_r:
1259 スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
1260 }
1261 calltex();
1262 }
1263 }
1264 ………
1265}
1266----------------------------------------
1267
1268(f) CPU例外ハンドラの出口処理
1269
1270カーネル管理のCPU例外ハンドラの出口処理は,割込みハンドラの出口処理と同
1271様である.
1272
1273カーネル管理外のCPU例外ハンドラの中では,実行状æ…
1274‹ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–すること
1275はなく,iras_texやena_texを呼び出すこともできないため,タスク例外処理ルー
1276チンの実行開始条件が新たに満たされることはなく,タスク例外処理ルーチン
1277の実行開始は必
1278要ない.
1279
1280このことから,CPU例外ハンドラの出å…
1281¥å£å‡¦ç†ã«ã¤ã„ても,割込みハンドラの出
1282å…
1283¥å£å‡¦ç†ã¨åŒæ§˜ã«ï¼Œæ¬¡ã®ã‚ˆã†ã«ä¿®æ­£ã™ã‚Œã°ã‚ˆã„.
1284
1285----------------------------------------
1286void
1287<CPU例外の出å…
1288¥å£å‡¦ç†>(void)
1289{
1290 ………
1291 if (タスクコンテキストでCPU例外発生) {
1292 ………
1293 if (reqflg) {
1294
1295 ret_exc_r:
1296 スクラッチレジスタを除くすべてのレジスタを
1297 スタックから復帰する
1298 }
1299 calltex();
1300 }
1301 }
1302 ………
1303}
1304----------------------------------------
1305
1306(g) 割込み優å…
1307ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´
1308
1309chg_ipmがタスクから呼び出された場合には,自タスクに対して「タスクが実行
1310状æ…
1311‹ã§ã‚る」「タスクコンテキストが実行されている」の2条件は満たされてい
1312る.また,「CPUロック状æ…
1313‹ã§ãªã„」の条件はchg_ipmのå…
1314¥å£ã§ãƒã‚§ãƒƒã‚¯ã—てい
1315る.そのため,パラメータintpriがTIPM_ENAALLであり,「タスク例外処理許可
1316状æ…
1317‹ã§ã‚る」「保留例外要因が0でない」の2条件が満たされている場合には,
1318タスク例外処理ルーチンを呼び出す.
1319
1320chg_ipmの関連部分の処理は次の通り.
1321
1322----------------------------------------
1323 t_set_ipm(intpri);
1324 if (intpri == TIPM_ENAALL) {
1325 ipmflg = true;
1326 ここにタスク切換え処理がå…
1327¥ã‚‹
1328 if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
1329 call_texrtn();
1330 }
1331 }
1332----------------------------------------
1333
1334dispatchを呼び出してタスク切換えを行う場合には,dispatchの出口でタスク
1335例外処理ルーチンを呼び出すためここで呼出し処理を行う必
1336要はないが,コー
1337ドが複雑になるため,dispatchを呼び出した場合もここでタスク例外処理ルー
1338チンの呼出し処理を行っている.
1339
1340●call_texrtnからdispatchを呼び出す処理について
1341
1342dispatch_rから(ターゲットによってはcalltexを経由して)call_texrtnを呼
1343び出し,call_texrtnからdispatchを呼び出すため,この2つの関数は相互再帰
1344呼出しをしている.ここでは,この実装
1345で支障のない理由を説明する.
1346
1347call_texrtnからdispatchを呼び出すのは,ディスパッチが保留されていない状
1348æ…
1349‹ã§å‘¼ã³å‡ºã•ã‚ŒãŸã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンが,その実行中にディスパッチ保留
1350状æ…
1351‹ã«é·ç§»ã—,さらにタスクディスパッチを必
1352要とする処理を行い,ディスパッ
1353チ保留状æ…
1354‹ã‚’解除しないままリターンした場合である.この場合,call_texrtn
1355の中でディスパッチ保留状æ…
1356‹ã‚’解除した後に,dispatchを呼び出してタスクディ
1357スパッチを行う.つまり,call_texrtnからdispatchを呼び出す処理は,タスク
1358例外処理ルーチンの中でディスパッチ保留状æ…
1359‹ã‚’解除すべきであったのを,解
1360除せずにリターンした場合を救済するためのものである.以下,この振舞いを
1361「救済ケース」と呼ぶ.
1362
1363そこで,比較のために,タスク例外処理ルーチンの最後で,正しくディスパッ
1364チ保留状æ…
1365‹ã‚’解除してからリターンした場合の振舞いを考える.この場合には,
1366ディスパッチ保留状æ…
1367‹ã‚’解除するサービスコール(ena_dsp,chg_ipm)の中で,
1368dispatchが呼び出されてタスクディスパッチが起こる.以下,この振舞いを
1369「正常ケース」と呼ぶ.
1370
1371正常ケースと救済ケースを比較すると,call_texrtn→タスク例外処理ルーチン
1372→サービスコール→dispatchの順でdispatchが呼び出されるか,call_texrtnか
1373ら直接dispatchが呼び出されるかの違いということになり,救済ケースの方が
1374スタックの使用量は少ない.つまり,正常ケースの動きを想定してスタック領
1375域が用意してあれば,救済ケースでも問題なく動作することになる.
1376
1377ここで,正常ケースと救済ケースで,上記以外に違いがないことが重要である.
1378å…
1379·ä½“的には,call_texrtnの中で,タスク例外処理許可状æ…
1380‹ã«ã™ã‚‹ï¼ˆp_runtsk
1381->enatexをtrueにする)前に,dispatchを呼び出すことが重要である.タスク
1382例外処理許可状æ…
1383‹ã«ã—た後にdispatchを呼び出すと,出口のdispatch_rで,再
1384びタスク例外処理ルーチンを実行してしまう可能性があり,救済ケースの方が
1385スタックの使用量が増えてしまう.
1386
1387タスク例外処理ルーチンの中で,タスク例外処理許可状æ…
1388‹ã«ã—たままリターン
1389した場合には,call_texrtnから呼び出したdispatchの出口のdispatch_rで再び
1390タスク例外処理ルーチンを実行してしまう可能性がある.この場合も,タスク
1391例外処理ルーチンの最後で,ディスパッチ保留状æ…
1392‹ã‚’解除してからリターンし
1393た場合よりはスタックの使用量が少ないが,タスク例外処理禁止状æ…
1394‹ã«ã—た後
1395にディスパッチ保留状æ…
1396‹ã‚’解除してリターンした場合よりは,スタックの使用
1397量が増える場合がある.そこで,このような状況が起こらないように,
1398dispatchを呼ぶ前にp_runtsk->enatexをfalseにする.
1399
1400
1401○エラーのチェック順序
1402
1403サービスコール内
1404におけるエラーチェックは,以下の順序で行うことを原則と
1405する.なお,この節には,保護機能対応カーネルに関する記述が含まれている
1406が,それらの記述は将来的にはより適切なドキュメントに移動する予定である.
1407
1408●エラーの3分類
1409
1410サービスコールのエラーは,大きく以下の3つに分類することができる.
1411
1412(a) 静的エラー
1413
1414対象のカーネルオブジェクトが登録されているか否かや,その状æ…
1415‹ã«ä¾å­˜ã›ãš
1416に,チェックすることができるエラー.
1417
1418(b) 準静的エラー
1419
1420対象のカーネルオブジェクトが登録されていれば,その状æ…
1421‹ã«ä¾å­˜ã›ãšã«ãƒã‚§ãƒƒ
1422クすることができるエラー.
1423
1424(c) 動的エラー
1425
1426対象のカーネルオブジェクトの状æ…
1427‹ã«ä¾å­˜ã™ã‚‹ã‚¨ãƒ©ãƒ¼ï¼Ž
1428
1429ASPカーネルにおいては,(a)と(b)のエラーはクリティカルセクションの外側で,
1430この順序でチェックし,(c)のエラーはクリティカルセクションの内
1431側でチェッ
1432クする.ただし,動的生成機能拡張パッケージでは,(b)のエラー(の一部)は
1433クリティカルセクションの内
1434側で実施する必
1435要がある.
1436
1437●静的エラーのチェック順序
1438
1439静的エラーには,実行コンテキストのエラー(ディスパッチ保留状æ…
1440‹ã‹ã‚‰ã®å‘¼
1441出しエラーも含む),パラメータの範囲等のエラー(対象のカーネルオブジェ
1442クトに依存せずにチェックできるもの)が含まれる.
1443
1444サービスコール中では,最初に実行コンテキストのエラーをチェックし,その
1445後,パラメータの並び順に,範囲等のエラーをチェックする.
1446
1447保護機能対応カーネルでは,パラメータがポインタである場合に,ポインタの
1448指すメモリ領域がアクセス可能であるかをチェックする必
1449要があるが,メモリ
1450領域の設定が静的である場合には,このエラーチェックもここで実施する.た
1451だし,メモリ領域の設定が静的でない場合には,このエラーチェックはクリティ
1452カルセクションの内
1453側で行う必
1454要がある.
1455
1456●准静的エラーのチェック順序
1457
1458准静的エラーのチェックの前に,対象のカーネルオブジェクトの管理ブロック
1459のå…
1460ˆé ­ç•ªåœ°ã‚’,ローカル変数に代å…
1461¥ã™ã‚‹ï¼Ž
1462
1463保護機能対応カーネルでは,この次に,対象のカーネルオブジェクトがアクセ
1464ス可能であるかをチェックする処理を行う.当該サービスコールの呼出しが,
1465システム状æ…
1466‹ã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚»ã‚¹è¨±å¯ãƒ™ã‚¯ã‚¿ã§ä¿è­·ã•ã‚Œã¦ã„る場合にも,この段
1467階でチェックを実施する.
1468
1469その後で,パラメータの範囲等のエラーの中で,対象のカーネルオブジェクト
1470の登録情
1471報(初期化ブロックに含まれている情
1472報)に依存してチェックすべき
1473もののチェックを,パラメータの並び順で実施する.
1474
1475
1476○CHECKマクロとgoto文の使用
1477
1478ASPカーネルの実装
1479においては,サービスコールの静的なエラーをチェックする
1480ために,名称が"CHECK_"で始まる一連のマクロ(これらを,CHECKマクロと総称
1481する)を用いている.
1482
1483CHECKマクロの定義中にはgoto文を含んでいるが,MISRA-Cなどのコーディング
1484ルールではgoto文の使用を禁止しており,goto文を使うべきではないという意
1485見も多い.また,マクロの定義中にgoto文を使用することが問題であるという
1486意見もある.
1487
1488ここでは,定義中にgoto文を含むCHECKマクロを用いる設計意図とそれを使用し
1489てよい条件,CHECKマクロの使用によりソフトウェアの信頼性に問題が生じるこ
1490とがないことを論証する.
1491
1492なお,ASPカーネルのカーネル本体の実装
1493では,CHECKマクロ以外にgoto文を用
1494いている箇所はない(一部のシステムサービスでは,これ以外の方法でgoto文
1495を用いている).
1496
1497●CHECKマクロの定義とその使用法
1498
1499kernel/check.hには,25個のCHECKマクロが定義されているが,いずれも次のパ
1500ターンで定義されている.ここでXXXXXには,チェックしたいエラーの種類を表
1501す文字列がå…
1502¥ã‚‹ï¼Ž
1503
1504----------------------------------------
1505#define CHECK_XXXXX(<……>) { \
1506 if (<エラー条件>) { \
1507 ercd = <エラーコード>; \
1508 goto error_exit; \
1509 } \
1510}
1511----------------------------------------
1512
1513これらのCHECKマクロは,多くのサービスコールの処理関数中で,次のように使
1514用されている.
1515
1516----------------------------------------
1517ER
1518<サービスコール名>(……)
1519{
1520 <ローカル変数の宣言>
1521 ER ercd;
1522
1523 LOG_XXX_YYY_ENTER(……);
1524 CHECK_XXXXX(……);
1525 CHECK_YYYYY(……);
1526
1527 <サービスコール処理本体>
1528
1529 error_exit:
1530 LOG_XXX_YYY_LEAVE(……);
1531 return(ercd);
1532}
1533----------------------------------------
1534
1535この例では,CHECKマクロを2つ使用しているが,1つのみ使用している場合もあ
1536れば,3つ以上使用している場合もある.また,複数のCHECKマクロの間に,ロー
1537カル変数への代å…
1538¥æ–‡ãŒå…
1539¥ã‚‹å ´åˆã‚‚ある(例えば,ter_tskの処理関数).
1540
1541●設計意図
1542
1543CHECKマクロを使用する意図は,ほとんどのサービスコールで必
1544要な静的エラー
1545のチェックコードをパターン化し,ソースコードの簡潔さを保つことで読みや
1546すさを向上させるとともに,記述ミスの可能性を減らすことである.
1547
1548ちなみに,CHECKマクロを使用しない場合,上に示したサービスコールの処理関
1549数は,次のように記述することになる.
1550
1551----------------------------------------
1552ER
1553<サービスコール名>(……)
1554{
1555 <ローカル変数の宣言>
1556 ER ercd;
1557
1558 LOG_XXX_YYY_ENTER(……);
1559 if (<XXXXXのエラー条件>) {
1560 ercd = <XXXXXのエラーコード>;
1561 }
1562 else {
1563 if (<YYYYYのエラー条件>) {
1564 ercd = <YYYYYのエラーコード>;
1565 }
1566 else {
1567
1568 <サービスコール処理本体>
1569
1570 }
1571 }
1572 LOG_XXX_YYY_LEAVE(……);
1573 return(ercd);
1574}
1575----------------------------------------
1576
1577CHECKマクロの内
1578容を知っているという前提の下では,å…
1579ƒã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®æ–¹ãŒ
1580読みやすいのは明らかである.
1581
1582なお,このようなCHECKマクロの定義には,goto文の使用が不可避である.
1583
1584●CHECKマクロを使用してよい条件
1585
1586CHECKマクロは,次の条件を満たすように使用しなければならない.
1587
1588(1) CHECKマクロは,サービスコール処理関数のå…
1589ˆé ­éƒ¨åˆ†ã§ï¼Œã‚µãƒ¼ãƒ“スコールå…
1590¥
1591  口のログを出した後,クリティカルセクションにå…
1592¥ã‚‹å‰ã¾ã§ã«ï¼Œå‡¦ç†é–¢æ•°
1593  のトップレベルで用いる.
1594
1595(2) サービスコール処理関数の末尾部分で,クリティカルセクションを抜けた
1596  後,サービスコール出口のログを出す前に,処理関数のトップレベルに,
1597  error_exitラベルを置く.
1598
1599●問題を生じることがない根拠
1600
1601このような方法でgoto文を使用しても,ソフトウェアの信頼性に問題が生じる
1602ことがないことを主張するには,そもそも,MISRA-Cなどのコーディングルール
1603でgoto文の使用を禁止している根拠,言い換えると,goto文の使用によりソフ
1604トウェアの信頼性に問題が生じる可能性のある理由を明らかにする必
1605要がある.
1606
1607MISRA-Cのドキュメントでは,goto文の使用を禁止する根拠についてあまり明確
1608になっておらず,ここではその根拠を次のように推測する.
1609
1610・処理の流れが複雑になり,プログラムの意図が読みにくくなる(いわゆる,
1611 スパゲッティプログラムになる).
1612
1613CHECKマクロの場合には,goto文をエラー発生時の強制脱出に用いており,ラベ
1614ルもerror_exitとするなど,プログラムの意図は明らかである.一方,このよ
1615うにgoto文をエラー時の強制脱出に用いる場合には,次の点もgoto文の使用を
1616禁止する根拠になりうる.
1617
1618・goto文で強制脱出することにより,脱出時に行わなければならない後処理が
1619 飛ばされるおそれがある.
1620
1621ただしこの点についても,CHECKマクロを上記の使用条件を満たして使う限りは,
1622脱出時に行わなければならない後処理はなく,CHECKマクロの使用によりソフト
1623ウェアの信頼性に問題が生じることはない.
1624
1625問題を生じることがないことを論証するもう1つ方法は,コーディングルールに
1626合致しないプログラムが,コーディングルールに合致したプログラムと等価で
1627あることを示す方法である.
1628
1629すでに「設計意図」の節で述べたように,CHECKマクロを使用したプログラムは,
1630goto文を使用しない等価なプログラムに書き換えることができるが,より一般
1631的には,次のことが言える.
1632
1633else部を持たないif文のthen部の最後に,if文より下(前方)にあり,if文と
1634同じブロック内
1635の同じ階層のラベルへ分岐するgoto文がある場合には,if文と
1636ラベルの間の文をelse部にすることにより,goto文を使わない等価なプログラ
1637ムに書き換えることができる.
1638
1639例として,goto文を使った次のプログラムを考える.
1640
1641----------------------------------------
1642 {
1643 /* if文の前の文 */
1644 if (....) {
1645 /* then部の文 */
1646 goto <ラベル>;
1647 }
1648 /* if文とラベルの間の文 */
1649 <ラベル>:
1650 /* ラベルより後ろの文 */
1651 }
1652----------------------------------------
1653
1654このプログラムは,goto文を使わない次のプログラムと等価である.
1655
1656----------------------------------------
1657 {
1658 /* if文の前の文 */
1659 if (....) {
1660 /* then部の文 */
1661 }
1662 else {
1663 /* if文とラベルの間の文 */
1664 }
1665 /* ラベルより後ろの文 */
1666 }
1667----------------------------------------
1668
1669この条件に合致するgoto文が複数ある場合には,下にあるgoto文から順に上記
1670の方法によって書き換えることで,goto文を使わない等価なプログラムに書き
1671換えることができる.
1672
1673CHECKマクロの使用方法は,上記のgoto文の使用方法に合致するため,goto文を
1674使用しない等価なプログラムに書き換えることができる.よって,このCHECKマ
1675クロにより問題を生じることはない.
1676
1677
1678○ext_tsk,ext_kerの返り値
1679
1680μITRON4.0仕様では,ext_tskはリターンすることのないサービスコールとなっ
1681ているが,TOPPERS新世代カーネルにおいては,このサービスコールの返り値を
1682ER型に変更し,非タスクコンテキストから呼ばれた場合には,E_CTXエラーを返
1683り値としてリターンすることとする.
1684
1685この仕様に対するいくつかの対案を検討したが,以下の理由で採用しない.
1686
1687・JSPカーネルのように,危険の可能性を検出しながら実行を継続する方法は,
1688 信頼性・安å…
1689¨æ€§ã‚’重視するシステムでは望ましくない.信頼性・安å…
1690¨æ€§ã‚’重
1691 視するシステムでは,危険の可能性を検出したら,早期にリカバリをすべき
1692 である.
1693
1694・ASPカーネルの当初案のカーネルをダウンさせる方法は,アプリケーション側
1695 で回復する余地をなくすという意味で望ましくない.
1696
1697・過去の互換性を保つために,型をvoidとしたまま,非タスクコンテキストか
1698 ら呼ばれた場合にはリターンするとする方法は,カーネルの仕様変更に気づ
1699 きにくくなるという意味で望ましくない.また,他のエラーコード(例えば
1700 E_NOSPT)を返す余地をなくしている.
1701
1702・一種のCPU例外を呼び出すことにする方法は,カーネル仕様å…
1703¨ä½“の整合性を考
1704 えて採用しなかった.ここで一種のCPU例外を導å…
1705¥ã™ã‚‹ã‚ˆã‚Šã‚‚,サービスコー
1706 ルがエラーを返した場合に呼ばれるOSEK/VDX OS仕様のエラーフックに相当す
1707 る機能を導å…
1708¥ã—た方が有用性が高いと思われるためである.
1709
1710この変更により,さらに,CPUロック状æ…
1711‹ã‚„ディスパッチ禁止状æ…
1712‹ã§ext_tskが
1713呼ばれた場合にもエラーリターンする方法が考えられるが,タスクのメインルー
1714チンからのリターンとext_tskが等価にならないため,採用しない.また,他の
1715処理単位からのリターン方法と整合させる意味もある(例えば,割込みハンド
1716ラからCPUロック状æ…
1717‹ã®ã¾ã¾ãƒªã‚¿ãƒ¼ãƒ³ã—た場合の扱い).
1718
1719これにあわせて,ext_kerについても,返り値をER型に変更する.ASPカーネル
1720では,ext_kerがエラーを返すことはないが,HRPカーネルでは,E_OACVエラー
1721を返す場合がある.
1722
1723なお,μITRON4.0仕様では,exd_tskもリターンすることのないサービスコール
1724となっているが,TOPPERS新世代カーネルでは,exd_tskはサポートしていない.
1725
1726
1727○カーネルのデータ構造に対するvolatile宣言について(クリティカルセクショ
1728ンの出å…
1729¥å‡¦ç†ã®å®Ÿç¾ã«é–¢ã™ã‚‹åˆ¶ç´„)
1730
1731カーネル内
1732のデータ構造は,並行実行される他の処理単位(割込みハンドラや
1733タスク)からもアクセスされる可能性があるため,volatile宣言が必
1734要ではな
1735いかと考えられる.実際,クリティカルセクション内
1736でカーネル変数を読むコー
1737ドが,コンパイラの最適化によりクリティカルセクション外に移動され,それ
1738が原因となった問題事例も報告されている.
1739
1740カーネル内
1741のすべてのデータ構造にvolatile宣言をつける方法は,安å…
1742¨ã§ã¯ã‚
1743るが,最適化が抑止されるために,カーネルのサイズや性能には悪影響を与え
1744る.そこでASPカーネルでは,次の方法でvolatile宣言の必
1745要性をなくすことと
1746する.
1747
1748ASPカーネルにおいては,並行実行される他の処理単位から書き換えられる可能
1749性のあるデータ構造は,すべて,CPUロック状æ…
1750‹ã¾ãŸã¯å…
1751¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
1752‹ã«ã‚ˆ
1753るクリティカルセクション内
1754でアクセスしている.クリティカルセクション内
1755
1756でのデータ構造のアクセスが,コンパイラの最適化によりクリティカルセクショ
1757ン外に移動されないようにするには,コンパイラに対して,クリティカルセク
1758ションの出å…
1759¥å‡¦ç†ã«ã‚ˆã‚Šï¼Œãƒ¡ãƒ¢ãƒªä¸Šã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ãŒæ›¸ãå¤‰ã‚ã‚‹å¯èƒ½æ€§ãŒã‚るこ
1760とを知らせればよい.
1761
1762å…
1763·ä½“的には,クリティカルセクションの出å…
1764¥å‡¦ç†ã‚’関数によって実現すれば,
1765このような最適化を抑止することができる.しかし,ASPカーネルの多くのター
1766ゲット依存部において,クリティカルセクションの出å…
1767¥å‡¦ç†ã¯ãƒžã‚¯ãƒ­ã‚„インラ
1768イン関数により実装
1769されており,上のような最適化を抑止できない.
1770
1771そこで,クリティカルセクションの出å…
1772¥å‡¦ç†ã‚’実現する場合には,メモリ上の
1773データ構造が書き変わる可能性があることを,何らかの方法でコンパイラに知
1774らせなければならないという制約を設ける.GNU開発環境では,次のいずれかの
1775方法でこの制約を満たすことができる.
1776
1777(a) クリティカルセクションの出å…
1778¥å‡¦ç†ã®å…
1779¨ä½“または出å…
1780¥å‡¦ç†ã®æœ¬è³ªçš„な部分
1781 (å…
1782·ä½“的には,割込み禁止/許可する処理)を(インラインでない)通常
1783 の関数により実現する.
1784
1785(b) クリティカルセクションの出å…
1786¥å‡¦ç†ã®æœ¬è³ªçš„な部分をインラインアセンブ
1787 ラによって実現している場合には,そのインラインアセンブラのclobber変
1788 数リストに"memory"を追加する.
1789
1790(c) クリティカルセクションの出å…
1791¥å‡¦ç†ã®æœ¬è³ªçš„な部分が,マクロやインライ
1792 ン関数呼出しで実現している場合には,クリティカルセクションにå…
1793¥ã‚‹å‡¦
1794 理の最後と出る処理のå…
1795ˆé ­ã«ï¼ŒAsm("":::"memory")という記述をå…
1796¥ã‚Œã‚‹ï¼Ž
1797
1798なお,この制約が適用されるクリティカルセクションの出å…
1799¥å‡¦ç†ã¯ï¼Œä»¥ä¸‹ã®ã‚‚
1800のである.
1801
1802 SIL_LOC_INT
1803 SIL_UNL_INT
1804 t_lock_cpu, i_lock_cpu, x_lock_cpu
1805 t_unlock_cpu, i_unlock_cpu, x_unlock_cpu
1806
1807
1808○型キャストに伴う警告メッセージ
1809
1810GCCで-O2オプションをつけてコンパイルした場合に,カーネルのソースコード
1811中の数箇所で,次の警告メッセージが出る(GCCのバージョンにもよる).
1812
1813warning: dereferencing type-punned pointer will break strict-aliasing rules
1814
1815これは,GCCに-O2オプションをつけると,コンパイラがC言語のstrict
1816aliasing ruleを前提とするためである.コンパイラにstrict aliasing ruleを
1817適用させないためには,GCCのオプションに-fno-strict-aliasingを指定すれば
1818よい.これにより,警告メッセージは抑止されるが,strict aliasing ruleを
1819前提とした最適化は行われなくなる.
1820
1821ASPカーネルに実装
1822においては,strict aliasing ruleを前提とした最適化を行っ
1823てもよく,この警告メッセージを無視しても差し支えない.以下では,この警
1824告メッセージを無視しても差し支えない理由を述べる.
1825
1826警告メッセージが出る例として,semaphore.c中の次の行について検討する.
1827
1828 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
1829
1830この警告メッセージの原因は,直接的には,&winfo_semを(WINFO_WOBJ *)にキャ
1831ストしていることであるが,本質的な原因は,このコードがC言語のstrict
1832aliasing ruleに従わない代å…
1833¥æ–‡ã®åŽŸå› ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚り,このルールに依存
1834した最適化が誤った結果を引き起こす可能性があることである.
1835
1836C言語のstrict aliasing ruleは,互換性のない異なる型を通して,オーバラッ
1837プするメモリ領域をアクセスする代å…
1838¥æ–‡ã‚’使用してはならないというものであ
1839る(使用した場合の振舞いは未定義になる).このケースでは,(WINFO_SEM
1840*)型のポインタ経由と(WINFO_WOBJ *)型のポインタ経由で,オーバラップする
1841メモリ領域をアクセスする代å…
1842¥æ–‡ã‚’使用してはならないことになる.また,警
1843告メッセージの原因になってはいないが,(SEMCB *)型のポインタ経由と
1844(WOBJCB *)型のポインタ経由で,オーバラップするメモリ領域をアクセスする
1845代å…
1846¥æ–‡ã‚’使用してはならない.
1847
1848ASPカーネルの実装
1849においては,semaphore.c中の関数においては,(SEMCB *)型
1850および(WINFO_SEM *)型のポインタを使用しており,(WOBJCB *)型および
1851(WINFO_WOBJ *)型のポインタ経由でメモリ領域をアクセスすることはない.一
1852方,そこから呼び出されるwait.c中の関数においては,(WOBJCB *)型および
1853(WINFO_WOBJ *)型のポインタを使用しており,(SEMCB *)型および(WINFO_SEM
1854*)型のポインタ経由でメモリ領域をアクセスすることはない.
1855
1856strict aliasing ruleに従わない代å…
1857¥æ–‡ã®å•é¡Œç‚¹ã¯ï¼Œã“のルールに依存した最
1858適化が誤った結果を引き起こす可能性があることであるが,異なるコンパイル
1859単位をまたいで最適化が行われることはないため,これにより問題が起こるこ
1860とはないと言うことができる.
1861
1862同じ議論は,他のソースファイル(eventflag.c,dataqueue.c,pridataq.c,
1863mailbox.c,mempfix.c)中の警告メッセージについても,そのまま当てはまる.
1864
1865
1866○性能評価用システム時刻参ç…
1867§æ©Ÿèƒ½
1868
1869●必
1870要性と使途
1871
1872ASPカーネルには,ASPカーネル上で動作するタスクやASPカーネル自身の性能を
1873計測するために,システム時刻より精度の高い性能評価用システム時刻を読み
1874出す機能をサポートする.性能評価用システム時刻は,マイクロ秒単位で表現
1875されるが,実際の精度はターゲット依存である.
1876
1877この機能を用いてあるプログラムの実行時間を計測するには,その実行直前と
1878実行直後に性能評価用システム時刻を読み出し,その差を求める.そのため,
1879性能評価用システム時刻は常に相対値を使用し,性能評価用システム時刻の絶
1880対値を使用することは想定していない.
1881
1882●API仕様
1883
1884性能評価用システム時刻参ç…
1885§æ©Ÿèƒ½ã§ã¯ï¼Œæ¬¡ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’用いる.
1886
1887 SYSUTM 性能評価用システム時刻(符号無し整数,単位はマイクロ秒,
1888 32ビット以上)
1889
1890SYSUTM型は,ターゲット非依存部においてulong_t型(すなわち,unsigned
1891long型)に定義されており,そのサイズは,32ビット以上で,ターゲット定義
1892である.
1893
1894性能評価用システム時刻がSYSUTM型で表現できる範囲を超
1895えた(つまり,オー
1896バフローした)場合,性能評価用システム時刻は0に戻る.評価対象プログラム
1897の実行前後の性能評価用システム時刻の差を求める場合には,計測する時間が
1898SYSUTM型で表現できる範囲である限り,0に戻ることを特別に考æ…
1899®ã™ã‚‹å¿…
1900要はな
1901い.
1902
1903SYSUTM型が32ビットの場合,性能評価用システム時刻は約71分でオーバフロー
1904する.そのため,この機能を71分を越える時間の測定に使った場合の動作は保
1905証されない.
1906
1907性能評価用システム時刻参ç…
1908§æ©Ÿèƒ½ã®ãŸã‚ã®ã‚µãƒ¼ãƒ“スコールの仕様については,
1909「TOPPERS新世代カーネル統合仕様書」の「4.6.1 システム時刻管理」の節を参
1910ç…
1911§ã™ã‚‹ã“と.
1912
1913●実装
1914
1915
1916時刻をマイクロ秒単位で取得するために,周期的なタイムティックを供給する
1917タイマの現在値(タイマはカウントアップするものと仮定する)を読み出し,
1918それをマイクロ秒単位に換算した値に,現在のシステム時刻(ミリ秒単位で表
1919現される)を1000倍した値を加えたものを性能評価用システム時刻とする.現
1920在のシステム時刻を1000倍する際に,オーバフローが発生する可能性があるが,
1921無視してかまわない.
1922
1923ただし,システム時刻の現在値とタイマの現在値を一貫した状æ…
1924‹ã§èª­ã¿å‡ºã™ã®
1925は容易ではない.両方の値を順に読み出すと,読出しの間にタイマがオーバフ
1926ローして割込み要求が発生した場合に,片方はオーバフロー前の値,もう片方
1927はオーバフロー後の値を読んでしまい,誤った性能評価用システム時刻を取得
1928してしまう.
1929
1930この問題を解決する方法はいくつか考えられるが,どの方法を採用するの決定
1931にあたり,次の要求事項
1932を設定した.
1933
1934(1) 多くのターゲットシステムで実現できること.
1935
1936(2) サービスコールの実行時間が可能な限り一定となること.言い換えると,
1937 条件によってサービスコールの実行時間が大きく変動しないこと.
1938
1939(3) サービスコール中の可能な限り同じタイミングの時刻を返すこと.言い換
1940 えると,条件によって時刻を読み取るタイミングが変動しないこと.
1941
1942(4) 調整する必
1943要のあるパラメータを最小限とすること.
1944
1945これらの要求事項
1946を満たす方法として,次の方法を用いることにした.
1947
1948まず,NMIを除くすべての割込みを禁止した状æ…
1949‹ã§ï¼Œã‚·ã‚¹ãƒ†ãƒ æ™‚刻の現在値,タ
1950イマの現在値(1回目),タイマ割込み要求の有無,タイマの現在値(2回目)
1951を,この順で読み出す.割込みを禁止しているため,この間にシステム時刻の
1952現在値が変化することはなく,システム時刻の現在値を読み出す順番はどこで
1953もよい.また,タイマの現在値の2回目の読出しは,タイマ割込み要求があった
1954場合にのみ必
1955要となるが,(2)の要求から,タイマ割込み要求の有無によらず読
1956み出すこととする.
1957
1958これらの値を読み出した後,割込み禁止を解除し,次の処理を行う.まず,タ
1959イマ割込み要求がなかった場合には,システム時刻の現在値と,1回目に読んだ
1960タイマの現在値は一貫した値であることが保証できるため,これらの値から性
1961能評価用システム時刻の現在値を求める.
1962
1963次にタイマ割込み要求があった場合には,1回目に読んだタイマの現在値が,タ
1964イマ割込み要求発生前の値(オーバフロー前の値)である場合と,発生後の値
1965(オーバフロー後の値)である場合の両方の可能性が考えられる.このどちら
1966の場合であったかを,2回目に読んだタイマの現在値を使って,次のように決定
1967する.2回目の値は,タイマ割込み要求発生後の値(オーバフロー後の値)であ
1968ることが保証できるため,1回目の値が2回目の値よりも大きい場合には,その
1969間にオーバフローがあったものと推測できる.つまり,1回目の値はオーバフロー
1970前の値ということになり,システム時刻の現在値と一貫した値であるとして性
1971能評価用システム時刻の現在値を求める.逆に,1回目の値が2回目の値と同じ
1972かそれより小さい場合には,1回目の値はオーバフロー後の値であると推測でき
1973る.この場合には,次のタイムティックのシステム時刻を求め,その値と1回目
1974の値が一貫した値であるとして性能評価用システム時刻の現在値を求める.
1975
1976ここで,タイマ割込み要求があった場合には,2回目に読んだタイマの現在値を
1977用いる方法が考えられるが,(3)の要求を満たさなくなるために採用しなかった.
1978また,JSPカーネルと同様の方法は,(4)の要求を満たさないために採用しなかっ
1979た.
1980
1981上で「推測できる」としたのは,この推測が成り立たなくなるケースがあるた
1982めである.この推測が成り立たなくなるケースは,次の2つの場合に分けて分析
1983することができる.
1984
1985(a) 1回目の値がオーバフロー後の値であるにもかかわらず,1回目の値が2回目
1986 の値よりも大きくなる場合
1987
1988このようなケースは,タイマ割込みが要求されているにもかかわらずサービス
1989されない状æ…
1990‹ãŒé•·æ™‚間続くか,タイマの現在値を1回目に読んでから2回目に読
1991むまでの間に長い時間がかかった結果,その間に(再度)オーバフローが発生
1992した場合に起こる.つまり,タイマ割込みがサービスされない時間が,タイム
1993ティックの周期よりも長くなった場合である.このような場合には,システム
1994時刻の更新も正しく行われなくなる.
1995
1996(b) 1回目の値がオーバフロー前の値であるにもかかわらず,1回目の値が2回目
1997 の値と同じかそれよりも小さくなる場合
1998
1999このようなケースは,タイマの現在値を1回目に読んでから2回目に読むまでの
2000間に,タイマがほぼ1周分カウントアップした場合に起こる.この場合も,タイ
2001マ割込みが禁止されている時間が,タイムティックの周期よりも長かったこと
2002になり,システム時刻の更新が正しく行えなくなる.
2003
2004いずれのケースも,タイマ割込みが長時間禁止されている,タイマ割込みより
2005も優å…
2006ˆåº¦ã®é«˜ã„割込み処理が長時間続けて実行された,シミュレーション環境
2007においてシミュレータのプロセスが長時間スケジュールされなかったなどの理
2008由で,システム時刻の更新が正しく行えない状況に相当する.そこでこの状況
2009を,サービスコール使用上の注意事項
2010に盛り込む.
2011
2012実際のコードにおいては,システム時刻の現在値は変数に保持されていないた
2013め(上位桁はcurrent_timeに保持されているが,下位桁を保持する変数がな
2014い),次のタイムティックのシステム時刻を用いて計算している.そのため,
2015タイマの現在値がオーバフロー後の値であると判断した場合を除いては,タイ
2016ムティックの周期時間を,求めた性能評価用システム時刻から減算する.この
2017処理により,サービスコールの実行時間が変動することになるが,if文の内
2018容
2019が(コンパイラの最適化を仮定すると)定数値の減算1回なので,変動はわずか
2020である.
2021
2022このサービスコールは,任意の状æ…
2023‹ã‹ã‚‰å‘¼ã³å‡ºã™ã“とができるため,SILのå…
2024¨å‰²
2025込みロック機能を用いて,サービスコール内
2026部のクリティカルセクションを実
2027現する.
2028
2029
2030○タスク例外処理禁止フラグをenatexで実装
2031している理由
2032
2033タスク例外処理禁止フラグは,TCB中のenatexフィールド(タスク例外処理許可
2034状æ…
2035‹ã§ã‚ることを示す)の形で保持している.このフィールドをdistexとせず
2036enatexとしたのは,JSPカーネルにおいてタスクディスパッチ禁止フラグを
2037enadspの形で保持したのと整合させたためである.
2038
2039ASPカーネルでは,enadspはdisdspに変更になったことから,enatexもdistexに
2040変更した方が良かったと思われる.
2041
2042以上
Note: See TracBrowser for help on using the repository browser.