TOPPERS Confidential TOPPERS/ASP3カーネル 設計メモ ASP3カーネルにおけるシステム時刻管理機能の設計について 作成者: 高田広章(名古屋大学) 最終更新: 2014年6月22日 ○メモの位置付け このメモは,TOPPERS/ASP3カーネルにおけるシステム時刻管理機能の設計につ いて記述するものである.最終的な設計ドキュメントは,ASP3カーネルの設計 書に入れ込む予定であるが,このメモは,設計ドキュメントを作成する過程を 記録することも目的とする. ○参照文献 [1] TOPPERS第3世代カーネル(ITRON系)統合仕様書 Release 3.A.0(最終更新: 2014年5月18日). [2] TOPPERSプロジェクト ディスカッションメモ「TOPPERS第3世代カーネル (ITRON系)における時間管理について」(最終更新: 2014年5月18日). [3] TOPPERS/ASP3カーネル 設計メモ Release 3.A.0(最終更新: 2014年5月31 日). ○実装対象とする外部仕様 このメモでは,文献[1]の以下の部分に記述されている仕様の中で,ASP3カーネ ル(ドリフト調整機能拡張パッケージを含む)でサポートする機能を実装する ための設計ドキュメントを作成する. 「2.3.2 サービスコールとパラメータ」の節の次の部分 (2) システム時刻と相対時間 (3) タイムアウトとポーリング 「4.6.1 システム時刻管理」の節の全体 また,実装で想定するハードウェア構成として,次の記述も考慮する. 「2.1.4 想定するハードウェア構成」の節の(c) 具体的には,以下のタグを持つ仕様が実装対象となる(仕様書に記述されてい る順にリストアップする).なお,下のリスト中の「⇒」以降の記述は,後の 工程で追記したものである.この工程では,まずはリストアップのみを行って いる. ●2.1.4 想定するハードウェア構成 NGKI0556:(c)〔3〕 ●2.3.2(2) システム時刻と相対時間 NGKI0548:(a*)〔3〕 ⇒ASPD1001,ASPD1043,t_stddef.h NGKI0041:(b) ⇒ASPD1001,… NGKI0042:(a) ⇒ASPD1001,… NGKI0549:(a)〔3〕 ⇒ASPD1001,…,t_stddef.h NGKI0550:(b*)〔3〕 ⇒ASPD1001,システム時刻管理機能の設計全体に影響 NGKI0551:(b*)〔3〕 ⇒t_stddef.h NGKI0046:(a*) ⇒ASPD1026,ASPD1027 NGKI0048:(b) ⇒NGKI1233,NGKI2472,NGKI2481 NGKI0049:(a) ⇒ASPD1049 NGKI0050:(a) ⇒ASPD1049 NGKI0552:(a)〔3〕 ⇒time_event.c ●2.3.2(3) タイムアウトとポーリング(一部) NGKI0553:(b)〔3〕 ⇒ASPD1001,… NGKI0554:(a)〔3〕 ⇒ASPD1001,… ●4.6.1 システム時刻管理 NGKI3603:(a) NGKI2333:(a) NGKI3559:(a)〔3〕 NGKI2336:(a) NGKI2337:(a) NGKI2338:(a)〔M〕 ⇒ASP3対象外 NGKI2339:(a)〔M〕 ⇒ASP3対象外 NGKI2340:(a)〔M〕 ⇒ASP3対象外 NGKI2341:(a)〔M〕 ⇒ASP3対象外 NGKI2342:(a)〔M〕 ⇒ASP3対象外 NGKI3560:(a)〔3〕 NGKI3593:(a)〔3〕 ⇒ドリフト機能拡張 NGKI3594:(b)〔3〕 ⇒ドリフト機能拡張 NGKI3595:(a)〔3M〕 ⇒ASP3対象外 NGKI3580:(a)〔3〕 NGKI3574:(d)〔3〕 NGKI3573:(a)〔3〕 NGKI3575:(a)〔3〕 NGKI3576:(a)〔3M〕 ⇒ASP3対象外 NGKI3561:(a)〔3〕←NGKI3594 NGKI3562:(a)〔3〕 NGKI3578:(a)〔3〕 NGKI3579:(a)〔3〕 ASPS0224:(a)〔3〕 ASPS0225:(a)〔3〕 NGKI3563:(a*)〔3〕 ⇒time_manage.c NGKI3564:(a*)〔3〕 ⇒time_manage.c NGKI3565:(a*)〔3〕 ⇒time_manage.c NGKI3566:(a)〔3P〕 ⇒ASP3対象外 NGKI3567:(a)〔3〕 ⇒ASPD1059,ASPD1060 NGKI3568:(a)〔3M〕 ⇒ASP3対象外 NGKI2349:(a*) ⇒time_manage.c NGKI2350:(a*) ⇒time_manage.c NGKI2351:(a*) ⇒time_manage.c NGKI2352:(a)〔P〕 ⇒ASP3対象外 NGKI2353:(a)〔P〕 ⇒ASP3対象外 NGKI2354:(a) ⇒ASPD1057,ASPD1058 NGKI3591:(a)〔3〕 ⇒ASPD1041,ASPD1057,ASPD1058 NGKI3592:(a)〔3〕 ⇒ASPD1059,ASPD1060 NGKI2355:(a)〔M〕 ⇒ASP3対象外 NGKI3581:(a*)〔3〕 ⇒time_manage.c NGKI3583:(a*)〔3〕 ⇒time_manage.c NGKI3584:(a*)〔3〕 ⇒time_manage.c NGKI3585:(a)〔3P〕 ⇒ASP3対象外 NGKI3586:(a*)〔3〕 ⇒ASPD1053 NGKI3587:(a*)〔3〕 ⇒ASPD1053 NGKI3588:(a*)〔3〕 ⇒time_event.c NGKI3589:(a*)〔3〕 ⇒time_event.c NGKI3590:(a)〔3M〕 ⇒ASP3対象外 NGKI3596:(a)〔3〕 ⇒ドリフト機能拡張 NGKI3598:(a)〔3〕 ⇒ドリフト機能拡張 NGKI3599:(a)〔3〕←NGKI3594 ⇒ドリフト機能拡張 NGKI3600:(a)〔3P〕 ⇒ASP3対象外 NGKI3601:(a)〔3〕 ⇒ドリフト機能拡張 NGKI3602:(a)〔3M〕 ⇒ASP3対象外 ASPS0226:(a)〔3〕 ⇒サポート範囲に関する要求 ASPS0227:(a)〔3〕 ⇒サポート範囲に関する要求 NGKI3569:(a*)〔3〕 ⇒time_manage.c NGKI3571:(a*)〔3〕 ⇒time_manage.c NGKI3572:(a*)〔3〕 ⇒time_manage.c NGKI3577:(a)〔3M〕 ⇒ASP3対象外 これらの中で,ASP3カーネルでサポートしない機能に関するタグには,「⇒ ASP3対象外」と記載する.具体的には,保護機能対応カーネルやマルチプロセッ サ対応カーネルのみに適用されるタグがこれに該当する. また,「⇒ドリフト機能拡張」と記載したタグは,[ASPS0224]により標準で はサポートしないが,[ASPS0225]によりドリフト調整機能拡張パッケージで サポートすることを示す.「⇒サポート範囲に関する要求」は,ASP3カーネル および拡張パッケージで,どの範囲の仕様をサポートするかに関する記述であ る. 外部仕様書からの要求事項に加えて,ASP3カーネル 設計メモ(文献[3])の 「TOPPERS/ASP3カーネルの実装設計方針」の章に記述されている以下の要求事 項も考慮する. (1) ソースコードの読みやすさ・改造しやすさを重視する (2) 新しいターゲットシステムへのポーティングが容易な構造とする (3) 検証が容易な構造とする (4) 実行性能とメモリ使用量に配慮する (5) スケーラビリティに配慮する (6) ティックレスの時間管理(ティックレスカーネル) ●TOPPERS/ASP3カーネルの実装設計方針 ASPR0001:(a) ASPR0002:(a) ASPR0003:(a) ASPR0004:(a) ASPR0005:(a) ASPR0006:(a) ASPR0007:(a) ASPR0008:(a) ASPR0009:(a) ASPR0010:(a) ASPR0011:(a)〔3〕 ○設計ドキュメントの本体 ●ティックレスのタイムイベント処理 オーバランハンドラの起動以外のタイムイベント処理(タイムアウト処理,タ スクの遅延,周期ハンドラの起動,アラームハンドラの起動)は,システム時 刻をきっかけとして行われる[NGKI3603]. ASP3カーネルでは,システム時刻は,ハードウェアが持つ高分解能タイマを用 いて実現する.高分解能タイマは,一定時間毎にカウントアップし,指定した 回数カウントアップしたら,タイマ割込みを発生させる機能を持つものとする [NGKI0556]. 処理すべきタイムイベントがない時にタイマ割込みを発生させないようにする ためには[ASPR0011],発生を待っているタイムイベントの中で,最も早く発 生するタイムイベントの発生時刻に割込みを発生させるように,高分解能タイ マを設定するのが基本である【ASPD1002】. ●タイムイベントヒープ タイムイベントを効率的に処理するために,発生を待っているタイムイベント の集合を管理し,その中で発生時刻が最も早いものを効率的に取り出せるデー タ構造が必要である.このデータ構造には,TOPPERS/JSPカーネルで導入してか ら長い実績のあるタイムイベントヒープを用いる.タイムイベントヒープの設 計については,別に記述することとする. タイムイベントヒープに登録されているタイムイベントの中で,発生時刻が最 も早いものを,先頭のタイムイベントと呼ぶ. ●イベント時刻 システム時刻は64ビットの整数型になる場合があるが[NGKI0548],タイムイ ベントの発生時刻を64ビットで管理するのは効率が悪い.なぜなら,タイムイ ベントの発生時刻は相対時間でしか指定できず[NGKI0041],相対時間は32ビッ トで表現されることから[NGKI0549],ある時点でタイムイベントヒープに登 録されているタイムイベントの発生時刻は,おおよそ,32ビットで表現できる 時間幅に収まるためである.そこで,タイムイベントヒープに登録されている タイムイベントの発生時刻は,32ビットの符号無し整数型で表現することにす る【ASPD1001】.この時刻を,イベント時刻と呼ぶ. 実際には,ある時点で登録されているタイムイベントの発生時刻が32ビットで 表現できる時間幅に収まるように,外部仕様を定めている.以下では,これが 32ビットで表現できる時間幅に収まることを論証する. タイムイベントの発生時刻を相対時間で指定する場合,相対時間の基準時刻は, 周期ハンドラの起動時刻を除いては[NGKI2372][NGKI2373],相対時間を指 定するサービスコールを呼び出した時刻(言い換えると現在時刻)である [NGKI0042].そのため,相対時間に指定できる最大値をTMAX_RELTIMと書くこ とにすると,タイムイベントヒープに登録されているタイムイベントの発生時 刻は,おおよそ,現在時刻以降で,(現在時刻+TMAX_RELTIM)以前である.周期 ハンドラの起動時刻に関しては,「周期ハンドラのタイムイベントの登録」の 節で検討する. ただし,以下に挙げるいくつかの理由で,登録されているタイムイベントの発 生時刻が,現在時刻より前や,(現在時刻+TMAX_RELTIM)より後になる場合があ る. そこで,TMAX_RELTIMを4,000,000,000とし[NGKI0550],32ビットで表現でき る最大値(4,294,967,296)との間に,294,967,295(約294秒)のマージンを設 けている.そのため,以下に挙げる理由毎の最大幅の合計が294秒を超えなけれ ば,32ビットで表現できる時間幅に収まることになる. 以下では,登録されているタイムイベントの発生時刻が,現在時刻より前にな る理由と前になる最大幅,(現在時刻+TMAX_RELTIM)より後になる理由と後にな る最大幅について検討する. (1) 現在時刻より前になる理由 (1-1) タイムイベント処理の遅れ タイムイベントを処理するためのタイマ割込みが発生してから,タイムイベン トが処理されるまでの間は,タイムイベントの発生時刻は,現在時刻より前に なっている.特に,タイマ割込みが長時間マスクされていた場合や,タイマ割 込みより優先される処理が長時間実行されていた場合,プロセッサが処理でき る以上の頻度でタイムイベントが発生した場合には,タイムイベントの処理は 大幅に遅れることになる.タイムイベントの処理が大幅に遅れる原因はアプリ ケーションによって作られるものであるため,この状況を防ぐのはアプリケー ションの責任とする.具体的には,タイムイベントの処理が2秒以上遅れる状況 では,カーネルの動作は保証されないものとしている[NGKI3608].そのため, タイムイベント処理の遅れにより,登録されているタイムイベントの発生時刻 が現在時刻より前になる最大幅は,2秒と考えてよい. (1-2) システム時刻の調整によりシステム時刻を進めた システム時刻を調整するサービスコール(adj_tim)によりシステム時刻を進め ると,登録されているタイムイベントの発生時刻が,現在時刻より前になる可 能性がある.これに関しては,adj_timの1回の呼出しで進められる時間範囲が 最大1秒に制限されている[NGKI3561][NGKI3584]ことに加えて,1秒以上過 去の発生時刻を持つタイムイベントが処理されずに残っている場合は,それ以 上システム時刻を進めることができない[NGKI3588]こととしている.そのた め,システム時刻を進めたことにより,登録されているタイムイベントの発生 時刻が現在時刻より前になる最大幅は,2秒以下である. 外部仕様の制限[NGKI3608]は,システム時刻の調整によりシステム時刻を進 めた場合にも適用されるものである.そのため,(1-2)の理由によりタイムイベ ントの発生時刻が現在時刻より前になる最大幅(2秒以下)は,(1-1)の理由に よる最大幅(2秒)に含まれる.実際には,(1-2)の最大幅を考慮して,外部仕 様[NGKI3608]の制限時間を定めた. (2) (現在時刻+TMAX_RELTIM)より後になる理由 (2-1) 相対時間を長い方に丸める 詳しいことは後述するが,相対時間を指定した新たなタイムイベントを登録す る時には,相対時間を長い方に丸めるために,タイムイベントの発生時刻に高 分解能タイマの進み幅を加える.そのため,登録するタイムイベントの発生時 刻が,(現在時刻+TMAX_RELTIM)より,高分解能タイマの進み幅の分,後になる 場合がある.高分解能タイマの進み幅はターゲットにより定まるが,ターゲッ ト依存部に対して,1ミリ秒以下にするという制約を課すことにする 【ASPD1021】. (2-2) システム時刻の調整によりシステム時刻を戻した システム時刻を調整するサービスコール(adj_tim)によりシステム時刻を戻す と,登録されているタイムイベントの発生時刻が,(現在時刻+TMAX_RELTIM)よ り後になる可能性がある.これに関しては,adj_timの1回の呼出しで戻せる時 間範囲が最大1秒に制限されている[NGKI3561][NGKI3584]ことに加えて,現 在のシステム時刻が,システム時刻が最も進んでいた時のシステム時刻より1秒 以上戻っている場合には,システム時刻をそれ以上戻せない[NGKI3589]こと としている.そのため,システム時刻を戻したことにより,登録されているタ イムイベントの発生時刻が(現在時刻+TMAX_RELTIM)より後になる最大幅は,2 秒以下である. ●イベント時刻の比較方法 イベント時刻を32ビットで表現すると,周回することは避けられない.イベン ト時刻が周回する(UINT32_MAXを超える)と,イベント時刻は0に戻るため,イ ベント時刻の前後関係を,イベント時刻の単純な大小関係で判定することがで きなくなる. イベント時刻が周回した場合でも,イベント時刻の前後関係を判定できるよう にするために,周回する前のイベント時刻(値としては大きい)と周回後のイ ベント時刻(値としては小さい)の境界を示す値を,グローバル変数で管理す る【ASPD1008】.これを,境界イベント時刻と呼ぶ.イベント時刻の前後関係 は,比較対象のイベント時刻から境界イベント時刻を引いた値(オーバフロー は無視する)の大小関係で判定する【ASPD1009】. 前後関係の判定が必要なイベント時刻は,タイムイベントヒープに登録されて いるすべてのタイムイベントの発生時刻と,現在のイベント時刻である.その ため,直感的には,境界イベント時刻は,前述のマージンの中に設定されてい ればよい.具体的には,境界イベント時刻は,現在時刻から(1-1)の最大幅を引 いたイベント時刻と,(現在時刻+TMAX_RELTIM)に(2-1)と(2-2)の最大幅を加え たイベント時刻の間(イベント時刻は循環しているため,2つの「間」があるが, マージンとなっている方の間)に設定されていればよい. 前述のマージンから,(1-1)(2-1)(2-2)の最大幅を引くと,約290秒のマージン が残る.境界イベント時刻は,この間のどこに置いても良いが,(1-1)の最大幅 はアプリケーションの設計が悪いと超えてしまう可能性があるため,これが超 えた場合のロバスト性を考慮して,現在のイベント時刻の200秒前に設定するこ ととする【ASPD1010】. ●現在時刻の算出 イベント時刻と,高分解能タイマのカウント値(以下,単にカウント値と呼ぶ) の対応を管理するために,現在時刻を算出する度に,算出した時点でのカウン ト値とイベント時刻を,グローバル変数に保存する【ASPD1012】.すなわち, それらのグローバル変数には,現在時刻を前回に算出した時点でのカウント値 とイベント時刻を保持している. 現在時刻(現在のイベント時刻)を必要とする場合には,次の処理を行う.ま ず,高分解能タイマから,現在のカウント値を読み出す【ASPD1013】.読み出 したカウント値と前回のカウント値の差から,イベント時刻がどれだけ進んだ かを求める【ASPD1014】.その値を,前回のイベント時刻に加えて,現在のイ ベント時刻を算出する【ASPD1015】.算出したイベント時刻は,読み出した現 在のカウント値とともに,グローバル変数に格納する【ASPD1016】.さらに, 境界イベント時刻を更新する【ASPD1011】. なお,最後に現在時刻を算出した時点でのイベント時刻は,カーネルの初期化 時に0に初期化する【ASPD1047】.また,境界イベント時刻も,それに合わせて 初期化する【ASPD1048】. ●高分解能タイマ割込みの発生タイミングの設定 前述したように,高分解能タイマからの割込みの発生タイミングは,タイムイ ベントヒープの先頭のタイムイベントの発生時刻に設定するのが基本である [ASPD1002]. ただし,高分解能タイマのタイマ周期が,APIで指定できる最大相対時間よりも 短い場合には,上のような設定ができない場合がある.具体的には,先頭のタ イムイベントの発生時刻までの時間が,高分解能タイマのタイマ周期よりも長 い場合に,先頭のタイムイベントの発生時刻に割込みを発生するように設定で きない.この場合,タイマ周期が経過する以前にダミーの割込みを発生させ, 時刻を更新する処理を行う【ASPD1003】.不必要なタイミングで割込みが発生 することになるが,タイマ周期が経過する以前に時刻を更新する処理を行わな いと,高分解能タイマが周回したかがわからなくなるため,やむをえない. ここで,ダミーの割込みを発生させるタイミングが問題になる.タイマ周期が 経過する直前に割込みがかかるように設定した場合,何らかの理由で割込み処 理が遅延すると,割込みハンドラ内で高分解能タイマを読んだ時点でタイマが 周回している可能性があり,タイマが周回したことを見落とす可能性がある. そこで,ダミーの割込みを発生させるまでの時間は,タイマ周期からタイマ割 込みの最大遅延時間を引いた時間よりも短い時間に設定しなければならない 【ASPD1004】.ダミーの割込みを発生させるまでの時間は,ターゲット依存に 定めることとする【ASPD1005】. 同じ理由で,タイムイベントヒープの先頭のタイムイベントの発生までの時間 が,ダミーの割込みを発生させるまでの時間よりも長い場合には,ダミーの割 込みを発生させるまでの時間が経過したタイミングで割込みを発生させ,時刻 を更新する処理を行う【ASPD1006】.ダミーの割込みを発生させるまでの時間 はタイマ周期よりも短く設定されることから,この処理により[ASPD1003]も 実現される. さらに,タイムイベントヒープが空の場合にも,ダミーの割込みを発生させる までの時間が経過したタイミングで割込みを発生させ,時刻を更新する処理を 行う【ASPD1007】. システム時刻を調整した場合や,何らかの理由で割込み処理が遅延した場合に は,高分解能タイマの割込み発生タイミングを設定しようとした時点で,先頭 のタイムイベントの発生時刻を過ぎている可能性がある.このような場合には, タイマ割込みをすぐに発生させる【ASPD1017】. ●高分解能タイマ割込みの処理 高分解能タイマ割込みが発生すると,まず,前述の方法で現在時刻を算出する 【ASPD1022】.次に,タイムイベントヒープ中のタイムイベントの中で,発生 時刻が現在時刻以前のものを,以下の手順で処理する. タイムイベントヒープが空でない場合には,先頭のタイムイベントの発生時刻 と現在時刻を比較し,発生時刻が現在時刻以前である場合には,そのタイムイ ベントをタイムイベントヒープから削除し,タイムイベントを処理する 【ASPD1018】.これを,タイムイベントヒープが空になるか,先頭のタイムイ ベントの発生時刻が現在時刻以前でなくなるまで繰り返す【ASPD1019】. [ASPD1019]の繰り返しの間に,タイムイベントを1つ以上処理していた場合に は,その間に時間が経過していると考えられるため,再度,前述の方法で現在 時刻を算出し,前の段落に記述した処理を行う【ASPD1020】. タイムイベントを1つも処理せずに[ASPD1019]の繰り返しを終えた場合には, 前述の方法で高分解能タイマ割込みの発生タイミングを設定し,割込み処理を 終える【ASPD1025】. ●相対時間指定によるタイムイベントの登録 相対時間を指定してタイムイベントを登録する場合には,現在時刻を遅い方に 丸めた時刻に,指定された相対時間を加えて,タイムイベントの発生時刻を求 める【ASPD1026】. 現在時刻を遅い方に丸めるのは,[NGKI0046]により,タイムイベントの処理 を行うまでの時間を,相対時間によって指定した以上としなければならないた めである.それに対して,前述の方法で現在時刻を算出すると,現在時刻を早 い方に丸めた時刻が求まる.そこで,前述の方法で算出した現在時刻に,高分 解能タイマの進み幅(これを,TSTEP_HRTCNTと書く)を加えて,現在時刻を遅 い方に丸めた時刻とする【ASPD1027】. 以上の処理の後,タイムイベントをタイムイベントヒープに挿入する 【ASPD1030】.登録したタイムイベントが,先頭のタイムイベントになった場 合には,前述の方法で高分解能タイマ割込みの発生タイミングを設定する 【ASPD1031】. ただし,高分解能タイマ割込みの処理の途中でタイムイベントが登録される場 合には,タイマ割込み処理を終える前に高分解能タイマ割込みの発生タイミン グが設定されるため,ここで設定する必要はない.これを実現するために,高 分解能タイマ割込みの処理中であることを示すフラグをグローバル変数に用意 し【ASPD1032】,このフラグがセットされている場合には,高分解能タイマ割 込みの発生タイミングの設定を行わない【ASPD1034】.なお,このフラグは, システムの初期化時にクリアし,高分解能タイマ割込みの処理の入口でセット し,出口でクリアする【ASPD1033】. ●周期ハンドラのタイムイベントの登録 ASP3カーネルでは,TA_PHS属性の周期ハンドラをサポートしない[ASPS0172] ため,周期ハンドラを動作開始する時刻が,周期ハンドラを起動する時刻の基 準時刻となる[NGKI2372]. 周期ハンドラの初回の起動時刻は,周期ハンドラを動作開始する時刻から,周 期ハンドラの起動位相後である[NGKI2365].周期ハンドラを起動するタイム イベントを登録する処理の内容は,周期ハンドラを静的APIにより動作開始する 場合と,サービスコールにより動作開始する場合で異なる. 周期ハンドラを静的APIにより動作開始する場合には,カーネルの初期化処理で, タイムイベントを登録する.この時点ではシステム時刻は0であるため,周期ハ ンドラを動作開始する時刻は0ということになり,起動位相を発生時刻として, タイムイベントをタイムイベントヒープに挿入する【ASPD1035】.起動位相と して指定できる時間は0以上TMAX_RELTIM以下であるため[NGKI2399],タイム イベントの発生時刻は,現在時刻以降,(現在時刻+TMAX_RELTIM)以前という範 囲に収まる.周期ハンドラの動作開始の有無にかかわらず,カーネルの初期化 処理の最後で,高分解能タイマ割込みの発生タイミングを設定する必要がある ため,タイムイベントを登録する時点では,高分解能タイマ割込みの発生タイ ミングは設定しない. 周期ハンドラをサービスコールにより動作開始する場合には,現在時刻を基準 時刻,起動位相を相対時間としてタイムイベントを登録すればよいため,すで に検討したタイムイベントの発生時刻を相対時間で指定する場合と同様である 【ASPD1036】. 周期ハンドラの2回目以降の起動時刻は,前回の起動時刻から,周期ハンドラの 起動周期後である[NGKI2365].そのためのタイムイベントの登録処理は,高 分解能タイマ割込みの処理から呼び出される周期ハンドラ起動ルーチンの中で, 周期ハンドラを呼び出す前に,周期ハンドラを次回起動するためのタイムイベ ントを登録する形で行う【ASPD1037】.登録するタイムイベントの発生時刻は, 周期ハンドラの今回の起動時刻に起動周期を加えた時刻とする【ASPD1038】. 周期ハンドラ起動ルーチンが呼ばれた時点で,周期ハンドラを今回起動するタ イムイベントは,直前まで,タイムイベントヒープの先頭にあったタイムイベ ントである.また,起動周期として指定できる時間は0より大きくTMAX_RELTIM 以下であることから[NGKI2397],登録するタイムイベントの発生時刻は,直 前まで先頭にあったタイムイベントの発生時刻より後で,(直前まで先頭にあっ たタイムイベントの発生時刻+TMAX_RELTIM)以前という範囲に収まる.タイム イベントの処理が2秒以上遅れる状況では,カーネルの動作は保証されないもの としている[NGKI3608]ことから,直前まで先頭にあったタイムイベントの発 生時刻が,現在時刻より前になる最大幅は2秒と考えてよく,既に検討した (1-1)の最大幅の範囲内である. タイムイベントを登録する周期ハンドラ起動ルーチンは,高分解能タイマ割込 みの処理から呼び出されるため,ここで高分解能タイマ割込みの発生タイミン グを設定する必要はない. ●タイムイベントの登録解除 タイムイベントの登録を解除する場合には,タイムイベントをタイムイベント ヒープから削除する【ASPD1039】. 高分解能タイマ割込みの処理の途中でタイムイベントが登録解除される場合で なく,削除したタイムイベントが先頭のタイムイベントであった場合には,前 述の方法で高分解能タイマ割込みの発生タイミングを設定する【ASPD1040】. ●タイムイベントが発生するまでの時間の計算 タイムイベントが発生するまでの時間を計算する場合には,タイムイベントの 発生時刻から,現在時刻を遅い方に丸めた時刻を引くことによって求める 【ASPD1049】.現在時刻を遅い方に丸めた時刻は,[ASPD1027]の方法で求め る【ASPD1050】. 現在時刻を遅い方に丸めるのは,[NGKI0050]により,タイムイベントが発生 する時刻を相対時間で返す場合には,タイムイベントが処理されるのは,基準 時刻から相対時間として返された以上の時間が経過した後としなければならな いためである.ここでの基準時刻は,相対時間を返すサービスコールを呼び出 した時刻(言い換えると現在時刻)である[NGKI0049]. ただし,タイムイベントの発生時刻が,現在時刻以前である場合には,タイム イベントまでの残り時間として0を返す[NGKI0552]. ●システム時刻の管理 システム時刻を参照するサービスコール(get_tim)は,システム時刻が最も進 んでいた時のシステム時刻(adj_timでシステム時刻を戻していない場合には, 現在のシステム時刻に一致する)を返す[NGKI3591].これを実現するために, システム時刻が最も進んでいた時のイベント時刻を,グローバル変数で管理す る【ASPD1041】. 最も進んでいた時のイベント時刻は,カーネルの初期化時に0に初期化し 【ASPD1046】,現在のイベント時刻を進める度に更新する.具体的には,最も 進んでいた時のイベント時刻と進める前の現在のイベント時刻の差が,現在の イベント時刻の進み分よりも小さい場合には,最も進んでいた時のイベント時 刻を,進めた後の現在のイベント時刻に一致させる【ASPD1042】. システム時刻とイベント時刻は,同じ速度で進むため,システム時刻を設定し ない間は,その差は一定である.その差を管理するために,get_timで参照する するシステム時刻(64ビットの符号無し整数型.ただし,64ビットの整数型が サポートされていないターゲットでは32ビットの符号無し整数型[NGKI0548]) と,最も進んでいた時のイベント時刻(32ビットの符号無し整数型)の差を, グローバル変数で管理する【ASPD1043】.この差を,システム時刻のオフセッ トと呼ぶ. カーネルの初期化時には,システム時刻は0に初期化され[NGKI2333],最も進 んでいた時のイベント時刻も0に初期化される[ASPD1046]ことから,システム 時刻のオフセットも0に初期化する【ASPD1044】.また,システム時刻が64ビッ トの符号無し整数型の場合には,最も進んでいた時のイベント時刻を進めた結 果,その値が周回した時には,システム時刻のオフセットに2^32を加算する 【ASPD1045】. ●システム時刻の参照と設定 システム時刻の参照(get_tim)の処理本体(排他制御の内側の処理)では,ま ず,前述の方法で現在時刻を算出・更新し,それに伴って,最も進んでいた時 のイベント時刻も更新する【ASPD1057】.その後,最も進んでいた時のイベン ト時刻にシステム時刻のオフセットを加えることで,最も進んでいた時のシス テム時刻を求め,指定されたメモリ領域に返す【ASPD1058】. システム時刻の設定(set_tim)の処理本体(排他制御の内側の処理)では,ま ず,前述の方法で現在時刻を算出・更新し,それに伴って,最も進んでいた時 のイベント時刻も更新する【ASPD1059】.その後,指定されたシステム時刻と 最も進んでいた時のイベント時刻の差を求め,システム時刻のオフセットに格 納する【ASPD1060】. [NGKI3592]で変化しないことが要求されている「get_timで参照するシステム 時刻の進みが止まっている時間」は,最も進んでいた時のイベント時刻と現在 のイベント時刻の差で実現されている.上記のset_timの処理手順では,現在時 刻と最も進んでいた時のイベント時刻を,サービスコールが呼び出された時点 の状態に更新する以外には,最も進んでいた時のイベント時刻と現在のイベン ト時刻の差を変更することはない.そのため,上の処理手順で[NGKI3592]の 要求を満たしている. ●システム時刻の調整 システム時刻の調整(adj_tim)の処理本体(排他制御の内側の処理)は,以下 の手順で行う. まず,前述の方法で現在時刻を算出する【ASPD1051】.次に,E_OBJエラーの チェックを行う【ASPD1052】.E_OBJエラーのチェックの内容は,システム時刻 を進める場合と遅らせる場合で異なる.システム時刻を進める場合には,タイ ムイベントヒープが空でなく,先頭のタイムイベントの発生時刻が現在時刻よ りも1秒以上前である場合に,E_OBJエラーとする[NGKI3588].システム時刻 を遅らせる場合には,最も進んでいた時のイベント時刻と現在のイベント時刻 との差が1秒以上の場合に,E_OBJエラーとする[NGKI3589]. E_OBJエラーでない場合には,現在のイベント時刻に,指定された調整量を加え る【ASPD1053】.これにより,システム時刻の現在値に指定された調整量を加 えられ[NGKI3586],タイムイベントが発生するまでの相対時間も調整される [NGKI3587].また,境界イベント時刻を更新する【ASPD1055】. ここで,イベント時刻を進める場合には,[ASPD1042]と同じ方法で,最も進 んでいた時のイベント時刻も更新する【ASPD1054】. 最後に,前述の方法で高分解能タイマ割込みの発生タイミングを設定する 【ASPD1056】. ●カーネルの初期化時の処理 カーネルの初期化時には,タイムイベント管理モジュールの初期化処理におい て,最後に現在時刻を算出した時点でのイベント時刻,境界イベント時刻,最 も進んでいた時のイベント時刻,高分解能タイマ割込みの処理中であることを 示すフラグを初期化し,タイムイベントヒープを空に初期化する【ASPD1061】. その後に呼び出される周期ハンドラ機能の初期化処理において,静的APIにより 動作開始する周期ハンドラの,初回の起動のためのタイムイベントを登録する 【ASPD1062】. カーネルの初期化処理の最後(カーネル動作を開始する直前)に,高分解能タ イマの現在のカウント値を読み出し,その値で,最後に現在時刻を算出した時 点でのカウント値を初期化する【ASPD1063】.最後に,前述の方法で,高分解 能タイマ割込みの発生タイミングを設定する【ASPD1064】. ●高分解能タイマモジュール(ターゲット依存部)の仕様 ★未完成 ○トレーサビリティ ●ASPD1001に関する補足説明 ASPD1001(タイムイベントの発生時刻を,カーネル内部では32ビットで扱う) は,すり合わせ設計の結果である.具体的には,外部仕様の多くの要求に依存 して決定されていることに加えて,これに依存して他の多くの設計が出てきて いる.つまり,外部仕様と設計が多対多に関係している中で,ASPD1001がハブ になっている. また,ASPD1001から外部仕様に対する制限事項が抽出されているという意味で も,すり合わせ設計になっている.この関係を素直に表現すると,設計から外 部仕様に対してリンクがあることになるが,このような逆関係は避けるべきと 考えたため,外部仕様から設計へのリンクとして表現している.これに該当す るリンクは,下のトレーサビリティ一覧で"#"をつけて区別した.また,外部仕 様書の仕様決定の理由に,これらの制限事項が,実装を考慮したものである旨 を記述している. ●設計項目に対する上位要求からのトレーサビリティ ASPD1001:(a*) ←ASPR0006,NGKI0548,NGKI0041,NGKI0042, NGKI0549,NGKI0550#,NGKI0553,NGKI0554, NGKI3608#,NGKI3561#,NGKI3584#,NGKI3588#, NGKI3589,NGKI2372,NGKI2373,ASPS0172, NGKI2365,NGKI2397,NGKI2399 ASPD1002:(a*) ←ASPR0011 ASPD1003:(b*)(e:ASPD1002) ASPD1004:(d) ASPD1005:(d) ASPD1006:(a*)(e:ASPD1002) ←ASPD1003 ASPD1007:(a*) ASPD1008:(a*) ←ASPD1001 ASPD1009:(a*) ←ASPD1001 ASPD1010:(ab*) ←ASPD1001 ASPD1011:(a*) ←ASPD1016,ASPD1010 ASPD1012:(a*) ←NGKI3559,ASPR0011 ASPD1013:(a*) ←NGKI3559 ASPD1014:(a*) ←NGKI3559 ASPD1015:(a*) ←NGKI3559 ASPD1016:(a*) ←ASPD1012 ASPD1017:(a*)(e:ASPD1002) ASPD1018:(a*) ASPD1019:(a*) ASPD1020:(a*) ASPD1021:(d) ASPD1022:(a*) ASPD1023:欠番 ASPD1024:欠番 ASPD1025:(a*) ASPD1026:(a*) ASPD1027:(a*) ⇒ASPD1050 ASPD1028:欠番 ASPD1029:欠番 ASPD1030:(a*) ASPD1031:(a*) ASPD1032:(a*) ASPD1033:(a*) ASPD1034:(a*) ASPD1035:(a*) ASPD1036:(a*) ASPD1037:(a*) ASPD1038:(a*) ASPD1039:(a*) ASPD1040:(a*) ASPD1041:(a*) ←NGKI3591 ASPD1042:(a*) ←ASPD1041 ASPD1043:(a*) ASPD1044:(a*) ASPD1045:(a*) ASPD1046:(a*) ←ASPD1041 ASPD1047:(a*) ASPD1048:(a*) ←ASPD1010 ASPD1049:(a*) ←NGKI0049,NGKI0050 ASPD1050:(a*) ←ASPD1027 ASPD1051:(a*) ASPD1052:(a*) ASPD1053:(a*) ←NGKI3586,NGKI3587 ASPD1054:(a*) ASPD1055:(a*) ←ASPD1010 ASPD1056:(a*) ASPD1057:(a*) ←NGKI2354,NGKI3591 ASPD1058:(a*) ←NGKI2354,NGKI3591 ASPD1059:(a*) ←NGKI3567,NGKI3592 ASPD1060:(a*) ←NGKI3567,NGKI3592 ASPD1061:(a*) ASPD1062:(a*) ASPD1063:(a*) ASPD1064:(a*) 以上