source: asp3_wo_tecs/trunk/doc/design.txt@ 302

Last change on this file since 302 was 302, checked in by ertl-honda, 7 years ago

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

File size: 55.8 KB
Line 
1
2 TOPPERS/ASP3カーネル
3 設計メモ
4
5 対応バージョン: Release 3.B.0
6 最終更新: 2016年1月3日
7
8このドキュメントは,TOPPERS/ASP3カーネルの設計メモである.作成途中のも
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-2016 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 480 2016-01-03 07:37:12Z ertl-hiro $
65----------------------------------------------------------------------
66
67○目次
68
69・TOPPERS/ASP3カーネルの実装
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 - ディスパッチャ本体とアイドル処理
105・xsns_dpnの実装
106
107 - カーネル管理外の状æ…
108‹ã«é–¢ã™ã‚‹è€ƒå¯Ÿ
109 - xsns_dpnの実装
110
111・エラーのチェック順序
112 - エラーの3分類
113 - 静的エラーのチェック順序
114 - 準静的エラーのチェック順序
115・CHECKマクロとgoto文の使用
116 - CHECKマクロの定義とその使用法
117 - 設計意図
118 - CHECKマクロを使用してよい条件
119 - 問題を生じることがない根拠
120・カーネルのデータ構造に対するvolatile宣言について
121・型キャストに伴う警告メッセージ
122・kernel_cfg.hへの依存関係の扱い
123
124
125○TOPPERS/ASP3カーネルの実装
126設計方針
127
128TOPPERS/ASP3カーネル(以下,ASP3カーネル)は,TOPPERS第3世代カーネル
129(ITRON系)の基盤となるリアルタイムカーネルである.TOPPERS第3世代カーネ
130ル仕様(ITRON系)の設計方針と,ASP3カーネルの適用対象領域と設計方針につ
131いては,TOPPERS第3世代カーネル(ITRON系)統合仕様書に述べられている.
132
133以下では,ASP3カーネルの実装
134設計方針について述べるが,仕様設計方針とも
135関連しており,明確に分離できない部分もある.
136
137TOPPERS/ASP3カーネルの実装
138設計を行うにあたり,次の方針を設定する.
139
140(1) ソースコードの読みやすさ・改造しやすさを重視する【ASPR0001】
141
142ソースコードが読みやすいことは,オープンソースソフトウェアの品質を向上
143させる上で最も重要な特性である.ソースコードを理解している技術者
144が増え
145ることで,問題を早期に発見することができ,サポート体制もå…
146…
147実させること
148ができる.また,ソースコードが読みやすいことは,シンプルな設計がされて
149いることも意味しており,信頼性向上にもつながる.さらに,技術者
150教育のた
151めの教材とする観点からも,ソースコードが読みやすいことは重要となる.
152
153改造しやすいことは,システム毎の要求にあわせたチューニングが行いやすい
154ことを意味しており,すり合わせ型の開発を支援する性質である.また,ASP3
155カーネルを基盤として一連のTOPPERS第3世代カーネル(ITRON系)を開発してい
156く上でも,改造しやすいことは必
157須の条件である.
158
159(2) 新しいターゲットシステムへのポーティングが容易な構造とする
160
161組込みシステムには多様なハードウェアが用いられるため,それらに容易にポー
162ティングできることは重要な性質である.そのために,実行性能にé…
163æ…
164®ã—つつ
165ハードウェアを抽象化し,ターゲットシステムに依存する部分(ターゲット依
166存部)と依存しない部分(ターゲット非依存部)を明確に分離する【ASPR0002】.
167また,開発環境(コンパイラなど)に依存する部分も明確に分離する【ASPR0003】.
168
169(3) 検証が容易な構造とする
170
171信頼性を確保するために,検証が容易な構造とする.
172
173å…
174·ä½“的には,サービスコールのほとんどå…
175¨ä½“を割込み禁止で実行することとし,
176サービスコールの処理途中で割込みを許可しない【ASPR0004】.この構造は,
177読みやすく改造しやすいソースコードにするためにも有効である.これにより
178割込み応答性が犠牲になるが,それによって問題を生じるアプリケーションは
179少数であり,やむをえないものと考える.
180
181また,条件コンパイル等によりコンフィギュレーションできる箇所を増やすと,
182細かな最適化ができる一方で,検証すべき組合せが増えることから,コンフィ
183ギュレーションできる箇所は必
184要最低限とする【ASPR0005】.
185
186(4) 実行性能とメモリ使用量にé…
187æ…
188®ã™ã‚‹
189
190上記の方針を満たした上で,高い実行性能と小さいメモリ使用量を達成できる
191ような実装
192を行う【ASPR0006】.実行性能を向上させる際には,平均性能の向
193上よりも,最悪時性能の向上を重視する.
194
195ソースコードの読みやすさを重視すると言っても,実行性能の悪いアルゴリズ
196ムを安易に採用することはせず,高い実行性能を達成できるアルゴリズムを用
197いる【ASPR0007】.ただし,新しいターゲットシステムへのポーティングを容
198易にするために大部分をC言語で実装
199しており,すべてをアセンブリ言語で記述
200した場合に比べて実行性能が落ちるのはやむをえない.
201
202メモリ使用量については,RAMの使用量を削減することに重点を置いた設計を行
203うが,上記の方針および実行性能とのトレードオフを考æ…
204®ã—,ぎりぎりまでの
205削減は行わない【ASPR0008】.
206
207(5) スケーラビリティにé…
208æ…
209®ã™ã‚‹
210
211様々
212な規模のシステムに適用できるスケーラビリティをもった構造とする.特
213に,小規模なシステムに適用する際に,使用しない機能をカーネルが持ってい
214ることによるメモリ使用量の増加が最小限になるようにé…
215æ…
216®ã™ã‚‹ï¼Ž
217
218å…
219·ä½“的には,アプリケーションとカーネルを1つのロードモジュールにリンクす
220る方法(1リンクモデル)を想定し,カーネルを関数単位でライブラリ化して,
221使用する関数のみをリンクできる構造とする【ASPR0009】.これは一種のコン
222フィギュレーションであるが,この方法は,条件コンパイルによるコンフィギュ
223レーションとは違い,検証工数に与える影響が小さい.
224
225また,固定的に使用するRAM領域を減らし,スタックに置ける情
226報はできる限り
227スタック上に置く【ASPR0010】.
228
229(6) タイムティックを用いない時間管理(ティックレスカーネル)
230
231消費エネルギー削減のため,不必
232要なタイミングでプロセッサを動作させない
233ことが求められる.å…
234·ä½“的には,処理すべきタイムイベントがない時に,タイ
235マ割込みがかからないような実装
236とする【ASPR0011】.
237
238
239○システム状æ…
240‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£…
241
242
243この章では,「TOPPERS第3世代カーネル(ITRON系)統合仕様書」の「2.5 シス
244テム状æ…
245‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã€ã®ç¯€ã«è¦å®šã•ã‚Œã¦ã„るシステム状æ…
246‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆ
247の実装
248方法について記述する.
249
250●カーネル動作状æ…
251‹ã¨éžå‹•ä½œçŠ¶æ…
252‹ï¼»NGKI0143ï¼½
253
254カーネルの動作状æ…
255‹ã‚’管理するために,カーネル動作状æ…
256‹ãƒ•ãƒ©ã‚°ï¼ˆkerflg)を
257用意する.kerflgは,スタートアップモジュールでfalse(=0)に初期化する.
258また,カーネル動作の開始時にtrueにし,カーネル動作の終了時にfalseにする.
259
260----------------------------------------
261bool_t kerflg = false;
262----------------------------------------
263
264kerflgは,sns_kerで参ç…
265§ã™ã‚‹ï¼Žã‚«ãƒ¼ãƒãƒ«éžå‹•ä½œçŠ¶æ…
266‹ã§sns_ker以外のサービス
267コールを呼び出した場合の動作は保証する必
268要がないため,他のサービスコー
269ルではkerflgを参ç…
270§ã—ない[NGKI0146].
271
272●タスクコンテキストと非タスクコンテキスト[NGKI0148]
273
274タスクコンテキストと非タスクコンテキストの切換えは,ターゲットハードウェ
275アおよびターゲット依存部に委ねる.また,どちらのコンテキストで実行中で
276あるかを判別する関数(sense_context)も,ターゲット依存部で用意すること
277とする.
278
279●å…
280¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
281‹ã¨å…
282¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
283‹
284
285å…
286¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯ãƒ•ãƒ©ã‚°ã®ç®¡ç†ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ね,å…
287¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
288‹
289に遷移させるマクロ(SIL_LOC_INT)と,å…
290ƒã®çŠ¶æ…
291‹ã«æˆ»ã™ãƒžã‚¯ãƒ­ï¼ˆSIL_UNL_INT)
292は,SILのターゲット依存部で用意することとする.å…
293¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
294‹ã§ã‚ã‚‹
295か否かを判別する機能は,必
296要がないために用意していない.
297
298å…
299¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
300‹ã§sns_kerとext_ker以外のサービスコールを呼び出した場
301合の動作は保証する必
302要がないため,サービスコール中でå…
303¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
304‹
305であることを判別する必
306要はない.
307
308●CPUロック状æ…
309‹ã¨CPUロック解除状æ…
310‹
311
312CPUロックフラグの管理はターゲット依存部に委ね,CPUロック状æ…
313‹ã«é·ç§»ã•ã›
314る関数(lock_cpu)と,CPUロック解除状æ…
315‹ã«é·ç§»ã•ã›ã‚‹é–¢æ•°ï¼ˆunlock_cpu)は,
316ターゲット依存部で用意することとする.また,CPUロック状æ…
317‹ã§ã‚るか否かを
318判別する関数(sense_lock)も,ターゲット依存部で用意することとする.
319
320●割込み優å…
321ˆåº¦ãƒžã‚¹ã‚¯
322
323割込み優å…
324ˆåº¦ãƒžã‚¹ã‚¯ã®ç®¡ç†ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ね,タスクコンテキストか
325ら割込み優å…
326ˆåº¦ãƒžã‚¹ã‚¯ã‚’設定する関数(t_set_ipm)と,それを参ç…
327§ã™ã‚‹é–¢æ•°
328(t_get_ipm)は,ターゲット依存部で用意することとする.
329
330●ディスパッチ禁止状æ…
331‹ã¨ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ…
332‹ï¼»NGKI0177ï¼½
333
334ディスパッチ禁止フラグを管理するために,それを反転したフラグ(ensdsp)
335を用意する.enadspは,カーネルの初期化時にtrueに初期化する.
336
337----------------------------------------
338bool_t enadsp;
339----------------------------------------
340
341●ディスパッチ保留状æ…
342‹
343
344ディスパッチ保留状æ…
345‹ã¯ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ï¼ŒCPUロック状æ…
346‹ï¼Œå‰²
347込み優å…
348ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
349¨è§£é™¤ã§ãªã„状æ…
350‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ…
351‹ã®ã„ずれか(ま
352たは,それらが重なった状æ…
353‹ï¼‰ã§ã‚る.
354
355ディスパッチ保留状æ…
356‹ã§ãªã„こと(つまり,ディスパッチできる状æ…
357‹ã§ã‚るこ
358と)を効率的に判別するために,割込み優å…
359ˆåº¦ãƒžã‚¹ã‚¯å…
360¨è§£é™¤çŠ¶æ…
361‹ã§ã‚り,ディ
362スパッチ許可状æ…
363‹ã§ã‚る(ディスパッチ禁止状æ…
364‹ã§ãªã„)ことを示すフラグ
365(dspflg)を用意する.すなわち,常に以下の関係が成り立つようにする.
366
367 dspflg == ((t_get_ipm() == TIPM_ENAALL) && enadsp)
368
369dspflgは,カーネルの初期化時にtrueに初期化する.また,タスクコンテキス
370トにおいて割込み優å…
371ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ãŒå¤‰æ›´ã•ã‚Œã‚‹ã‹ï¼Œå‰²è¾¼ã¿ç¦æ­¢ãƒ•ãƒ©ã‚°ãŒå¤‰æ›´
372される度に更新する.
373
374----------------------------------------
375bool_t dspflg;
376----------------------------------------
377
378
379○タスク状æ…
380‹ã®ç®¡ç†ã¨ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒªãƒ³ã‚°
381
382●タスク状æ…
383‹ã®ç®¡ç†
384
385タスク管理ブロック(TCB)中のタスク状æ…
386‹ã‚’管理するフィールド(tstat)で
387は,タスク状æ…
388‹ãŒæ¬¡ã®ã„ずれであるかを管理する.
389
390 ・実行できる状æ…
391‹
392 ・休止状æ…
393‹
394 ・(狭義の)待
395ち状æ…
396‹
397 ・強制待
398ち状æ…
399‹
400 ・二重待
401ち状æ…
402‹
403
404また,タスクが(狭義の)待
405ち状æ…
406‹ã¨äºŒé‡å¾…
407ち状æ…
408‹ã®æ™‚には,同じフィールド
409で待
410ち要因も管理する.
411
412タスクが実行できる状æ…
413‹ã®æ™‚に,実行状æ…
414‹ã§ã‚るか実行可能状æ…
415‹ã§ã‚るかは,
416このフィールドでは管理せず,実行状æ…
417‹ã®ã‚¿ã‚¹ã‚¯ã®TCBを指すポインタ変数
418(p_runtsk)によって判別する.実行状æ…
419‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„場合は,p_runtskは
420NULLにする.
421
422----------------------------------------
423TCB *p_runtsk;
424----------------------------------------
425
426p_runtskは,カーネルの初期化時にNULLに初期化し,ディスパッチャにおいて
427更新する.サービスコールの処理の中で自タスクに関する情
428報を参ç…
429§ã™ã‚‹å ´åˆ
430は,p_runtskを用いる.
431
432●タスクスケジューラ
433
434タスクスケジューラは,実行できる状æ…
435‹ã®ã‚¿ã‚¹ã‚¯ã®ä¸­ã‹ã‚‰ï¼Œå®Ÿè¡Œã™ã¹ãã‚¿ã‚¹ã‚¯
436を決定し,そのタスクのTCBを指すポインタ変数(p_schedtsk)を設定する.実
437行できる状æ…
438‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„場合は,p_schedtskはNULLにする.
439
440----------------------------------------
441TCB *p_schedtsk;
442----------------------------------------
443
444p_runtskは,通常はp_schedtskと一致しているが,非タスクコンテキスト実行
445中は,一致しているとは限らない.割込み優å…
446ˆåº¦ãƒžã‚¹ã‚¯å…
447¨è§£é™¤ã§ãªã„状æ…
448‹ã®é–“
449とディスパッチ禁止状æ…
450‹ã®é–“(すなわち,dspflgがtrueである間)は,
451p_schedtskを更新しない.
452
453タスクスケジューラに対しては,どのタスクが実行できる状æ…
454‹ã§ã‚るかを知ら
455せる必
456要がある.そのため,タスクスケジューラは,次の2つの関数を用意する.
457
458 ・タスクが実行できる状æ…
459‹ã«é·ç§»ã—たことを知らせる関数(make_runnable)
460 ・タスクが実行できる状æ…
461‹ã‹ã‚‰ä»–の状æ…
462‹ã¸é·ç§»ã—たことを知らせる関数
463 (make_non_runnable)
464
465また,処理の効率化のために,上の2つの関数を用いずにレディキューを直接操
466作してタスクスケジュールを行う関数として,次の2つの関数を用意する.
467
468 ・タスクの優å…
469ˆåº¦ã®å¤‰æ›´ï¼ˆchange_priority)
470 ・レディキューの回転(rotate_ready_queue)
471
472
473○タスクディスパッチ処理の実装
474
475
476●タスクディスパッチ処理の必
477要なタイミング
478
479タスクディスパッチは,実行状æ…
480‹ã®ã‚¿ã‚¹ã‚¯ï¼ˆp_runtsk)と最高優å…
481ˆé †ä½ã®ã‚¿ã‚¹
482ク(p_schedtsk)が一致しておらず,ディスパッチ保留状æ…
483‹ã§ãªã„場合に行う.
484このことから,タスクディスパッチ処理を行う必
485要があるのは,次の3つの場合
486である.
487
488(1) 実行状æ…
489‹ã®ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ…
490‹ã§ãªããªã‚‹
491
492自タスクを広義の待
493ち状æ…
494‹ã«é·ç§»ã•ã›ã‚‹ã‚µãƒ¼ãƒ“スコールや,自タスクを終了さ
495せるサービスコールにおいて,タスクディスパッチ処理を行う必
496要がある.
497
498(2) 最高優å…
499ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–する
500
501タスクの起動,タスクの待
502ち解除,タスクの強制待
503ちからの再開,タスクの優
504å…
505ˆåº¦ã®å¤‰æ›´ï¼Œã‚¿ã‚¹ã‚¯ã®å„ªå…
506ˆé †ä½ã®å›žè»¢ã‚’行うサービスコールにおいて,最高優
507å…
508ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–し,ディスパッチ保留状æ…
509‹ã§ãªã„場合には,タスクディ
510スパッチ処理を行う必
511要がある.
512
513(3) ディスパッチ保留状æ…
514‹ãŒè§£é™¤ã•ã‚Œã‚‹
515
516ディスパッチ保留状æ…
517‹ã¨ã¯ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ï¼ŒCPUロック状æ…
518‹ï¼Œ
519割込み優å…
520ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
521¨è§£é™¤ã§ãªã„状æ…
522‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ…
523‹ã®ç·ç§°ã§ã‚ã‚‹
524ため,これらの状æ…
525‹ã®ã„ずれかが遷移するタイミングで,タスクディスパッチ
526処理を行う必
527要がある.å…
528·ä½“的には,次のタイミングが該当する.
529
530(3-1) 非タスクコンテキストからタスクコンテキストに遷移する
531
532割込みハンドラまたはCPU例外ハンドラからタスクにリターンする際に,タスク
533ディスパッチ処理を行う必
534要がある.
535
536(3-2) CPUロック状æ…
537‹ãŒè§£é™¤ã•ã‚Œã‚‹
538
539CPUロック状æ…
540‹ã«ãŠã„ては,上記の(1)や(2)の状況を作り出すサービスコールを
541呼び出すことができない.そのため,CPUロック状æ…
542‹ã®è§£é™¤æ™‚には,タスクディ
543スパッチ処理を行う必
544要がない.
545
546(3-3) 割込み優å…
547ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
548¨è§£é™¤ã•ã‚Œã‚‹
549
550割込み優å…
551ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)により割込み優å…
552ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
553¨è§£é™¤ã•ã‚Œ
554る場合に,タスクディスパッチ処理を行う必
555要がある.
556
557また,タスクの終了,割込みハンドラからのリターン,CPU例外ハンドラからの
558リターンによって,割込み優å…
559ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
560¨è§£é™¤ã•ã‚Œã‚‹å ´åˆãŒã‚り,その場合
561には,タスクディスパッチ処理を行う必
562要がある.
563
564(3-4) ディスパッチ許可状æ…
565‹ã«ãªã‚‹
566
567ディスパッチの許可(ena_dsp)において,タスクディスパッチ処理を行う必
568要
569がある.
570
571また,タスクの終了によって,ディスパッチ許可状æ…
572‹ã«ãªã‚‹å ´åˆãŒã‚り,その
573場合には,タスクディスパッチ処理を行う必
574要がある.
575
576以上に加えて,カーネルの動作開始時にも,タスクディスパッチ処理を呼び出
577す.
578
579●タスクディスパッチャの構造
580
581タスクディスパッチャの主な機能は,切換え前のタスクのコンテキスト(プロ
582セッサの汎用レジスタ等)をメモリ上に保存し,切換え後のタスクのコンテキ
583ストをメモリ上から復帰することである.ここで,保存/復帰しなければなら
584ないレジスタは,タスクディスパッチャが実行される状況によって,次のよう
585な違いがある.
586
587・タスクが割込み(または,CPU例外)によりプリエンプトされる場合には,す
588 べてのレジスタを保存しなければならない.また,その状æ…
589‹ã‹ã‚‰å®Ÿè¡Œå†é–‹ã™
590 る場合には,すべてのレジスタを復帰しなければならない.
591
592・タスクが自発的にタスクディスパッチャを呼び出す場合には,スクラッチレ
593 ジスタ(caller saved register)以外のレジスタを保存すればよい.また,
594 その状æ…
595‹ã‹ã‚‰å®Ÿè¡Œå†é–‹ã™ã‚‹å ´åˆã«ã¯ï¼Œã‚¹ã‚¯ãƒ©ãƒƒãƒãƒ¬ã‚¸ã‚¹ã‚¿ä»¥å¤–のレジスタを
596 復帰すればよい.
597
598・タスクが終了する場合には,どのレジスタも保存する必
599要がない.
600
601・タスクが実行開始する場合には,どのレジスタも復帰する必
602要がない.
603
604そこで,それぞれの状況で必
605要最低限のレジスタのみを保存/復帰するために,
606タスクディスパッチ処理を,(a) コンテキストの保存処理,(b) 実行するタス
607クの選択処理,(c) コンテキストの復帰処理の3つのステップで構成し,(a)と
608(c)のステップについては,タスクディスパッチャが実行される状況毎に用意す
609る.å…
610·ä½“的には,次の各処理を行うルーチンを用意する.
611
612(a) コンテキストの保存処理
613 (a-1) タスクが自発的に呼び出した場合の保存処理(dispatch)
614 (a-2) 割込みハンドラの出口で呼び出された場合の保存処理(ret_int)
615 (a-3) CPU例外ハンドラの出口で呼び出された場合の保存処理(ret_exc)
616 (a-4) タスクの終了時の処理(exit_and_dispatch)
617 (a-5) カーネルの動作開始時の処理(start_dispatch)
618(b) 実行するタスクの選択(ディスパッチャ本体,dispatcher)
619(c) コンテキストの復帰処理
620 (c-1) タスクが自発的に呼び出した場合の復帰処理(dispatch_r)
621 (c-2) 割込みハンドラの出口で呼び出された場合の復帰処理(ret_int_r)
622 (c-3) CPU例外ハンドラの出口で呼び出された場合の復帰処理(ret_exc_r)
623 (c-4) タスクの実行開始時の処理(start_r)
624
625●タスクの終了時のタスクディスパッチ
626
627ext_tskによるタスクの終了時に,起動要求がキューイングされていると,同じ
628タスクがすぐに起動される場合がある.この場合,タスクディスパッチャにとっ
629ては,同じタスクへの切換えに見え,タスクディスパッチ処理をスキップ可能
630に思えるが,実際には,同じタスクの異なるインスタンスへの切換えであるた
631め,タスクディスパッチ処理をスキップしてはならない.
632
633上述のタスクディスパッチャの構造により,タスクの終了時には,それ専用の
634処理(exit_and_dispatch)を呼び出す.この処理では,実行状æ…
635‹ã®ã‚¿ã‚¹ã‚¯ã‚’参
636ç…
637§ã›ãšï¼Œã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ä¿å­˜ã‚‚行わずに,次に実行するタスクの選択処理を行
638うため,タスクディスパッチ処理がスキップされることはない.
639
640ena_terおよびchg_ipmによるタスクの終了時も,これと同様である.
641
642なお,他タスクからタスクを終了させるサービスコール(ras_ter,ter_tsk)
643では,実行状æ…
644‹ã®ã‚¿ã‚¹ã‚¯ã‚’終了させることはできないため,このような状況は
645起こらない.
646
647●ディスパッチャ本体とアイドル処理
648
649タスクディスパッチャでは,コンテキストの保存処理を行った後,ディスパッ
650チャ本体へ分岐する.
651
652ディスパッチャ本体では,まず,p_schedtskをp_runtskに代å…
653¥ã™ã‚‹ï¼Žp_runtsk
654がNULLでない場合は,p_runtsk(ディスパッチå…
655ˆã®ã‚¿ã‚¹ã‚¯ï¼‰ã®TCBからスタック
656ポインタを復帰し,TCBに保存されている実行再開番地に分岐する.分岐å…
657ˆã«ãŠ
658いて,コンテキストの復帰処理を行う.
659
660p_runtskがNULLになるのは,実行できる状æ…
661‹ã®ã‚¿ã‚¹ã‚¯ãŒãªããªã£ãŸå ´åˆã§ã‚る.
662実行できる状æ…
663‹ã®ã‚¿ã‚¹ã‚¯ãŒãªããªã‚‹ã®ã¯ï¼Œå®Ÿè¡ŒçŠ¶æ…
664‹ã®ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ…
665‹
666でなくなり,他に実行できる状æ…
667‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„場合に限られる.この場合,
668スケジューラがp_schedtskをNULLに設定し,タスクディスパッチャが実行され
669る.
670
671実行できる状æ…
672‹ã®ã‚¿ã‚¹ã‚¯ãŒãªããªã£ãŸå ´åˆã®å‡¦ç†ã‚’,アイドル処理と呼ぶ.ア
673イドル処理では,CPUロック状æ…
674‹ã‚’解除して,割込みの発生を待
675つ.割込みが発
676生し,いずれかのタスクが実行できる状æ…
677‹ã«ãªã£ãŸå ´åˆã«ã¯ï¼Œå‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©
678の出口処理でタスクディスパッチが行われ,ディスパッチャ本体には戻らない.
679割込みによっていずれのタスクも実行できる状æ…
680‹ã«ãªã‚‰ãªã‹ã£ãŸå ´åˆã«ã¯ï¼Œãƒ‡ã‚£
681スパッチャ本体に戻り,再度割込みの発生を待
682つ.
683
684アイドル処理をこのように実装
685すると,割込みハンドラの出口処理(ret_int)
686からタスクディスパッチャが呼び出された場合に,p_runtskがNULLになってい
687る可能性がある.そのため,割込みハンドラの出口で呼び出された場合のコン
688テキストの保存処理の際に,p_runtskがNULLであるかチェックし,NULLの場合
689にはコンテキストの保存を行わないようにする必
690要がある.
691
692アイドル処理は,最後に実行状æ…
693‹ã§ã‚ったタスクのスタック領域を用いて実行
694される.ここで,以下の2つの課題が生じる.
695
6961つめの課題は,カーネルの動作開始時には,「最後に実行状æ…
697‹ã§ã‚ったタスク」
698が存在しないことである.カーネルの初期化処理が,それ専用のスタック領域
699を用いて実行されていた場合には,アイドル処理をそのまま実行しても差し支
700えないが,非タスクコンテキスト用のスタック領域を用いて実行されていた場
701合には,他のスタック領域に切り換える必
702要がある(アイドル処理を非タスク
703コンテキスト用のスタック領域で実行すると,アイドル処理中に受け付けた割
704込み処理で,スタックが破壊される可能性がある).そこで,そのような場合
705には,カーネルの動作開始時の処理(start_dispatch)において,スタックを,
706IDが1のタスクのスタック領域に切り換えることにする.カーネルの動作開始直
707後にアイドル処理が実行される時には,すべてのタスクが休止状æ…
708‹ã«ãªã£ã¦ã„
709るため,どのタスクのスタック領域も使われておらず,アイドル処理で使用し
710て差し支えない.ASP3カーネルでは,少なくとも1つのタスクを生成する必
711要が
712あることから,IDが1のタスクは必
713ず存在する.
714
715もう1つの課題は,「最後に実行状æ…
716‹ã§ã‚ったタスクのスタック領域」が解放さ
717れる可能性である.タスクのスタック領域が解放されるのは,タスクが削除さ
718れた場合であるため,ASP3カーネルで問題になるのは,動的生成機能拡張パッ
719ケージを用いた場合のみである.ASP3カーネルでは,割込みハンドラからタス
720クを削除するサービスコール(del_tsk)を呼び出すことができず,タスクの終
721了と同時にタスクを削除するサービスコール(exd_tsk)もサポートしていない
722ことから,タスクを削除するのは他のタスクからであり,削除されたタスクが
723「最後に実行状æ…
724‹ã§ã‚ったタスク」になっていることはない.以上より,「最
725後に実行状æ…
726‹ã§ã‚ったタスクのスタック領域」が解放されている可能性はない.
727
728上のアイドル処理中で割込みの発生を待
729っている間は,タスクコンテキストで
730CPUロック解除状æ…
731‹ã§ã‚るにもかかわらず,p_runtskがNULLになっている.この
732状況は,通常はアプリケーションから観測できないが,ここで(ハードウェア
733故
734障などの理由で)CPU例外が発生すると,アプリケーションから観測されてし
735まう.å…
736·ä½“的には,xsns_dpnがfalseを返すにもかかわらず,get_tidが
737TSK_NONEが返ってしまう.この状況を防ぐために,p_runtskがNULLの場合には,
738xsns_dpnがtrueを返すようにする.
739
740このような措置を行うと,CPU例外ハンドラが規則通りに実装
741されていれば,
742CPU例外ハンドラの出口処理ではp_runtskがNULLになる状況はないはずであるが,
743安å…
744¨ã®ãŸã‚ã«ï¼Œp_runtskがNULLの場合にはコンテキストの保存を行わないよう
745にする.
746
747
748○xsns_dpnの実装
749設計
750
751●カーネル管理外の状æ…
752‹ã«é–¢ã™ã‚‹è€ƒå¯Ÿ
753
754カーネル管理外の状æ…
755‹ã¨ã¯ï¼Œä»¥ä¸‹ã®3状æ…
756‹ã®ç·ç§°ã§ã‚る.
757
758 (1) å…
759¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
760‹
761 (2) カーネル管理外の割込みハンドラ実行中
762 (3) カーネル管理外のCPU例外ハンドラ実行中
763
764カーネル管理外のCPU例外ハンドラとは,以下のいずれかで発生したCPU例外に
765よって起動されたCPU例外ハンドラのことを言う.
766
767 (3-1) カーネル非動作状æ…
768‹
769 (3-2) カーネル内
770のクリティカルセクションの実行中
771 (3-3) å…
772¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
773‹
774 (3-4) CPUロック状æ…
775‹
776 (3-5) カーネル管理外の割込みハンドラ実行中
777 (3-6) カーネル管理外のCPU例外ハンドラ実行中
778
779統合仕様書には,カーネル管理外の状æ…
780‹ã§ã¯ï¼Œå°‘なくとも,カーネル管理の割
781込みはマスクされている[NGKI0545]としているが,これは次の理由による.
782
783まず,(1)については,å…
784¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
785‹ã§ã¯NMIを除くすべての割込みがマ
786スクされるため[NGKI0160],カーネル管理の割込みがマスクされているのは
787明らかである.
788
789(2)については,カーネル管理の割込みの優å…
790ˆåº¦ãŒTMIN_INTPRIと同じかそれよ
791りも低いのに対して,カーネル管理外の割込みの優å…
792ˆåº¦ã¯TMIN_INTPRIよりも高
793いため,カーネル管理外の割込みハンドラ実行中は,カーネル管理の割込みは
794マスクされていることになる.
795
796(3)については,CPU例外ハンドラの起動によって割込みのマスク状æ…
797‹ã¯å¤‰åŒ–し
798ないため,CPU例外が発生した時の状æ…
799‹ã«ã¤ã„て考察すればよい.
800
801カーネル非動作状æ…
802‹(3-1)では,原則として,NMIを除くすべての割込みがマス
803クされる[NGKI0144]ため,カーネル管理の割込みはマスクされている.
804
805カーネル内
806のクリティカルセクション(3-2)は,カーネル管理の割込みのマスク
807により実現していることから,明らかである.
808
809CPUロック状æ…
810‹(3-4)では,すべてのカーネル管理の割込みがマスクされる
811[NGKI0167]ことから,条件を満たしている.
812
813残る(3-3)(3-5)(3-6)については,カーネル管理外の状æ…
814‹ã§ç™ºç”Ÿã—たCPU例外に
815より起動されたCPU例外ハンドラは,カーネル管理外の状æ…
816‹ã§ã‚ることを意味し
817ており,帰納的に説明することができる.
818
819以上により,カーネル管理外の状æ…
820‹ã§ã¯ï¼Œå°‘なくとも,カーネル管理の割込み
821はマスクされている[NGKI0545]ことがわかる.ただし,(3-1)については,
822「原則として」というフレーズがあるため,この原則が守られない場合は例外
823となる.
824
825●xsns_dpnの実装
826
827
828xsns_dpnは,実行中のCPU例外ハンドラの起動原因となったCPU例外が,以下の
8293条件を満たす場合にfalse,そうでない場合にtrueを返す[NGKI3151].
830
831 (a) カーネル管理外のCPU例外でない
832 (b) タスクコンテキストで発生
833 (c) CPU例外が発生した時の状æ…
834‹ãŒãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ…
835‹ã§ãªã„
836
837さらに,「アイドル処理」の節で述べた通り,p_runtskがNULLの場合には,
838xsns_dpnがtrueを返すようにする必
839要がある.つまり,上の3条件に次の条件を
840加えた4条件が満たす場合にfalseを返す.
841
842 (d) p_runtskがNULLでない
843
844カーネル管理外のCPU例外とは,以下のいずれかで発生したCPU例外のことを言
845う.
846
847 (a-1) カーネル非動作状æ…
848‹
849 (a-2) カーネル内
850のクリティカルセクションの実行中(カーネル実行中)
851 (a-3) å…
852¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
853‹
854 (a-4) CPUロック状æ…
855‹
856 (a-5) カーネル管理外の割込みハンドラ実行中
857 (a-6) カーネル管理外のCPU例外ハンドラ実行中
858
859また,ディスパッチ保留状æ…
860‹ã¨ã¯ï¼Œä»¥ä¸‹ã®ã„ずれかの場合を言う.
861
862 (c-1) 非タスクコンテキストの実行中
863 (c-2) CPUロック状æ…
864‹
865 (c-3) 割込み優å…
866ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
867¨è§£é™¤ã§ãªã„状æ…
868‹
869 (c-4) ディスパッチ禁止状æ…
870‹
871
872xsns_dpnでは,これらの条件をすべてチェックする必
873要がある.
874
875これらの条件の中で,まず,(b)と(c-1),(a-4)と(c-2)は重複している.また,
876(a-1)はkerflg,(c-4)はenadsp,(d)はp_runtskを参ç…
877§ã™ã‚‹ã“とで,ターゲット
878非依存部で判定することができる.残りの条件は,ターゲット依存部で用意す
879る関数exc_sense_intmaskにより判定する.
880
881すなわち,exc_sense_intmaskは,CPU例外が発生した時のシステム状æ…
882‹ãŒï¼Œä»¥
883下の条件をすべて満たす場合にtrue,そうでない場合にfalseを返すものとする.
884
885 (a-2) カーネル内
886のクリティカルセクションの実行中でない
887 (a-3) å…
888¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
889‹ã§ãªã„
890 (a-4) CPUロック状æ…
891‹ã§ãªã„
892 (a-5) カーネル管理外の割込みハンドラ実行中でない
893 (a-6) カーネル管理外のCPU例外ハンドラ実行中でない
894 (b) タスクコンテキスト
895 (c-3) 割込み優å…
896ˆåº¦ãƒžã‚¹ã‚¯ãŒå…
897¨è§£é™¤
898
899上で考察した通り,(a-2)〜(a-6)では,(少なくとも)カーネル管理の割込み
900がマスクされている.そこで,多くの場合,カーネル管理の割込みがすべてマ
901スクされていることをチェックすることで,(a-2)〜(a-6)の判定を一括して行
902うことができる.また,割込み優å…
903ˆåº¦ãƒžã‚¹ã‚¯ã‚’実現しているハードウェアレジ
904スタをチェックすることで,(a-2)〜(a-6)と(c-3)の判定を一括して行える場合
905も多い.
906
907なお,カーネル管理の割込みがすべてマスクされていることをチェックするこ
908とで,(a-1)の条件も判定できるため,ターゲット非依存部でkerflgをチェック
909する必
910要はないことになるが,カーネル非動作状æ…
911‹ã§NMIを除くすべての割込み
912がマスクされるのは「原則として」であるため,kerflgもチェックした方が安
913å…
914¨ã§ã‚る.
915
916また,カーネル管理の割込みがすべてマスクされていることをチェックすると,
917dis_intにより,すべてのカーネル管理の割込みを個別にマスクした場合にも
918xsns_dpnがtrueを返してしまう可能性がある.このようにならないことが望ま
919しいが,カーネル管理の割込みすべてをdis_intで個別にマスクする状況は稀で
920あると考えられるため,このような状況でxsns_dpnがtrueを返すこと(つまり,
921リカバリが行えないこと)を,ターゲット定義の制限としても差し支えない.
922
923
924○エラーのチェック順序
925
926サービスコール内
927におけるエラーチェックは,以下の順序で行うことを原則と
928する.なお,この節には,保護機能対応カーネルに関する記述が含まれている
929が,それらの記述は将来的にはより適切なドキュメントに移動する予定である.
930
931●エラーの3分類
932
933サービスコールのエラーは,大きく以下の3つに分類することができる.
934
935(a) 静的エラー
936
937対象のカーネルオブジェクトが登録されているか否かや,その状æ…
938‹ã«ä¾å­˜ã›ãš
939に,チェックすることができるエラー.
940
941(b) 準静的エラー
942
943対象のカーネルオブジェクトが登録されていれば,その状æ…
944‹ã«ä¾å­˜ã›ãšã«ãƒã‚§ãƒƒ
945クすることができるエラー.
946
947(c) 動的エラー
948
949対象のカーネルオブジェクトの状æ…
950‹ã«ä¾å­˜ã™ã‚‹ã‚¨ãƒ©ãƒ¼ï¼Ž
951
952ASPカーネルにおいては,(a)と(b)のエラーはクリティカルセクションの外側で,
953この順序でチェックし,(c)のエラーはクリティカルセクションの内
954側でチェッ
955クする.ただし,動的生成機能拡張パッケージでは,(b)のエラー(の一部)は
956クリティカルセクションの内
957側で実施する必
958要がある.
959
960●静的エラーのチェック順序
961
962静的エラーには,実行コンテキストのエラー(ディスパッチ保留状æ…
963‹ã‹ã‚‰ã®å‘¼
964出しエラーも含む),パラメータの範囲等のエラー(対象のカーネルオブジェ
965クトに依存せずにチェックできるもの)が含まれる.
966
967サービスコール中では,最初に実行コンテキストのエラーをチェックし,その
968後,パラメータの並び順に,範囲等のエラーをチェックする.
969
970保護機能対応カーネルでは,パラメータがポインタである場合に,ポインタの
971指すメモリ領域がアクセス可能であるかをチェックする必
972要があるが,メモリ
973領域の設定が静的である場合には,このエラーチェックもここで実施する.た
974だし,メモリ領域の設定が静的でない場合には,このエラーチェックはクリティ
975カルセクションの内
976側で行う必
977要がある.
978
979●准静的エラーのチェック順序
980
981准静的エラーのチェックの前に,対象のカーネルオブジェクトの管理ブロック
982のå…
983ˆé ­ç•ªåœ°ã‚’,ローカル変数に代å…
984¥ã™ã‚‹ï¼Ž
985
986保護機能対応カーネルでは,この次に,対象のカーネルオブジェクトがアクセ
987ス可能であるかをチェックする処理を行う.当該サービスコールの呼出しが,
988システム状æ…
989‹ã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚»ã‚¹è¨±å¯ãƒ™ã‚¯ã‚¿ã§ä¿è­·ã•ã‚Œã¦ã„る場合にも,この段
990階でチェックを実施する.
991
992その後で,パラメータの範囲等のエラーの中で,対象のカーネルオブジェクト
993の登録情
994報(初期化ブロックに含まれている情
995報)に依存してチェックすべき
996もののチェックを,パラメータの並び順で実施する.
997
998
999○CHECKマクロとgoto文の使用
1000
1001ASP3カーネルの実装
1002においては,サービスコールの静的なエラーをチェックする
1003ために,名称が"CHECK_"で始まる一連のマクロ(これらを,CHECKマクロと総称
1004する)を用いている.
1005
1006CHECKマクロの定義中にはgoto文を含んでいるが,MISRA-Cなどのコーディング
1007ルールではgoto文の使用を禁止しており,goto文を使うべきではないという意
1008見も多い.また,マクロの定義中にgoto文を使用することが問題であるという
1009意見もある.
1010
1011ここでは,定義中にgoto文を含むCHECKマクロを用いる設計意図とそれを使用し
1012てよい条件,CHECKマクロの使用によりソフトウェアの信頼性に問題が生じるこ
1013とがないことを論証する.
1014
1015なお,ASP3カーネルのカーネル本体の実装
1016では,CHECKマクロ以外にgoto文を用
1017いている箇所はない(一部のシステムサービスでは,これ以外の方法でgoto文
1018を用いている).
1019
1020●CHECKマクロの定義とその使用法
1021
1022kernel/check.hには,25個のCHECKマクロが定義されているが,いずれも次のパ
1023ターンで定義されている.ここでXXXXXには,チェックしたいエラーの種類を表
1024す文字列がå…
1025¥ã‚‹ï¼Ž
1026
1027----------------------------------------
1028#define CHECK_XXXXX(<……>) { \
1029 if (<エラー条件>) { \
1030 ercd = <エラーコード>; \
1031 goto error_exit; \
1032 } \
1033}
1034----------------------------------------
1035
1036これらのCHECKマクロは,多くのサービスコールの処理関数中で,次のように使
1037用されている.
1038
1039----------------------------------------
1040ER
1041<サービスコール名>(……)
1042{
1043 <ローカル変数の宣言>
1044 ER ercd;
1045
1046 LOG_XXX_YYY_ENTER(……);
1047 CHECK_XXXXX(……);
1048 CHECK_YYYYY(……);
1049
1050 <サービスコール処理本体>
1051
1052 error_exit:
1053 LOG_XXX_YYY_LEAVE(……);
1054 return(ercd);
1055}
1056----------------------------------------
1057
1058この例では,CHECKマクロを2つ使用しているが,1つのみ使用している場合もあ
1059れば,3つ以上使用している場合もある.また,複数のCHECKマクロの間に,ロー
1060カル変数への代å…
1061¥æ–‡ãŒå…
1062¥ã‚‹å ´åˆã‚‚ある(例えば,ter_tskの処理関数).
1063
1064●設計意図
1065
1066CHECKマクロを使用する意図は,ほとんどのサービスコールで必
1067要な静的エラー
1068のチェックコードをパターン化し,ソースコードの簡潔さを保つことで読みや
1069すさを向上させるとともに,記述ミスの可能性を減らすことである.
1070
1071ちなみに,CHECKマクロを使用しない場合,上に示したサービスコールの処理関
1072数は,次のように記述することになる.
1073
1074----------------------------------------
1075ER
1076<サービスコール名>(……)
1077{
1078 <ローカル変数の宣言>
1079 ER ercd;
1080
1081 LOG_XXX_YYY_ENTER(……);
1082 if (<XXXXXのエラー条件>) {
1083 ercd = <XXXXXのエラーコード>;
1084 }
1085 else {
1086 if (<YYYYYのエラー条件>) {
1087 ercd = <YYYYYのエラーコード>;
1088 }
1089 else {
1090
1091 <サービスコール処理本体>
1092
1093 }
1094 }
1095 LOG_XXX_YYY_LEAVE(……);
1096 return(ercd);
1097}
1098----------------------------------------
1099
1100CHECKマクロの内
1101容を知っているという前提の下では,å…
1102ƒã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®æ–¹ãŒ
1103読みやすいのは明らかである.
1104
1105なお,このようなCHECKマクロの定義には,goto文の使用が不可避である.
1106
1107●CHECKマクロを使用してよい条件
1108
1109CHECKマクロは,次の条件を満たすように使用しなければならない.
1110
1111(1) CHECKマクロは,サービスコール処理関数のå…
1112ˆé ­éƒ¨åˆ†ã§ï¼Œã‚µãƒ¼ãƒ“スコールå…
1113¥
1114  口のログを出した後,クリティカルセクションにå…
1115¥ã‚‹å‰ã¾ã§ã«ï¼Œå‡¦ç†é–¢æ•°
1116  のトップレベルで用いる.
1117
1118(2) サービスコール処理関数の末尾部分で,クリティカルセクションを抜けた
1119  後,サービスコール出口のログを出す前に,処理関数のトップレベルに,
1120  error_exitラベルを置く.
1121
1122●問題を生じることがない根拠
1123
1124このような方法でgoto文を使用しても,ソフトウェアの信頼性に問題が生じる
1125ことがないことを主張するには,そもそも,MISRA-Cなどのコーディングルール
1126でgoto文の使用を禁止している根拠,言い換えると,goto文の使用によりソフ
1127トウェアの信頼性に問題が生じる可能性のある理由を明らかにする必
1128要がある.
1129
1130MISRA-Cのドキュメントでは,goto文の使用を禁止する根拠についてあまり明確
1131になっておらず,ここではその根拠を次のように推測する.
1132
1133・処理の流れが複雑になり,プログラムの意図が読みにくくなる(いわゆる,
1134 スパゲッティプログラムになる).
1135
1136CHECKマクロの場合には,goto文をエラー発生時の強制脱出に用いており,ラベ
1137ルもerror_exitとするなど,プログラムの意図は明らかである.一方,このよ
1138うにgoto文をエラー時の強制脱出に用いる場合には,次の点もgoto文の使用を
1139禁止する根拠になりうる.
1140
1141・goto文で強制脱出することにより,脱出時に行わなければならない後処理が
1142 飛ばされるおそれがある.
1143
1144ただしこの点についても,CHECKマクロを上記の使用条件を満たして使う限りは,
1145脱出時に行わなければならない後処理はなく,CHECKマクロの使用によりソフト
1146ウェアの信頼性に問題が生じることはない.
1147
1148問題を生じることがないことを論証するもう1つ方法は,コーディングルールに
1149合致しないプログラムが,コーディングルールに合致したプログラムと等価で
1150あることを示す方法である.
1151
1152すでに「設計意図」の節で述べたように,CHECKマクロを使用したプログラムは,
1153goto文を使用しない等価なプログラムに書き換えることができるが,より一般
1154的には,次のことが言える.
1155
1156else部を持たないif文のthen部の最後に,if文より下(前方)にあり,if文と
1157同じブロック内
1158の同じ階層のラベルへ分岐するgoto文がある場合には,if文と
1159ラベルの間の文をelse部にすることにより,goto文を使わない等価なプログラ
1160ムに書き換えることができる.
1161
1162例として,goto文を使った次のプログラムを考える.
1163
1164----------------------------------------
1165 {
1166 /* if文の前の文 */
1167 if (....) {
1168 /* then部の文 */
1169 goto <ラベル>;
1170 }
1171 /* if文とラベルの間の文 */
1172 <ラベル>:
1173 /* ラベルより後ろの文 */
1174 }
1175----------------------------------------
1176
1177このプログラムは,goto文を使わない次のプログラムと等価である.
1178
1179----------------------------------------
1180 {
1181 /* if文の前の文 */
1182 if (....) {
1183 /* then部の文 */
1184 }
1185 else {
1186 /* if文とラベルの間の文 */
1187 }
1188 /* ラベルより後ろの文 */
1189 }
1190----------------------------------------
1191
1192この条件に合致するgoto文が複数ある場合には,下にあるgoto文から順に上記
1193の方法によって書き換えることで,goto文を使わない等価なプログラムに書き
1194換えることができる.
1195
1196CHECKマクロの使用方法は,上記のgoto文の使用方法に合致するため,goto文を
1197使用しない等価なプログラムに書き換えることができる.よって,このCHECKマ
1198クロにより問題を生じることはない.
1199
1200
1201○カーネルのデータ構造に対するvolatile宣言について(クリティカルセクショ
1202ンの出å…
1203¥å‡¦ç†ã®å®Ÿç¾ã«é–¢ã™ã‚‹åˆ¶ç´„)
1204
1205カーネル内
1206のデータ構造は,並行実行される他の処理単位(割込みハンドラや
1207タスク)からもアクセスされる可能性があるため,volatile宣言が必
1208要ではな
1209いかと考えられる.実際,クリティカルセクション内
1210でカーネル変数を読むコー
1211ドが,コンパイラの最適化によりクリティカルセクション外に移動され,それ
1212が原因となった問題事例も報告されている.
1213
1214カーネル内
1215のすべてのデータ構造にvolatile宣言をつける方法は,安å…
1216¨ã§ã¯ã‚
1217るが,最適化が抑止されるために,カーネルのサイズや性能には悪影響を与え
1218る.そこでASP3カーネルでは,次の方法でvolatile宣言の必
1219要性をなくすことと
1220する.
1221
1222ASP3カーネルにおいては,並行実行される他の処理単位から書き換えられる可能
1223性のあるデータ構造は,すべて,CPUロック状æ…
1224‹ã¾ãŸã¯å…
1225¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
1226‹ã«ã‚ˆ
1227るクリティカルセクション内
1228でアクセスしている.クリティカルセクション内
1229
1230でのデータ構造のアクセスが,コンパイラの最適化によりクリティカルセクショ
1231ン外に移動されないようにするには,コンパイラに対して,クリティカルセク
1232ションの出å…
1233¥å‡¦ç†ã«ã‚ˆã‚Šï¼Œãƒ¡ãƒ¢ãƒªä¸Šã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ãŒæ›¸ãå¤‰ã‚ã‚‹å¯èƒ½æ€§ãŒã‚るこ
1234とを知らせればよい.
1235
1236å…
1237·ä½“的には,クリティカルセクションの出å…
1238¥å‡¦ç†ã‚’関数によって実現すれば,
1239このような最適化を抑止することができる.しかし,ASP3カーネルの多くのター
1240ゲット依存部において,クリティカルセクションの出å…
1241¥å‡¦ç†ã¯ãƒžã‚¯ãƒ­ã‚„インラ
1242イン関数により実装
1243されており,上のような最適化を抑止できない.
1244
1245そこで,クリティカルセクションの出å…
1246¥å‡¦ç†ã‚’実現する場合には,メモリ上の
1247データ構造が書き変わる可能性があることを,何らかの方法でコンパイラに知
1248らせなければならないという制約を設ける.GNU開発環境では,次のいずれかの
1249方法でこの制約を満たすことができる.
1250
1251(a) クリティカルセクションの出å…
1252¥å‡¦ç†ã®å…
1253¨ä½“または出å…
1254¥å‡¦ç†ã®æœ¬è³ªçš„な部分
1255 (å…
1256·ä½“的には,割込み禁止/許可する処理)を(インラインでない)通常
1257 の関数により実現する.
1258
1259(b) クリティカルセクションの出å…
1260¥å‡¦ç†ã®æœ¬è³ªçš„な部分をインラインアセンブ
1261 ラによって実現している場合には,そのインラインアセンブラのclobber変
1262 数リストに"memory"を追加する.
1263
1264(c) クリティカルセクションの出å…
1265¥å‡¦ç†ã®æœ¬è³ªçš„な部分が,マクロやインライ
1266 ン関数呼出しで実現している場合には,クリティカルセクションにå…
1267¥ã‚‹å‡¦
1268 理の最後と出る処理のå…
1269ˆé ­ã«ï¼ŒAsm("":::"memory")という記述をå…
1270¥ã‚Œã‚‹ï¼Ž
1271
1272なお,この制約が適用されるクリティカルセクションの出å…
1273¥å‡¦ç†ã¯ï¼Œä»¥ä¸‹ã®ã‚‚
1274のである.
1275
1276 SIL_LOC_INT
1277 SIL_UNL_INT
1278 lock_cpu
1279 unlock_cpu
1280
1281
1282○型キャストに伴う警告メッセージ
1283
1284GCCで-O2オプションをつけてコンパイルした場合に,カーネルのソースコード
1285中の数箇所で,次の警告メッセージが出る(GCCのバージョンにもよる).
1286
1287warning: dereferencing type-punned pointer will break strict-aliasing rules
1288
1289これは,GCCに-O2オプションをつけると,コンパイラがC言語のstrict
1290aliasing ruleを前提とするためである.コンパイラにstrict aliasing ruleを
1291適用させないためには,GCCのオプションに-fno-strict-aliasingを指定すれば
1292よい.これにより,警告メッセージは抑止されるが,strict aliasing ruleを
1293前提とした最適化は行われなくなる.
1294
1295ASP3カーネルに実装
1296においては,strict aliasing ruleを前提とした最適化を行っ
1297てもよく,この警告メッセージを無視しても差し支えない.以下では,この警
1298告メッセージを無視しても差し支えない理由を述べる.
1299
1300警告メッセージが出る例として,semaphore.c中の次の行について検討する.
1301
1302 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
1303
1304この警告メッセージの原因は,直接的には,&winfo_semを(WINFO_WOBJ *)にキャ
1305ストしていることであるが,本質的な原因は,このコードがC言語のstrict
1306aliasing ruleに従わない代å…
1307¥æ–‡ã®åŽŸå› ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚り,このルールに依存
1308した最適化が誤った結果を引き起こす可能性があることである.
1309
1310C言語のstrict aliasing ruleは,互換性のない異なる型を通して,オーバラッ
1311プするメモリ領域をアクセスする代å…
1312¥æ–‡ã‚’使用してはならないというものであ
1313る(使用した場合の振舞いは未定義になる).このケースでは,(WINFO_SEM
1314*)型のポインタ経由と(WINFO_WOBJ *)型のポインタ経由で,オーバラップする
1315メモリ領域をアクセスする代å…
1316¥æ–‡ã‚’使用してはならないことになる.また,警
1317告メッセージの原因になってはいないが,(SEMCB *)型のポインタ経由と
1318(WOBJCB *)型のポインタ経由で,オーバラップするメモリ領域をアクセスする
1319代å…
1320¥æ–‡ã‚’使用してはならない.
1321
1322ASP3カーネルの実装
1323においては,semaphore.c中の関数においては,(SEMCB *)型
1324および(WINFO_SEM *)型のポインタを使用しており,(WOBJCB *)型および
1325(WINFO_WOBJ *)型のポインタ経由でメモリ領域をアクセスすることはない.一
1326方,そこから呼び出されるwait.c中の関数においては,(WOBJCB *)型および
1327(WINFO_WOBJ *)型のポインタを使用しており,(SEMCB *)型および(WINFO_SEM
1328*)型のポインタ経由でメモリ領域をアクセスすることはない.
1329
1330strict aliasing ruleに従わない代å…
1331¥æ–‡ã®å•é¡Œç‚¹ã¯ï¼Œã“のルールに依存した最
1332適化が誤った結果を引き起こす可能性があることであるが,異なるコンパイル
1333単位をまたいで最適化が行われることはないため,これにより問題が起こるこ
1334とはないと言うことができる.
1335
1336同じ議論は,他のソースファイル(eventflag.c,dataqueue.c,pridataq.c,
1337mailbox.c,mempfix.c)中の警告メッセージについても,そのまま当てはまる.
1338
1339
1340○kernel_cfg.hへの依存関係の扱い
1341
1342システムコンフィギュレーションファイルからインクルードされたヘッダファ
1343イルが変更された場合,単純に依存関係をたどるとコンフィギュレータの再実
1344行が必
1345要になり,kernel_cfg.hが更新される.その結果,kernel_cfg.hに依存
1346するソースファイルの再コンパイルが行われる.しかし,ヘッダファイルが変
1347更されても,kernel_cfg.hの内
1348容は更新されない場合も多い.このような場合,
1349再コンパイルは不要なはずである.
1350
1351この問題を解決する一般的な手法として,move-if-changeスクリプトを使い,
1352kernel_cfg.hの内
1353容が変わった場合のみ,そのタイムスタンプを更新する方法
1354がある.この場合,kernel_cfg.hを生成するターゲットは,タイムスタンプファ
1355イルにし,生成後にタイムスタンプファイルをtouchする必
1356要がある(そのよう
1357にしないと,kernel_cfg.hは,変更されたヘッダファイルに依存するため,次
1358回以降のmakeでも必
1359ずkernel_cfg.hの生成手順が実行されてしまう).
1360
1361ただし,タイムスタンプファイルをtouchする方法には,過去に,Windowsと
1362Cygwinのシステム時刻差異に伴う問題が指摘されている(下のURL参ç…
1363§ï¼‰ï¼Ž
1364
1365 http://dev.toppers.jp/trac/asp/ticket/286
1366
1367この問題を回避するために,コンフィギュレータによってタイムスタンプファ
1368イルを生成する方法をとる.
1369
1370これと同じ問題は,offset.hにも存在するため,同様に対処する.
1371
1372なお,kernel_cfg.cに同じ方法を適用してもよいが,再実行を防げる可能性が
1373ある処理がkernel_cfg.cのコンパイルだけで,それも再実行が必
1374要な場合が多
1375いため,メリットが小さいと考えて適用しないことにする.
1376
1377なお,ASPカーネルにおける対応は,move-if-changeを用いていなかったために,
1378あまり意味がなかった.これは,コンフィギュレータが内
1379容が更新されていな
1380いファイルのタイプスタンプを書き換えないことを想定していたためである
1381(その想定下でも,"touch -r"を用いた対応は不適切だった).コンフィギュ
1382レータをそのように改造することも難しくないが,コンフィギュレータによっ
1383てタイムスタンプを生成する方法は使えなくなる.
1384
1385以上
Note: See TracBrowser for help on using the repository browser.