このドキュメントは,TOPPERS第3世代カーネル(ITRON系)に属する一連のリアルタイムカーネルの仕様を,統合的に記述したものである.
現時点で,基本仕様(ASP3カーネルの仕様),保護機能対応(HRP3カーネルの仕様),マルチプロセッサ対応(FMP3カーネルの仕様),保護機能とマルチプロセッサの両方に対応する場合(HRMP3カーネルの仕様)に関しては記述が完成している.それに対して,メニーコアプロセッサ対応や動的生成対応については,十分な検討ができておらず,今後変更が加わる可能性がある.
TOPPERS Third Generation Kernel (ITRON-based) Specification Copyright (C) 2006-2023 by Embedded and Real-Time Systems Laboratory Graduate School of Information Science, Nagoya Univ., JAPAN Copyright (C) 2006-2023 by TOPPERS Project, Inc., JAPAN 上記著作権者は,以下の (1)〜(3) の条件を満たす場合に限り,本ドキュメ ント(本ドキュメントを改変したものを含む.以下同じ)を使用・複製・改 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. (1) 本ドキュメントを利用する場合には,上記の著作権表示,この利用条件 および下記の無保証規定が,そのままの形でドキュメント中に含まれて いること. (2) 本ドキュメントを改変する場合には,ドキュメントを改変した旨の記述 を,改変後のドキュメント中に含めること.ただし,改変後のドキュメ ントが,TOPPERSプロジェクト指定の開発成果物である場合には,この限 りではない. (3) 本ドキュメントの利用により直接的または間接的に生じるいかなる損害 からも,上記著作権者およびTOPPERSプロジェクトを免責すること.また, 本ドキュメントのユーザまたはエンドユーザからのいかなる理由に基づ く請求からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 本ドキュメントは,無保証で提供されているものである.上記著作権者およ びTOPPERSプロジェクトは,本ドキュメントに関して,特定の使用目的に対す る適合性も含めて,いかなる保証も行わない.また,本ドキュメントの利用 により直接的または間接的に生じたいかなる損害に関しても,その責任を負 わない.
仕様書で用いる記述項目と記号
この仕様書では,以下の記述項目を用いる.
【補足説明】の項では,仕様本体の記述に対する補足事項を説明する.
【〜〜カーネルにおける規定】の項では,TOPPERS第3世代カーネル(ITRON系)に属する特定のカーネルにおける追加仕様を規定する.
【〜〜仕様との関係】の項では,この仕様と,μITRON4.0仕様,μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との主な違いについて説明する.
【未決定事項】の項では,この仕様書の現時点のバージョンでは,決定されずに残っている事項について記述する.
【仕様決定の理由】の項では,仕様を決定するにあたって考慮した事項について説明する.
「第4章 カーネルAPI仕様」の章の各サービスコールおよび静的APIの仕様記述においては,以下の記述項目を用いる.
【静的API】の項では,システムコンフィギュレーションファイル中で静的APIを記述する形式を規定する.また,【C言語API】の項では,C言語からサービスコールを呼び出す形式を規定する.
【パラメータ】の項では,サービスコールおよび静的APIに渡すパラメータの名称とデータ型を規定し,簡単な説明を行う.また,【リターンパラメータ】の項では,サービスコールが返すリターンパラメータの名称とデータ型を規定し,簡単な説明を行う.【エラーコード】の項では,サービスコールおよび静的APIが返す可能性のあるメインエラーコードと,その検出条件を規定する.
【機能】の項では,サービスコールおよび静的APIの機能を規定する.
TOPPERS第3世代カーネルに属する特定のカーネルにおいてのみサポートするAPIについては,【サポートするカーネル】の項で,そのことを記述する.
また,「第4章 カーネルAPI仕様」の章では,カーネルのAPIの種別とAPIをサポートするカーネルの種類を表すために,次の記号を用いる.
〔T〕はタスクコンテキスト専用のサービスコールを示す.非タスクコンテキストから呼び出すと,E_CTXエラーとなる.
〔I〕は非タスクコンテキスト専用のサービスコールを示す.タスクコンテキストから呼び出すと,E_CTXエラーとなる.
〔TI〕はタスクコンテキストからも非タスクコンテキストからも呼び出すことのできるサービスコールを示す.
〔S〕は静的APIを示す.
〔P〕は保護機能対応カーネルのみでサポートされているAPIを示す.保護機能対応でないカーネルでは,このAPIはサポートされない.
〔M〕はマルチプロセッサ対応カーネルのみでサポートされているAPIを示す.マルチプロセッサ対応でないカーネルでは,このAPIはサポートされない.
〔D〕は動的生成対応カーネルのみでサポートされているAPIを示す.動的生成対応でないカーネルでは,このAPIはサポートされない.
〔x|y〕は,xまたはyに該当するAPIを示す.例えば,〔TP|TM〕は,保護機能対応カーネルまたはマルチプロセッサ対応カーネルでサポートされているタスクコンテキスト専用のサービスコールを示す.
また,エラーが発生する条件を表すために,次の記号を用いる.
〔s〕はサービスコールのみで発生するエラーを示す.静的APIでは,このエラーは発生しない.
〔S〕は静的APIのみで発生するエラーを示す.サービスコールでは,このエラーは発生しない.
〔P〕は保護機能対応カーネルのみで発生するエラーを示す.保護機能対応でないカーネルでは,このエラーは発生しない.
〔M〕はマルチプロセッサ対応カーネルのみで発生するエラーを示す.マルチプロセッサ対応でないカーネルでは,このエラーは発生しない.
〔D〕は動的生成対応カーネルのみで発生するエラーを示す.動的生成対応でないカーネルでは,このエラーは発生しない.
タグの付与方法
この仕様書では,トレーサビリティの確保のために,記述事項に対してタグを付与する.具体的には,以下に該当する記述事項を,タグを付与する対象とする.
-
対象ソフトウェアの実装に対する要求事項や制限事項
-
対象ソフトウェアの仕様に対する一般要求事項
-
対象ソフトウェアの動作環境に対する要求事項
-
ターゲット定義の規定
それに対して,用語の定義や補足説明,対象ソフトウェアを使用する上での推奨事項や注意事項,仕様決定の理由,他の仕様との関係に対しては,タグを付与しない.
タグの形式と意味は次の通りである(xxxxは4桁の数字を表す).
NGKIxxxx |
TOPPERS第3世代カーネル(ITRON系)全体を対象とした記述 |
|
ASPSxxxx |
TOPPERS/ASP3カーネルを対象とした記述 |
|
FMPSxxxx |
TOPPERS/FMP3カーネルを対象とした記述 |
|
HRPSxxxx |
TOPPERS/HRP3カーネルを対象とした記述 |
|
HRMPSxxxx |
TOPPERS/HRMP3カーネルを対象とした記述 |
|
SSPSxxxx |
TOPPERS/SSP3カーネルを対象とした記述 |
仕様書中では,ある記述事項にタグYYYYxxxx(YYYYは4〜5文字の英文字,xxxxは4桁の数字を表す)が付与されていることを,【YYYYxxxx】で表現する.それに対して,タグYYYYxxxxを参照する場合には,[YYYYxxxx]と表記する.
第1章 TOPPERS第3世代カーネル(ITRON系)の概要
TOPPERS第3世代カーネル(ITRON系)とは,TOPPERSプロジェクトにおいて,ITRON仕様をベースとして開発している一連のリアルタイムカーネルの総称である.この章では,TOPPERS第3世代カーネル仕様(ITRON系)の位置付けと設計方針,それに属する各カーネルの適用対象領域と設計方針について述べる.
1.1 TOPPERS第3世代カーネル(ITRON系)仕様の位置付け
TOPPERSプロジェクトでは,プロジェクトの第1フェーズにおいて,2000年に公開したTOPPERS/JSPカーネルを始めとして,μITRON4.0仕様およびその保護機能拡張(μITRON4.0/PX仕様)に準拠したリアルタイムカーネルを開発してきた.
μITRON4.0仕様は1999年に,μITRON4.0/PX仕様は2002年に公表されたが,それ以降,大きな仕様改訂は実施されていない.その間に,組込みシステムおよびソフトウェアのますますの大規模化・複雑化,これまで以上に高い信頼性・安全性に対する要求,小さい消費エネルギー下での高い性能要求など,組込みシステム開発を取り巻く状況は刻々変化してきた.リアルタイムカーネルに対しても,マルチプロセッサへの対応,発展的な保護機能のサポート,機能安全対応,省エネルギー制御機能のサポートなど,新しい要求が生じた.
TOPPERSプロジェクトでは,リアルタイムカーネルに対するこのような新しい要求に対応するために,μITRON4.0仕様を発展させる形で,TOPPERS新世代カーネル仕様を策定することになった.それをさらに拡張・改良したのが,TOPPERS第3世代カーネル(ITRON系)仕様である。
ただし,ITRON仕様が,各社が開発するリアルタイムカーネルを標準化することを目的に,リアルタイムカーネルの「標準仕様」を規定することを目指しているのに対して,TOPPERS第3世代カーネル(ITRON系)仕様は,TOPPERSプロジェクトにおいて開発している一連のリアルタイムカーネルの「実装仕様」を記述するものであり,ITRON仕様とは異なる目的・位置付けを持つものである.
1.2 TOPPERS第3世代カーネル(ITRON系)仕様の設計方針
TOPPERS第3世代カーネル(ITRON系)仕様を設計するにあたり,次の方針を設定する.
(1) μITRON4.0仕様をベースに拡張・改良を加える
TOPPERS第3世代カーネル(ITRON系)仕様は,多くの技術者の尽力により作成され,多くの実装・使用実績があるμITRON4.0仕様,およびそれを拡張・改良したTOPPERS新世代カーネル仕様をベースとする.ただし,μITRON4.0仕様およびTOPPERS新世代カーネル仕様の策定時以降の状況の変化を考慮し,それらで不十分と考えられる点については積極的に拡張・改良する.μITRON4.0仕様への準拠性やTOPPERS新世代カーネル仕様との互換性にはこだわらない.
(2) ソフトウェアの再利用性を重視する
μITRON4.0仕様およびTOPPERS新世代カーネル仕様の策定時点と比べると,組込みソフトウェアの大規模化が進展している一方で,ハードウェアの性能向上も著しい.そのため,ソフトウェアの再利用性を向上させるためには,少々のオーバヘッドは許容される状況にある.
そこで,TOPPERS第3世代カーネル(ITRON系)仕様では,μITRON4.0仕様においてオーバヘッド削減のために実装定義または実装依存としていたような項目についても,ターゲットシステムに依存する項目とするのではなく,強く規定する方針とする.
(3) 高信頼・安全なシステム構築を支援する
TOPPERS第3世代カーネル(ITRON系)仕様は,高信頼・安全な組込みシステム構築を支援するものとする.
安全性の面では,保護機能対応において,機能安全規格の要求を満たすことができるパーティショニング機能を実現する.また,アプリケーションプログラムに問題がある場合でも,リーゾナブルなオーバヘッドでそれを救済できるなら,救済するような仕様とする.
(4) アプリケーションシステム構築に必要な機能は積極的に取り込む
上記の方針を満たした上で,多くのアプリケーションシステムに共通に必要となる機能については,積極的にカーネルに取り込む.
カーネル単体の信頼性を向上させるためには,カーネルの機能は少なくした方が楽である.しかし,アプリケーションシステム構築に必要となる機能は,カーネルがサポートしていなければアプリケーションプログラムで実現しなければならず,システム全体の信頼性を考えると,多くのアプリケーションシステムに共通に必要となる機能については,カーネルに取り込んだ方が有利である.
1.3 TOPPERS/ASP3カーネルの適用対象領域と仕様設計方針
TOPPERS/ASP3カーネル(ASPは,Advanced Standard Profileの略.3はバージョン番号を示す.以下,ASP3カーネル)は,TOPPERS第3世代カーネル(ITRON系)の出発点となるリアルタイムカーネルである.保護機能を持ったカーネルやマルチプロセッサ対応のカーネルは,ASP3カーネルを拡張する形で開発する.
ASP3カーネルは,20年以上に渡るITRON仕様の技術開発成果をベースとして,完成度の高いリアルタイムカーネルを実現するものである.完成度を高めるという観点から,カーネル本体の仕様については,枯れた技術で実装できる範囲に留める.
ASP3カーネルの主な適用対象は,高い信頼性・安全性・リアルタイム性を要求される組込みシステムとする.ソフトウェア規模の面では,プログラムサイズ(バイナリコード)が数十KB〜1MB程度のシステムを主な適用対象とする.それより大規模なシステムには,保護機能を持ったリアルタイムカーネルを適用すべきと考えられる.
ASP3カーネルの機能は,カーネル内で動的なメモリ管理が不要な範囲に留める.これは,高い信頼性・安全性・リアルタイム性を要求される組込みシステムでは,システム稼働中に発生するメモリ不足への対処が難しいためである.この方針から,カーネルオブジェクトは静的に生成することとし,動的なオブジェクト生成機能は設けない.ただし,アプリケーションプログラムが動的なメモリ管理をするためのカーネル機能である固定長メモリプール機能はサポートする.
ASP3カーネルがサポートしていない機能の中で,ASP3カーネルに対して小規模な修正を行うことで対応できるものに関しては,拡張パッケージによりサポートしている.現時点で,ASP3カーネルがサポートしている拡張パッケージは次の通りである.
-
ドリフト調整機能拡張パッケージ
-
メッセージバッファ機能拡張パッケージ
-
オーバランハンドラ機能拡張パッケージ
-
タスク優先度拡張パッケージ
-
制約タスク拡張パッケージ
-
サブ優先度機能拡張パッケージ
-
優先度継承拡張パッケージ
-
動的生成機能拡張パッケージ
-
モノトニックタイマ機能拡張パッケージ
1.4 TOPPERS/FMP3カーネルの適用対象領域と仕様設計方針
TOPPERS/FMP3カーネル(FMPは,Flexible Multiprocessor Profileの略.3はバージョン番号を示す.以下,FMP3カーネル)は,ASP3カーネルを,マルチプロセッサ向けに拡張したリアルタイムカーネルである.
FMP3カーネルの適用対象となるターゲットハードウェアは,ホモジニアスなマルチプロセッサシステムで,プロセッサ数が4〜8個程度以下のものである.各プロセッサが全く同一のものである必要はないが,すべてのプロセッサでバイナリコードを共有することから,同じバイナリコードを実行できることが必要である.プロセッサ間の排他制御をジャイアントロックによって実現しているため,プロセッサ数が多くなると性能が劣化する.
FMP3カーネルでは,タスクを実行するプロセッサを静的に決定するのが基本であり,カーネルは自動的に負荷分散する機能を持たないが,タスクをマイグレーションさせるサービスコールを備えている.これを用いて,アプリケーションまたはシステムサービスで動的な負荷分散を実現することが可能である.
FMP3カーネルの機能は,ASP3カーネルと同様に,カーネル内で動的なメモリ管理が不要な範囲に留める.
【TOPPERS新世代カーネル統合仕様との関係】
TOPPERS新世代カーネル統合仕様に基づくTOPPERS/FMPカーネルは,ジャイアントロックと細粒度ロックの両方に対応しており,プロセッサ数が多いマルチ/メニーコアプロセッサにも適用可能であった.しかし,細粒度ロックに対応するためにコードが複雑になり,ジャイアントロックの場合に不要なオーバヘッドが生じるため,FMP3カーネルでは,ジャイアントロックのみに対応することとした.細粒度ロックに対応するカーネルは,別に開発する計画である.
1.5 TOPPERS/HRP3カーネルの適用対象領域と仕様設計方針
TOPPERS/HRP3カーネル(HRPは,High Reliable system Profileの略.3はバージョン番号を示す.以下,HRP3カーネル)は,さらに高い信頼性・安全性を要求される組込みシステムや,より大規模な組込みシステム向けに適用できるように,ASP3カーネルを拡張したリアルタイムカーネルである.
HRP3カーネルの適用対象となるターゲットハードウェアは,特権モードと非特権モードを備え,メモリ保護のためにMMU(Memory Management Unit)またはMPU(Memory Protection Unit)を持つプロセッサを用いたシステムである.HRP3カーネルの主な適用対象は,ソフトウェア規模の面では,プログラムサイズ(バイナリコード)が数百KB以上のシステムである.
HRP3カーネルの機能は,ASP3カーネルと同様に,カーネル内で動的なメモリ管理が不要な範囲に留める.具体的には,ASP3カーネルに対して,メモリ保護機能,時間パーティショニング機能,オブジェクトアクセス保護機能,拡張サービスコール機能,メッセージバッファ機能(ASP3カーネルでは拡張パッケージでサポート)を追加している.
HRP3カーネルがサポートしていない機能の中で,HRP3カーネルに対して小規模な修正を行うことで対応できるものに関しては,拡張パッケージによりサポートを予定している.現時点で,HRP3カーネルがサポートしている拡張パッケージは次の通りである.
-
オーバランハンドラ機能拡張パッケージ
-
動的生成機能拡張パッケージ
-
モノトニックタイマ機能拡張パッケージ
1.6 TOPPERS/HRMP3カーネルの適用対象領域と仕様設計方針
TOPPERS/HRMP3カーネル(HRMPは,High Reliable Multiprocessor Profileの略.3はバージョン番号を示す.以下,HRMP3カーネル)は,ASP3カーネルを,マルチプロセッサ向けかつ保護機能対応に拡張したリアルタイムカーネルである.
HRMP3カーネルの適用対象となるターゲットハードウェアは,FMP3カーネルの適用対象とHRP3の適用対象の両方の特徴を兼ね備えたシステムである.
【TOPPERS新世代カーネル統合仕様との関係】
マルチプロセッサと保護機能の両方に対応したカーネルは,TOPPERS新世代カーネル統合仕様に基づいては開発しなかった.
1.7 TOPPERS/SSP3カーネルの適用対象領域と仕様設計方針
TOPPERS/SSP3カーネル(SSPは,Smallest Set Profileの略.3はバージョン番号を示す.以下,SSP3カーネル)は,小規模な組込みシステムに用いるために,ASP3カーネルをベースに機能を絞り込んだリアルタイムカーネルである.
SSP3カーネルの機能は,μITRON4.0仕様の「仕様準拠の最低条件」の考え方を踏襲し,メモリ使用量を最小化するように定めている.具体的には,SSP3カーネルにおいては,タスクは待ち状態を持たない(言い換えると,制約タスクのみをサポートする)のが最大の特徴である.また,複数のタスクに同じ初期優先度を設定することができない.ASP3カーネルに対して下位互換性を持つように配慮しているが,システム全体のメモリ使用量を最小化するために有用な機能は,ASP3カーネルに対して追加している.
TOPPERS/SSP3カーネルの主な適用対象は,プログラムサイズ(バイナリコード)が数KB〜数十KB程度の極めて小規模な組込みシステムである.
1.8 その他のカーネル
以上で紹介したカーネルに加えて,メニーコアプロセッサに対応するカーネルを開発することを計画している.
第2章 主要な概念と共通定義
2.1 仕様の位置付け
この仕様は,TOPPERS第3世代カーネル(ITRON系)に属する各カーネルの仕様を,統合的に記述することを目標としている.また,TOPPERS第3世代カーネル(ITRON系)上で動作する各種のシステムサービスに共通に適用される事項についても規定する.
2.1.1 カーネルの機能セット
TOPPERS第3世代カーネル(ITRON系)は,TOPPERS/ASP3カーネルをベースとして,保護機能,マルチプロセッサ,カーネルオブジェクトの動的生成などに対応した一連のカーネルで構成される.
この仕様では,TOPPERS第3世代カーネル(ITRON系)を構成する一連のカーネルの仕様を統合的に記述するが,言うまでもなく,カーネルの種類によってサポートする機能は異なる.サポートする機能をカーネルの種類毎に記述する方法もあるが,カーネルの種類はユーザ要求に対応して増える可能性もあり,その度に仕様書を修正するのは得策ではない.
そこでこの仕様では,サポートする機能を,カーネルの種類毎ではなく,カーネルの対応する機能セット毎に記述する.具体的には,保護機能を持ったカーネルを保護機能対応カーネル,マルチプロセッサに対応したカーネルをマルチプロセッサ対応カーネル,カーネルオブジェクトの動的生成機能を持ったカーネルを動的生成対応カーネルと呼ぶことにする.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルは,保護機能対応カーネル,マルチプロセッサ対応カーネル,動的生成対応カーネルのいずれでもない【ASPS0001】.ただし,動的生成機能拡張パッケージを用いると,動的生成対応カーネルの機能の一部がサポートされる【ASPS0002】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルは,マルチプロセッサ対応カーネルであり,保護機能対応カーネル,動的生成対応カーネルではない【FMPS0001】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルは,保護機能対応カーネルであり,マルチプロセッサ対応カーネル,動的生成対応カーネルではない【HRPS0001】.ただし,動的生成機能拡張パッケージを用いると,動的生成対応カーネルの機能の一部がサポートされる【HRPS0009】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルは,保護機能とマルチプロセッサの両方に対応するカーネルであり,動的生成対応カーネルではない【HRMPS0001】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルは,保護機能対応カーネル,マルチプロセッサ対応カーネル,動的生成対応カーネルのいずれでもない【SSPS0001】.
【μITRON4.0仕様,μITRON4.0/PX仕様との関係】
μITRON4.0仕様は,カーネルオブジェクトの動的生成機能を持っているが,保護機能を持っておらず,マルチプロセッサにも対応していない.μITRON4.0/PX仕様は,μITRON4.0仕様に対して保護機能を追加するための仕様であり,カーネルオブジェクトの動的生成機能と保護機能を持っているが,マルチプロセッサには対応していない.
2.1.2 ターゲット非依存の規定とターゲット定義の規定
TOPPERS第3世代カーネル(ITRON系)は,アプリケーションプログラムの再利用性を向上させるために,ターゲットハードウェアや開発環境の違いをできる限り隠蔽することを目指している.ただし,ターゲットハードウェアや開発環境の制限によって実現できない機能が生じたり,逆にターゲットハードウェアの特徴を活かすためには機能拡張が不可欠になる場合がある.また,同一のターゲットハードウェアであっても,アプリケーションシステムによって使用方法が異なる場合があり,ターゲットシステム毎に仕様の細部に違いが生じることは避けられない.
そこで,TOPPERS第3世代カーネル(ITRON系)の仕様は,ターゲットシステムによらずに定めるターゲット非依存(target-independent)の規定と,ターゲットシステム毎に定めるターゲット定義(target-defined)の規定に分けて記述する.この仕様書は,ターゲット非依存の規定について記述するものであり,この仕様書で「ターゲット定義」とした事項は,ターゲットシステム毎に用意するドキュメントにおいて規定する.
また,この仕様書でターゲット非依存に規定した事項であっても,ターゲットハードウェアや開発環境の制限によって実現できない場合や,実現するためのオーバヘッドが大きくなる場合には,この仕様書の規定を逸脱する場合がある.このような場合には,ターゲットシステム毎に用意するドキュメントでその旨を明記する.
2.1.3 想定するソフトウェア構成
この仕様では,アプリケーションシステムを構成するソフトウェアを,アプリケーションプログラム(以下,単にアプリケーションと呼ぶ),システムサービス,カーネルの3階層に分けて考える(図2-1).カーネルとシステムサービスをあわせて,ソフトウェアプラットフォームと呼ぶ.

カーネルは,コンピュータの持つ最も基本的なハードウェア資源であるプロセッサ,メモリ,タイマを抽象化し,上位階層のソフトウェア(アプリケーションおよびシステムサービス)に論理的なプログラム実行環境を提供するソフトウェアである.
システムサービスは,各種の周辺デバイスを抽象化するソフトウェアで,ファイルシステムやネットワークプロトコルスタック,各種のデバイスドライバなどが含まれる.
また,この仕様では,プロセッサと各種の周辺デバイスの接続方法を隠蔽するためのソフトウェア階層として,システムインタフェースレイヤ(SIL)を規定する.
システムインタフェースレイヤ,カーネル,各種のシステムサービスを,上位階層のソフトウェアから使うためのインタフェースを,API(Application Programming Interface)と呼ぶ.
この仕様書では,第3章においてシステムインタフェースレイヤのAPI仕様を,第4章においてカーネルのAPI仕様を規定する.システムサービスのAPI仕様は,システムサービス毎の仕様書で規定される.
【μITRON4.0仕様との関係】
μITRON4.0仕様では,カーネルとアプリケーションの中間にあるソフトウェアをソフトウェア部品と呼んでいたが,TOPPERS組込みコンポーネントシステム(TECS)においてはカーネルもソフトウェア部品の1つと捉えることから,この仕様ではシステムサービスと呼ぶことにした.
2.1.4 想定するハードウェア構成
この仕様では,カーネルがサポートするターゲットハードウェアの構成として,以下のことを想定している.
ここに挙げるのは,この仕様を策定するにあたっての想定であり,これらをすべて満たせばカーネルを動作させることができるという網羅的な要件リストではない.逆に,これらに合致しないターゲットハードウェアであっても,ターゲット依存の仕様や制約を追加することで,カーネルを動作させることが可能な場合もある.
【TOPPERS新世代カーネル統合仕様との関係】
ハードウェア構成に対する想定を追加した.TOPPERS新世代カーネル統合仕様では,(1)と(6)の2項目のみを記述していた.
(1) メモリ構成
あるメモリ番地は,常に同一のメモリを指すこと(オーバレイのように,異なるメモリを同一のメモリ番地でアクセスすることがないこと)【NGKI0001】.マルチプロセッサ対応カーネルにおいては,同一のメモリに対しては,各プロセッサから同一の番地でアクセスできること【NGKI0002】.
【補足説明】
これらの想定に合致しないメモリを持つターゲットハードウェアであっても,カーネルを動作させることは可能であるが,想定に合致しないメモリは,アプリケーションの責任で使用する必要がある.特に保護機能対応するカーネルを使用する場合には,必要なパーティショニングが達成できているか,注意して使用することが必要である.
【仕様決定の理由】
アクセスできるプロセッサが限定されたメモリを想定していないのは,そのようなメモリ構成のターゲットハードウェアが少なくなっているためである.今後,必要性が高まった場合には,アクセスできるプロセッサが限定されたメモリを想定するように仕様拡張する可能性がある.
(2) 高分解能タイマ
一定時間毎にカウントアップしながら,指定した回数カウントアップしたら割込みを発生させる機能を備えた高分解能タイマを持つこと【NGKI0556】.マルチプロセッサ対応カーネルにおいては,高分解能タイマはすべてのプロセッサから読み出すことができ,指定した回数カウントアップしたら割込みを発生させる機能は,タイムイベントを処理するプロセッサ(少なくとも1つは必要)毎に持つこと【NGKI0621】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,指定した回数カウントアップしたら割込みを発生させる機能は,すべてのプロセッサに対して持つこと【HRMPS0013】.
【補足説明】
高分解能タイマは,一定時間毎にカウントアップするタイマと,指定した回数カウントアップしたら割込みを発生させるタイマの2つのタイマで実現することもできる.この場合,マルチプロセッサ対応カーネルにおいては,一定時間毎にカウントアップするタイマは各プロセッサで共有し,指定した回数カウントアップしたら割込みを発生させるタイマは,タイムイベントを処理するプロセッサ毎に持つことが必要である.
(3) タイムウィンドウタイマ
保護機能対応カーネルにおいては,時間パーティショニングをサポートしない場合を除き,指定した回数カウントアップしたら割込みを発生させる機能を備えたタイムウィンドウタイマを持つこと【NGKI0575】.マルチプロセッサ対応カーネルにおいては,タイムウィンドウタイマはプロセッサ毎に持つこと【NGKI0576】.
(4) オーバランタイマ
オーバランハンドラ機能をサポートする場合には,指定した回数カウントアップしたら割込みを発生させる機能を備えたオーバランタイマを持つこと【NGKI0564】.マルチプロセッサ対応カーネルにおいては,オーバランタイマはプロセッサ毎に持つこと【NGKI0565】.
(5) 実行モードとメモリ保護機構
保護機能対応カーネルにおいては,プロセッサが特権モードと非特権モードを備えていること【NGKI0646】.また,メモリ保護のために,MMU(Memory Management Unit)またはMPU(Memory Protection Unit)を持つこと【NGKI0647】.
(6) プロセッサ構成
マルチプロセッサ対応カーネルにおいては,各プロセッサが同一の機械語命令を実行できること【NGKI0003】.
(7) プロセッサ間の排他制御機構
マルチプロセッサ対応カーネルにおいては,プロセッサ間の排他制御(スピンロック)を実現するための機構を持つこと【NGKI0639】.システムインタフェースレイヤ用とカーネル内部用に,少なくとも2つのスピンロックを実現できることが望ましい【NGKI0640】.
2.1.5 想定するプログラミング言語
この仕様におけるAPI仕様は,ISO/IEC 9899:1990(以下,C90と呼ぶ)またはISO/IEC 9899:1999(以下,C99と呼ぶ)に準拠したC言語を,フリースタンディング環境で用いることを想定して規定している【NGKI0004】.
ただし,C90の規定に加えて,以下のことを仮定している.
-
16ビットおよび32ビットの整数型があること【NGKI0005】
-
ポインタが格納できるサイズの整数型があること【NGKI0006】
2.2 APIの構成要素とコンベンション
2.2.1 APIの構成要素
(1) サービスコール
上位階層のソフトウェアから,下位階層のソフトウェアを呼び出すインタフェースをサービスコール(service call)と呼ぶ.カーネルのサービスコールを,システムコール(system call)と呼ぶ場合もある.
(2) コールバック
下位階層のソフトウェアから,上位階層のソフトウェアを呼び出すインタフェースをコールバック(callback)と呼ぶ.
(3) 静的API
オブジェクトの生成情報や初期状態などを定義するために,システムコンフィギュレーションファイル中に記述するインタフェースを,静的API(static API)と呼ぶ.
(4) 構成マクロ
下位階層のソフトウェアに関する各種の情報を取り出すために,上位階層のソフトウェアが用いるマクロを,構成マクロ(configuration macro)と呼ぶ.
2.2.2 パラメータとリターンパラメータ
サービスコールやコールバックに渡すデータをパラメータ(parameter),それらが返すデータをリターンパラメータ(return parameter)と呼ぶ.また,静的APIに渡すデータもパラメータと呼ぶ.
オブジェクトを生成するサービスコールなど,パラメータの数が多い場合やオプションのパラメータがある場合,ターゲット定義のパラメータを追加する可能性がある場合には,複数のパラメータを1つの構造体に入れ,その領域へのポインタをパラメータとして渡す【NGKI0007】.また,パラメータのサイズが大きい場合にも,パラメータを入れた領域へのポインタをパラメータとして渡す場合がある【NGKI0008】.
C言語APIでは,リターンパラメータは,関数の返値とするか,リターンパラメータを入れる領域へのポインタをパラメータとして渡すことで実現する【NGKI0009】.オブジェクトの状態を参照するサービスコールなど,リターンパラメータの数が多い場合やターゲット定義のリターンパラメータを追加する可能性がある場合には,複数のリターンパラメータを1つの構造体に入れて返すこととし,その領域へのポインタをパラメータとして渡す【NGKI0010】.
複数のパラメータまたはリターンパラメータを入れるための構造体を,パケット(packet)と呼ぶ.
サービスコールやコールバックに,パケットを置く領域へのポインタやリターンパラメータを入れる領域へのポインタを渡す場合,別に規定がない限りは,サービスコールやコールバックの処理が完了した後は,それらの領域が参照されることはなく,別の目的に使用できる【NGKI0011】.
2.2.3 返値とエラーコード
一部の例外を除いて,サービスコールおよびコールバックの返値は,処理が正常終了したかを表す符号付き整数とする.処理が正常終了した場合には,E_OK(=0)または正の値が返るものとし,値の意味はサービスコールまたはコールバック毎に定める【NGKI0012】.処理が正常終了しなかった場合には,その原因を表す負の値が返る【NGKI0013】.処理が正常終了しなかった原因を表す値を,エラーコード(error code)と呼ぶ.
エラーコードは,いずれも負の値のメインエラーコードとサブエラーコードで構成される【NGKI0014】.メインエラーコードとサブエラーコードからエラーコードを構成するマクロ(ERCD)と,エラーコードからメインエラーコードを取り出すマクロ(MERCD),サブエラーコードを取り出すマクロ(SERCD)が用意されている【NGKI0015】.
メインエラーコードの名称・意味・値は,カーネルとシステムサービスで共通に定める(「2.14.4 TOPPERS共通エラーコード」の節を参照)【NGKI0016】.サービスコールおよびコールバックの機能説明中の「E_XXXXXエラーとなる」または「E_XXXXXエラーが返る」という記述は,メインエラーコードとしてE_XXXXXが返ることを意味する.
サブエラーコードは,エラーの原因をより詳細に表すために用いる.カーネルはサブエラーコードを使用せず,サブエラーコードとして常に-1が返る【NGKI0017】.サブエラーコードの名称・意味・値は,サブエラーコードを使用するシステムサービスのAPI仕様において規定する【NGKI0018】.
サービスコールが負の値のエラーコード(警告と通信エラーを表すものを除く)を返した場合には,サービスコールによる副作用がないのが原則である【NGKI0019】.ただし,そのような実装ができない場合にはこの原則の例外とし,サービスコールの機能説明にその旨を記述する【NGKI0020】.
サービスコールが複数のエラーを検出するべき状況では,その内のいずれか1つのエラーを示すエラーコードが返る【NGKI0021】.
コールバックが複数のエラーを検出するべき状況では,その内のいずれか1つのエラーを示すエラーコードを返せばよい【NGKI0022】.
なお,静的APIは返値を持たない.静的APIの処理でエラーが検出された場合の扱いについては,「2.12.5 コンフィギュレータの処理モデル」の節および「2.12.6 静的APIのパラメータに関するエラー検出」の節を参照すること.
2.2.4 機能コード
ソフトウェア割込みによりサービスコールを呼び出す場合などに用いるためのサービスコールを識別するための番号を,機能コード(function code)と呼ぶ.機能コードは符号付きの整数値とし,カーネルのサービスコールには負の値を割り付け,拡張サービスコールには正の値を用いる【NGKI0023】.
2.2.5 ヘッダファイル
カーネルやシステムサービスを用いるために必要な定義を含むファイル.
ヘッダファイルは,原則として,複数回インクルードしてもエラーにならないように対処されている.具体的には,ヘッダファイルの先頭で特定の識別子(例えば,kernel.hなら"TOPPERS_KERNEL_H")がマクロ定義され,ヘッダファイルの内容全体をその識別子が定義されていない場合のみ有効とする条件ディレクティブが付加されている【NGKI0024】.
2.3 主な概念
この仕様書では,メモリ領域(memory area)という用語は,連続したメモリの範囲という一般的な意味で使う.
2.3.1 オブジェクトと処理単位
(1) オブジェクト
カーネルまたはシステムサービスが管理対象とするソフトウェア資源を,オブジェクト(object)と呼ぶ.特に,カーネルが管理対象とするソフトウェア資源を,カーネルオブジェクト(kernel object)と呼ぶ.
オブジェクトは,種類毎に,番号によって識別する【NGKI0025】.カーネルまたはシステムサービスで,オブジェクトに対して任意に識別番号を付与できる場合には,1から連続する正の整数値でオブジェクトを識別するのを原則とする【NGKI0026】.この場合に,オブジェクトの識別番号を,オブジェクトのID番号(ID number)と呼ぶ.そうでない場合,すなわちカーネルまたはシステムサービスの内部または外部からの条件によって識別番号が決まる場合には,オブジェクトの識別番号を,オブジェクト番号(object number)と呼ぶ.識別する必要のないオブジェクトには,識別番号を付与しない場合がある【NGKI0027】.
オブジェクト属性(object attribute)は,オブジェクトの動作モードや初期状態を定めるもので,オブジェクトの登録時に指定する【NGKI0028】.オブジェクト属性にTA_XXXXが指定されている場合,そのオブジェクトを,TA_XXXX属性のオブジェクトと呼ぶ.複数の属性を指定する場合には,オブジェクト属性を渡すパラメータに,指定する属性値のビット毎論理和(C言語の"|")を渡す【NGKI0029】.また,指定すべきオブジェクト属性がない場合には,TA_NULLを指定する【NGKI0030】.
(2) 処理単位
オブジェクトの中には,プログラムが対応付けられるものがある.プログラムが対応付けられるオブジェクト(または,対応付けられるプログラム)を,処理単位(processing unit)と呼ぶ.処理単位に対応付けられるプログラムは,アプリケーションまたはシステムサービスで用意し,カーネルが実行制御する.
処理単位の実行を要求することを起動(activate),処理単位の実行を開始することを実行開始(start)と呼ぶ.
拡張情報(extended information)は,処理単位が呼び出される時にパラメータとして渡される情報で,処理単位の登録時に指定する【NGKI0031】.拡張情報は,カーネルやシステムサービスの動作には影響しない【NGKI0032】.
(3) タスク
カーネルが実行順序を制御するプログラムの並行実行の単位をタスク(task)と呼ぶ.タスクは,処理単位の1つである.
サービスコールの機能説明において,サービスコールを呼び出したタスクを,自タスク(invoking task)と呼ぶ.拡張サービスコールからサービスコールを呼び出した場合には,拡張サービスコールを呼び出したタスクが自タスクである.
カーネルには,静的APIにより,少なくとも1つのタスクを登録しなければならない.タスクが登録されていない場合には,コンフィギュレータがエラーを報告する【NGKI0033】.
【補足説明】
タスクが呼び出した拡張サービスコールが実行されている間は,「サービスコールを呼び出した処理単位」は拡張サービスコールであり,「自タスク」とは一致しない.そのため,保護機能対応カーネルにおいて,「サービスコールを呼び出した処理単位の属する保護ドメイン」と「自タスクの属する保護ドメイン」は,異なるものを指す.
(4) ディスパッチとスケジューリング
プロセッサが実行するタスクを切り換えることを,タスクディスパッチまたは単にディスパッチ(dispatching)と呼ぶ.それに対して,次に実行すべきタスクを決定する処理を,タスクスケジューリングまたは単にスケジューリング(scheduling)と呼ぶ.
ディスパッチが起こるべき状態(すなわち,スケジューリングによって,現在実行しているタスクとは異なるタスクが,実行すべきタスクに決定されている状態)となっても,何らかの理由でディスパッチを行わないことを,ディスパッチの保留(pend dispatching)という.ディスパッチを行わない理由が解除された時点で,ディスパッチが起こる【NGKI0034】.
(5) 割込みとCPU例外
プロセッサが実行中の処理とは独立に発生するイベントによって起動される例外処理のことを,外部割込みまたは単に割込み(interrupt)と呼ぶ.それに対して,プロセッサが実行中の処理に依存して起動される例外処理を,CPU例外(CPU exception)と呼ぶ.
周辺デバイスからの割込み要求をプロセッサに伝える経路を遮断し,割込み要求が受け付けられるのを抑止することを,割込みのマスク(mask interrupt)または割込みの禁止(disable interrupt)という.マスクが解除された時点で,まだ割込み要求が保持されていれば,その時点で割込み要求を受け付ける【NGKI0035】.
マスクすることができない割込みを,NMI(non-maskable interrupt)と呼ぶ.
例外処理を起こすための命令(ソフトウェア割込み命令)によって発生する例外処理を,ソフトウェア割込みと呼ぶ.ソフトウェア割込みは,特権モードで実行すべきサービスコールを呼び出すなどの目的で使用される.
【μITRON4.0仕様との関係】
μITRON4.0仕様において,未定義のまま使われていた割込みとCPU例外という用語を定義した.
(6) タイムイベント通知とタイムイベントハンドラ
時間の経過をきっかけに発生するイベントをタイムイベント(time event)と呼ぶ.タイムイベントをアプリケーションに通知する機能を,タイムイベント通知(time event notification),タイムイベントにより起動され,カーネルが実行制御する処理単位を,タイムイベントハンドラ(time event handler)と呼ぶ.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
タイムイベント通知の概念を追加した.
2.3.2 サービスコールとパラメータ
(1) 優先順位と優先度
優先順位(precedence)とは,処理単位の実行順序を説明するための仕様上の概念である.複数の処理単位が実行できる場合には,その中で最も優先順位の高い処理単位が実行される【NGKI0036】.
優先度(priority)は,タスクなどの処理単位の優先順位や,データなどの配送順序を決定するために,アプリケーションが処理単位やデータなどに与える値である.優先度は,符号付きの整数型であるPRI型で表し,1から連続した正の値を用いるのを原則とする【NGKI0037】.優先度は,値が小さいほど優先度が高い(すなわち,先に実行または配送される)ものとする【NGKI0038】.
サブ優先度(sub-priority)は,優先度が同一のタスクの間の優先順位を決定するために,アプリケーションがタスクに与える値である.サブ優先度機能をサポートするカーネルにおいては,サブ優先度を使用して優先順位を決定するか否かを,優先度毎に設定することができる【NGKI0558】.サブ優先度はuint_t型で表し,値が小さいほど優先度が高い【NGKI0559】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルは,サブ優先度機能をサポートしない【ASPS0016】.ただし,サブ優先度機能拡張パッケージを用いると,サブ優先度機能を追加することができる【ASPS0017】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルは,サブ優先度機能をサポートする【FMPS0010】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルは,サブ優先度機能をサポートしない【HRPS0012】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルは,サブ優先度機能をサポートしない【HRMPS0002】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルは,サブ優先度機能をサポートしない【SSPS0011】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
サブ優先度の概念を追加した.
(2) システム時刻と相対時間
カーネルが管理する時刻を,システム時刻(system time)と呼ぶ.システム時刻は,64ビット(ただし,64ビットの整数型がサポートされていないターゲットでは,32ビット)の符号無しの整数型であるSYSTIM型で表し,単位はマイクロ秒とする【NGKI0548】.
タイムイベントを発生させる時刻を指定する場合には,基準時刻(base time)からの相対時間(relative time)によって指定する【NGKI0041】.基準時刻は,別に規定がない限りは,相対時間を指定するサービスコールを呼び出した時刻となる【NGKI0042】.
相対時間は,32ビットの符号無しの整数型であるRELTIM型で表し,単位はシステム時刻と同一,すなわちマイクロ秒とする【NGKI0549】.相対時間に指定できる最大値は,4,000,000,000(66分40秒を表す)である【NGKI0550】.この値は,構成マクロTMAX_RELTIMに定義されている【NGKI0551】.
タイムイベントを発生させる時刻を相対時間で指定した場合,タイムイベントが処理されるのは,基準時刻から相対時間によって指定した以上の時間が経過した後となる【NGKI0046】.
タイムイベントが発生するまでの時間を参照する場合には,基準時刻からの相対時間として返される【NGKI0048】.基準時刻は,相対時間を返すサービスコールを呼び出した時刻となる【NGKI0049】.
タイムイベントが発生する時刻が相対時間で返された場合,タイムイベントが処理されるのは,基準時刻から相対時間として返された以上の時間が経過した後となる【NGKI0050】.何らかの理由でタイムイベントの処理が遅れ,タイムイベントが発生する時刻をすでに過ぎている場合には,相対時間として0が返される【NGKI0552】.
【補足説明】
サービスコールで相対時間に0を指定した場合には,高分解能タイマが基準時刻後に最初にカウントアップするのをきっかけに,タイムイベントが処理される.また,1を指定した場合には,基準時刻後に2回目にカウントアップするのをきっかけに,タイムイベントが処理される.これは,基準時刻後の最初のカウントアップは,基準時刻の直後に発生する可能性があるため,ここでタイムイベントを処理すると,基準時刻からの経過時間が1以上という仕様を満たせないためである.
同様に,相対時間として0が返された場合には,それ以降の可能な限り早いタイミングでタイムイベントが処理される.1が返された場合には,基準時刻後の2回目のカウントアップをきっかけにタイムイベントが処理される.
ただし,保護機能対応カーネルで時間パーティショニングを使用する場合には,ユーザドメインに属するタイムイベントの処理は,そのユーザドメインが実行されるタイムウィンドウに切り換わるまで実行されない.詳しくは,「2.6.7 時間パーティショニング使用時のスケジューリング規則」の節を参照すること.
【μITRON4.0仕様との関係】
システム時刻(SYSTIM型)と相対時間(RELTIM型)の時間単位は,μITRON4.0仕様では実装定義としていたが,この仕様ではマイクロ秒と規定した.また,システム時刻と相対時間のビット長を定め,相対時間の解釈についてより厳密に規定した.TMAX_RELTIMは,μITRON4.0仕様に規定されていないカーネル構成マクロである.
【TOPPERS新世代カーネル統合仕様との関係】
システム時刻(SYSTIM型)と相対時間(RELTIM型)の時間単位は,TOPPERS新世代カーネル統合仕様ではミリ秒としていたが,この仕様ではマイクロ秒に変更した.また,システム時刻と相対時間のビット長を定め,相対時間に指定できる最大値を規定した.相対時間の解釈について,タイムティックを使わない実装を想定した規定に変更した.
【仕様決定の理由】
相対時間に指定できる最大値を4,000,000,000に制限したのは,タイムイベントを発生させる時刻を,カーネル内部では32ビットの整数型で扱えるようにするためである.
(3) タイムアウトとポーリング
サービスコールの中で待ち状態が指定した時間以上継続した場合に,サービスコールの処理を取りやめて,サービスコールからリターンすることを,タイムアウト(timeout)という.タイムアウトしたサービスコールからは,E_TMOUTエラーが返る【NGKI0052】.
タイムアウトを起こすまでの時間(タイムアウト時間)は,32ビットの符号無しの整数型であるTMO型で表し,単位はシステム時刻と同一,すなわちマイクロ秒とする【NGKI0553】.タイムアウト時間に,0より大きく,TMAX_RELTIM以下の値を指定した場合には,タイムアウトを起こすまでの相対時間を表す【NGKI0554】.すなわち,タイムアウトの処理が行われるのは,サービスコールを呼び出してから指定した以上の時間が経過した後となる.
ポーリング(polling)を行うサービスコールとは,サービスコールの中で待ち状態に遷移すべき状況になった場合に,サービスコールの処理を取りやめてリターンするサービスコールのことをいう.ここで,サービスコールの処理を取りやめてリターンすることを,ポーリングに失敗したという.ポーリングに失敗したサービスコールからは,E_TMOUTエラーが返る【NGKI0055】.
ポーリングを行うサービスコールでは,待ち状態に遷移することはないのが原則である【NGKI0056】.そのため,ポーリングを行うサービスコールは,ディスパッチ保留状態であっても呼び出せる【NGKI0057】.ただし,サービスコールの中で待ち状態に遷移する状況が複数ある場合,ある状況でポーリング動作をしても,他の状況では待ち状態に遷移する場合がある.このような場合の振舞いは,該当するサービスコール毎に規定する【NGKI0058】.
タイムアウト付きのサービスコールは,別に規定がない限りは,タイムアウト時間にTMO_POL(=0)を指定した場合にはポーリングを行い,TMO_FEVR(=UINT32_MAX)を指定した場合にはタイムアウトを起こさないものとする【NGKI0059】.
【補足説明】
相対時間の0(基準時刻後の最初のカウントアップをきっかけにタイムイベントを処理)とタイムアウト時間のTMO_POL(=0,ポーリング)は意味が異なる.具体的な例として,dly_tsk(0U)を呼び出したタスクは待ち状態に遷移するのに対して,tslp_tsk(TMO_POL)を呼び出したタスクは待ち状態には遷移しない.
[NGKI0019]の原則より,サービスコールがタイムアウトした場合やポーリングに失敗した場合には,サービスコールによる副作用がないのが原則である.ただし,そのような実装ができない場合にはこの原則の例外とし,どのような副作用があるかをサービスコール毎に規定する.
タイムアウト付きのサービスコールを,タイムアウト時間をTMO_POLとして呼び出した場合には,ディスパッチ保留状態で呼び出すとE_CTXエラーとなることを除いては,ポーリングを行うサービスコールと同じ振舞いをする.また,タイムアウト時間をTMO_FEVRとして呼び出した場合には,タイムアウトなしのサービスコールと全く同じ振舞いをする.
【μITRON4.0仕様との関係】
タイムアウト時間(TMO型)の時間単位は,μITRON4.0仕様では実装定義としていたが,この仕様ではマイクロ秒と規定した.また,TMO型を符号無し整数に変更するとともに,ビット長を定め,指定できる最大値を規定した.
【TOPPERS新世代カーネル統合仕様との関係】
タイムアウト時間(TMO型)の時間単位は,TOPPERS新世代カーネル統合仕様ではミリ秒単位としていたが,この仕様ではマイクロ秒に変更した.また,TMO型を符号無し整数に変更するとともに,ビット長を定め,指定できる最大値を規定した.
【仕様決定の理由】
ディスパッチ保留状態において,ポーリングを行うサービスコールを呼び出せる場合があるのに対して,タイムアウト付きのサービスコールをタイムアウト時間をTMO_POLとして呼び出すとエラーになるのは,割込み優先度マスクが全解除でない状態やディスパッチ禁止状態では,自タスクを広義の待ち状態に遷移させる可能性のあるサービスコール(タイムアウト付きのサービスコールはこれに該当)を呼び出すことはできないという原則[NGKI0175]と[NGKI0179]があるためである.
(4) ノンブロッキング
サービスコールの中で待ち状態に遷移すべき状況になった時,サービスコールの処理を継続したままサービスコールからリターンする場合,そのサービスコールをノンブロッキング(non-blocking)という.処理を継続したままリターンする場合,サービスコールからはE_WBLKエラーが返る【NGKI0060】.E_WBLKは警告を表すエラーコードであり,サービスコールによる副作用がないという原則は適用されない【NGKI0061】.
サービスコールからE_WBLKエラーが返った場合には,サービスコールの処理は継続しているため,サービスコールに渡したパラメータまたはリターンパラメータを入れる領域はまだアクセスされる可能性があり,別の目的に使用することはできない【NGKI0062】.継続している処理が完了した場合や,何らかの理由で処理が取りやめられた場合には,コールバックを呼び出すなどの方法で,サービスコールを呼び出したソフトウェアに通知するものとする【NGKI0063】.
ノンブロッキングの指定は,タイムアウト時間にTMO_NBLK(=UINT32_MAX-1)を指定することによって行う【NGKI0064】.ノンブロッキングの指定を行えるサービスコールは,指定した場合の振舞いをサービスコール毎に規定する【NGKI0065】.
【補足説明】
ノンブロッキングは,システムサービスでサポートすることを想定した機能である.カーネルは,ノンブロッキングの指定を行えるサービスコールをサポートしていない.
(5) プロセッサ時間
プロセッサが処理単位の実行に要した時間をプロセッサ時間(processor time)と呼ぶ.プロセッサ時間は,32ビットの符号無しの整数型であるPRCTIM型で表し,単位はマイクロ秒とする【NGKI0573】.プロセッサ時間の計測精度は,ターゲットに依存する【NGKI0574】.
【補足説明】
プロセッサ時間は,処理単位の実行に要した時間であり,システム時刻の経過とは独立である.そのため,システム時刻の調整やドリフトの調整によって,プロセッサ時間の進み方が変わることはない.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様では,プロセッサ時間の概念はオーバランハンドラ機能のみで使用され,データ型の名称もOVRTIMであったが,この仕様では,時間パーティショニング機能でも使用するため,概念を一般化し,PRCTIM型に改名した.また,PRCTIM型のビット長を定めた.
2.3.3 保護機能
この節では,保護機能に関連する主な概念について説明する.この節の内容は,保護機能対応カーネルにのみ適用される.
【TOPPERS新世代カーネル統合仕様との関係】
ユーザドメインに属する処理単位がタスクの優先度を変更する際に,指定できるタスク優先度を制限することができる機能を廃止した.
(1) アクセス保護
保護機能対応カーネルは,処理単位が,許可されたカーネルオブジェクトに対して,許可された種別のアクセスを行うことのみを許し,それ以外のアクセスを防ぐアクセス保護機能を提供する【NGKI0066】.
アクセス制御の用語では,処理単位が主体(subject),カーネルオブジェクトが対象(object)ということになる.
(2) メモリオブジェクト
保護機能対応カーネルにおいては,メモリ領域をカーネルオブジェクトとして扱い,アクセス保護の対象とする【NGKI0067】.カーネルがアクセス保護の対象とする連続したメモリ領域を,メモリオブジェクト(memory object)と呼ぶ.メモリオブジェクトは,互いに重なりあうことはない【NGKI0068】.
メモリオブジェクトは,その先頭番地によって識別する【NGKI0069】.言い換えると,先頭番地がオブジェクト番号となる.
メモリオブジェクトの先頭番地とサイズには,ターゲットハードウェアでメモリ保護が実現できるように,ターゲット定義の制約が課せられる【NGKI0070】.
(3) 保護ドメイン
保護機能を提供するために用いるカーネルオブジェクトの集合を,保護ドメイン(protection domain)と呼ぶ.保護ドメインは,保護ドメインIDと呼ぶID番号によって識別する【NGKI0071】.
カーネルオブジェクトは,たかだか1つの保護ドメインに属する.処理単位は,いずれか1つの保護ドメインに属さなければならないのに対して,それ以外のカーネルオブジェクトは,いずれの保護ドメインにも属さないことができる【NGKI0072】.いずれの保護ドメインにも属さないカーネルオブジェクトを,無所属のカーネルオブジェクト(independent kernel object)と呼ぶ.
処理単位がカーネルオブジェクトにアクセスできるかどうかは,処理単位が属する保護ドメインにより決まるのが原則である【NGKI0073】.すなわち,カーネルオブジェクトに対するアクセス権は,処理単位ではなく,保護ドメイン単位で管理される.このことから,ある保護ドメインに属する処理単位がアクセスできることを,単に,その保護ドメインからアクセスできるという.
ただし,タスクのユーザスタック領域は,ターゲット定義での変更がない限りは,そのタスク(とカーネルドメインに属する処理単位)のみがアクセスできる(「2.11.6 ユーザタスクのユーザスタック領域」の節を参照).これは,[NGKI0073]の原則の例外となっている.
デフォルトでは,保護ドメインに属するカーネルオブジェクトは,同じ保護ドメイン(とカーネルドメイン)のみからアクセスできる【NGKI0075】.また,無所属のカーネルオブジェクトは,すべての保護ドメインからアクセスできる【NGKI0076】.詳しくは,「2.11.3 デフォルトのアクセス許可ベクタ」の節を参照すること.
(4) カーネルドメインとユーザドメイン
システムには,カーネルドメイン(kernel domain)と呼ばれる保護ドメインが1つ存在する【NGKI0077】.カーネルドメインに属する処理単位は,プロセッサの特権モードで実行される【NGKI0078】.また,すべてのカーネルオブジェクトに対して,すべての種別のアクセスを行うことが許可される【NGKI0079】.この仕様で,「ある保護ドメイン(またはタスク)のみからアクセスできる」といった場合でも,カーネルドメインからはアクセスすることができる.
カーネルドメイン以外の保護ドメインを,ユーザドメイン(user domain)と呼ぶ.ユーザドメインに属する処理単位は,プロセッサの非特権モードで実行される【NGKI0080】.また,どのカーネルオブジェクトに対してどの種別のアクセスを行えるかを制限することができる【NGKI0081】.
ユーザドメインには,1から連続する正の整数値の保護ドメインIDが付与される【NGKI0082】.カーネルドメインの保護ドメインIDは,TDOM_KERNEL(=-1)である【NGKI0083】.
この仕様では,システムに登録できるユーザドメインの数は,32個以下に制限する【NGKI0084】.これを超える数のユーザドメインを登録した場合には,コンフィギュレータがエラーを報告する【NGKI0085】.
【補足説明】
ユーザドメインは,システムコンフィギュレーションファイル中にユーザドメインの囲みを記述することで,カーネルに登録する(「2.12.3 保護ドメインの指定」の節を参照).ユーザドメインを動的に生成する機能は,現時点では用意していない.
保護機能対応でないカーネルは,カーネルドメインのみをサポートしているとみなすことができる.
【μITRON4.0/PX仕様との関係】
μITRON4.0/PX仕様のシステムドメイン(system domain)は,現時点ではサポートしない.システムドメインは,それに属する処理単位が,プロセッサの特権モードで実行され,カーネルオブジェクトに対するアクセスを制限することができる保護ドメインである.
(5) システムタスクとユーザタスク
カーネルドメインに属するタスクをシステムタスク(system task),ユーザドメインに属するタスクをユーザタスク(user task)と呼ぶ.
【補足説明】
特権モードで実行されるタスクをシステムタスク,非特権モードで実行されるタスクをユーザタスクと定義する方法もあるが,ユーザタスクであっても,サービスコールの実行中は特権モードで実行されるため,曖昧性を避けるために上記の定義とした.
μITRON4.0/PX仕様のシステムドメインに属するタスクは,システムタスクと呼ぶことになる.
(6) アクセス許可パターン
あるカーネルオブジェクトに対するある種別のアクセスが,どの保護ドメインに属する処理単位に許可されているかを表現するビットパターンを,アクセス許可パターン(access permission pattern)と呼ぶ.アクセス許可パターンの各ビットは,1つのユーザドメインに対応する【NGKI0086】.カーネルドメインには,すべてのアクセスが許可されているため,カーネルドメインに対応するビットは用意されていない.
アクセス許可パターンは,符号無し32ビット整数に定義されるデータ型(ACPTN)で保持し,値が1のビットに対応するユーザドメインにアクセスが許可されていることを表す【NGKI0087】.そのため,2つのアクセス許可パターンのビット毎論理和(C言語の"|")を求めることで,アクセスを許可されているユーザドメインの和集合(union)を得ることができる.また,2つのアクセス許可パターンのビット毎論理積(C言語の"&")を求めることで,アクセスを許可されているユーザドメインの積集合(intersection)を得ることができる.
アクセス許可パターンの指定に用いるために,指定したユーザドメインのみにアクセスを許可することを示すアクセス許可パターンを構成するマクロ(TACP)が用意されている【NGKI0088】.また,カーネルドメインのみにアクセスを許可することを示すアクセス許可パターンを表す定数(TACP_KERNEL)と,すべての保護ドメインにアクセスを許可することを示すアクセス許可パターンを表す定数(TACP_SHARED)が用意されている【NGKI0089】.
(7) アクセス許可ベクタ
カーネルオブジェクトに対するアクセスは,カーネルオブジェクトの種類毎に,通常操作1,通常操作2,管理操作,参照操作の4つの種別に分類されている【NGKI0090】.あるカーネルオブジェクトに対する4つの種別のアクセスに関するアクセス許可パターンをひとまとめにしたものを,アクセス許可ベクタ(access permission vector)と呼び,次のように定義されるデータ型(ACVCT)で保持する【NGKI0091】.
typedef struct acvct {
ACPTN acptn1; /* 通常操作1のアクセス許可パターン */
ACPTN acptn2; /* 通常操作2のアクセス許可パターン */
ACPTN acptn3; /* 管理操作のアクセス許可パターン */
ACPTN acptn4; /* 参照操作のアクセス許可パターン */
} ACVCT;
【補足説明】
カーネルオブジェクトの種類毎のアクセスの種別の分類については,「5.8 カーネルオブジェクトに対するアクセスの種別」の節を参照すること.
【μITRON4.0/PX仕様との関係】
μITRON4.0/PX仕様では,アクセス許可ベクタを,1つまたは2つのアクセス許可パターンで構成することも許しているが,この仕様では4つで構成するものと決めている.
(8) サービスコールの呼出し方法
保護機能対応カーネルでは,サービスコールは,ソフトウェア割込みによって呼び出すのが基本である.サービスコール呼出しを通常の方法で記述した場合,サービスコールはソフトウェア割込みによって呼び出される【NGKI0092】.
一般に,ソフトウェア割込みによるサービスコール呼出しはオーバヘッドが大きい.そのため,カーネルドメインに属する処理単位からは,関数呼出しによってサービスコールを呼び出すことで,オーバヘッドを削減することができる.そこで,カーネルドメインに属する処理単位から関数呼出しによってサービスコールを呼び出せるように,以下の機能が用意されている.
カーネルドメインに属する処理単位が実行する関数のみを含んだソースファイルでは,カーネルヘッダファイル(kernel.h)をインクルードする前に,TOPPERS_SVC_CALLをマクロ定義することで,サービスコール呼出しを通常の方法で記述した場合に,サービスコールは関数呼出しによって呼び出される【NGKI0093】.
また,カーネルドメインに属する処理単位が実行する関数と,ユーザドメインに属する処理単位が実行する関数の両方を含んだソースファイルでは,関数呼出しによってサービスコールを呼び出すための名称を作るマクロ(SVC_CALL)を用いることで,サービスコールは関数呼出しによって呼び出される【NGKI0094】.例えば,act_tskを関数呼出しによって呼び出す場合には,次のように記述すればよい.
ercd = SVC_CALL(act_tsk)(tskid);
【補足説明】
拡張サービスコールを,関数呼出しによって呼び出す方法は用意されていない.カーネルドメインに属する処理単位が,関数呼出しによって拡張サービスコールとして登録した関数を呼び出すことはできるが,その場合,呼び出したのは単なる関数であるとみなされ,拡張サービスコールであるとは扱われない.
2.3.4 時間パーティショニング
この節では,保護機能対応カーネルにおける時間パーティショニングに関連する主な概念について説明する.この節の内容は,保護機能対応カーネルにのみ適用される.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
時間パーティショニングの機能を新たに導入した.
(1) システム周期
保護ドメインを繰り返し実行する基本的な周期を,システム周期(system cycle)と呼ぶ.
(2) システム動作モード
保護ドメインをどのように繰り返し実行するかは,システム動作モード(system operating mode)毎に設定することができる.システム動作モードは,システム動作モードIDと呼ぶID番号によって識別する【NGKI0577】.
保護ドメインを繰り返し実行するのを停止するシステム動作モードとして,システム周期停止モードが用意されている【NGKI0578】.システム周期停止モードのID番号は,TSOM_STP(=-1)である【NGKI0579】.
(3) タイムウィンドウとアイドルウィンドウ
システム周期内の連続した時間区間をタイムウィンドウ(time window)と呼ぶ.タイムウィンドウは,システム動作モード毎に登録することができる【NGKI0580】.
システム周期内で,タイムウィンドウに含まれない時間区間を,アイドルウィンドウ(idle window)と呼ぶ.
タイムウィンドウは,1つのユーザドメインに割り当てる【NGKI0581】.1つのユーザドメインに,任意の数のタイムウィンドウを割り当てることができる【NGKI0582】.すなわち,1つのユーザドメインに複数のタイムウィンドウを割り当てることができるし,タイムウィンドウを割り当てないユーザドメインがあっても良い.
どのシステム動作モードにおいてもタイムウィンドウを割り当てられていないユーザドメインが1つ以上ある場合,スケジューリング上は,それらのユーザドメインをまとめて1つのユーザドメインであるかのように扱う【NGKI0583】.タイムウィンドウを割り当てられていないユーザドメインを1つにまとめたものを,アイドルドメイン(idle domain)と呼ぶ.あるオブジェクトが「アイドルドメインに属する」といった場合には,タイムウィンドウを割り当てられていないユーザドメインのいずれかに属することを意味する.
カーネルドメインにタイムウィンドウを割り当てることはできない.カーネルドメインに属する処理単位(ユーザタスクから呼び出された拡張サービスコールを除く)は,常に(すなわち,すべてのタイムウィンドウおよびアイドルウィンドウ内で)実行することができる【NGKI0623】.
マルチプロセッサ対応カーネルでは,タイムウィンドウは,プロセッサ毎に割り当てることができる【NGKI0624】.アイドルドメインにまとめられるのは,すべてのシステム動作モードにおいて,どのプロセッサに対してもタイムウィンドウを割り当てられていないユーザドメインである【NGKI0627】.
【使用上の注意】
あるユーザドメインに対して,システム動作モードAにおいてはタイムウィンドウが割り当てられており,システム動作モードBにおいては割り当てられていない場合を考える.この場合,そのユーザドメインは,システム動作モードAにおいてタイムウィンドウを割り当てられているため,アイドルドメインにはまとめられない.そのため,システム動作モードBでは,そのユーザドメインは全く実行されない.
2.3.5 マルチプロセッサ対応
この節では,マルチプロセッサ対応に関連する主な概念について説明する.この節の内容は,マルチプロセッサ対応カーネルにのみ適用される.
(1) クラス
マルチプロセッサに対応するために用いるカーネルオブジェクトの集合を,クラス(class)と呼ぶ.クラスは,クラスIDと呼ぶID番号によって識別する【NGKI0095】.カーネルオブジェクトは,たかだか1つのクラスに属する【NGKI0096】.
カーネルがどのようなクラスをサポートするかと,それらの識別名とID番号は,ターゲット定義である【NGKI0644】.カーネルヘッダファイル(kernel.h)のターゲット依存部において,各クラスの識別名が,クラスIDにマクロ定義される【NGKI0645】.
【補足説明】
処理単位を実行するプロセッサを静的に決定する機能分散型のマルチプロセッサシステムでは,プロセッサ毎にクラスを設ける方法が典型的である.それに対して,対称型のマルチプロセッサシステムで,処理単位のマイグレーションを許す場合には,プロセッサ毎のクラスに加えて,どのプロセッサでも実行できるクラスを(システム中に1つまたは初期割付けプロセッサ毎に)設ける方法が典型的である.
マルチプロセッサ対応でないカーネルは,カーネルによって規定された1つのクラスのみをサポートしているとみなすこともできる.
(2) プロセッサ
たかだか1つの処理単位のみを同時に実行できるハードウェアの単位を,プロセッサ(processor)と呼ぶ.プロセッサは,プロセッサIDと呼ぶID番号によって識別する【NGKI0098】.
複数のプロセッサを持つシステム構成をマルチプロセッサ(multiprocessor)と呼ぶ.マルチプロセッサ対応カーネルは,同時に複数の処理単位を実行することができる【NGKI0099】.
カーネルがサポートするプロセッサの数と各プロセッサの識別名は,ターゲット定義である【NGKI0642】.カーネルヘッダファイル(kernel.h)のターゲット依存部において,TNUM_PRCIDがサポートしているプロセッサ数に,各プロセッサの識別名がプロセッサIDに,それぞれマクロ定義される【NGKI0643】.
システムの初期化時と終了時に特別な役割を果たすプロセッサを,マスタプロセッサ(master processor)と呼び,システムに1つ存在する【NGKI0100】.どのプロセッサをマスタプロセッサとするかは,ターゲット定義である【NGKI0101】.マスタプロセッサ以外のプロセッサを,スレーブプロセッサ(slave processor)と呼ぶ.なお,カーネル動作状態では,マスタプロセッサとスレーブプロセッサの振舞いに違いはない【NGKI0102】.
(3) 処理単位の割付けとマイグレーション
処理単位は,後述のマイグレーションが発生しない限りは,いずれか1つのプロセッサに割り付けられて実行される【NGKI0103】.処理単位を実行するプロセッサを,割付けプロセッサと呼ぶ.また,処理単位が登録時に割り付けられるプロセッサを,初期割付けプロセッサと呼ぶ.
処理単位によっては,処理単位の登録後に,割付けプロセッサを変更することが可能である【NGKI0104】.処理単位の登録後に割付けプロセッサを変更することを,処理単位のマイグレーション(migration)と呼ぶ.
割付けプロセッサを変更できる処理単位に対しては,処理単位を割り付けることができるプロセッサ(これを,割付け可能プロセッサと呼ぶ)を制限することができる【NGKI0105】.
(4) クラスの持つ属性とカーネルオブジェクト
タスクの初期割付けプロセッサや割付け可能プロセッサなど,カーネルオブジェクトをマルチプロセッサ上で実現する際に設定すべき属性は,そのカーネルオブジェクトが属するクラスによって定まる.
各クラスは,ターゲット定義の属性として,初期割付けプロセッサと割付け可能プロセッサ(初期割付けプロセッサを含む1つまたは複数のプロセッサ)の情報を持つ【NGKI0107】.また,保護機能に対応しないカーネルにおいては,オブジェクトを生成する際にコンフィギュレータが確保するメモリ領域(オブジェクトの管理ブロックなど)の配置場所も,ターゲット定義である【NGKI0664】.
【仕様決定の理由】
初期割付けプロセッサと割付け可能プロセッサを,カーネルオブジェクト毎に設定できるようにしなかったのは,これらの属性をアプリケーション設計者が個別に設定するよりも,ターゲット依存部の実装者が有益な組み合わせをあらかじめクラスとして用意しておく方が良いと考えたためである.
(5) タイムイベント処理プロセッサ
タイムイベントの処理は,ターゲット定義の1つまたは複数のプロセッサで行う【NGKI0622】.タイムイベントを処理するプロセッサを,タイムイベント処理プロセッサと呼ぶ.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,すべてのプロセッサがタイムイベント処理プロセッサである【HRMPS0011】.すなわち,すべてのプロセッサがタイムイベントの処理を行う.
【TOPPERS新世代カーネル統合仕様との関係】
TOPPERS新世代カーネル統合仕様では,プロセッサ毎にシステム時刻を持つローカルタイマ方式と,システム全体で1つのシステム時刻を持つグローバルタイマ方式のどちらかを用いることとしていたが,この仕様では,システム全体で1つのシステム時刻を持つものと決めた.ただし,タイムイベント処理プロセッサを複数設けられることから,TOPPERS新世代カーネル統合仕様のグローバルタイマ方式とも異なる.これに伴い,ローカルタイマ方式とグローバルタイマ方式という用語を廃止した.
2.3.6 その他
【TOPPERS新世代カーネル統合仕様との関係】
保護ドメイン毎の標準セクションを廃止した.
(1) オブジェクトモジュール
プログラムのオブジェクトコードとデータを含むファイルを,オブジェクトモジュール(object module)と呼ぶ.オブジェクトファイルとライブラリは,オブジェクトモジュールである.
(2) メモリリージョン
オブジェクトモジュールに含まれるセクションの配置対象となる同じ性質を持った連続したメモリ領域をメモリリージョン(memory region)と呼ぶ.
メモリリージョンは,文字列によって識別する【NGKI0112】.メモリリージョンを識別する文字列を,メモリリージョン名と呼ぶ.
【μITRON4.0/PX仕様との関係】
メモリリージョンは,μITRON4.0/PX仕様にはない概念である.
(3) 標準のセクション
コンパイラに特別な指定をしない場合に出力するセクションを,標準のセクション(standard sections)と呼ぶ.ターゲット定義で,それ以外のセクションを標準のセクションと扱う場合もある【NGKI0113】.
(4) 自動メモリ配置と手動メモリ配置
保護機能対応カーネルにおいては,カーネルに登録されたオブジェクトモジュールやセクションをどの番地に配置するかはコンフィギュレータにより決定され,リンカスクリプトもコンフィギュレータにより生成されるのが標準である.これを,自動メモリ配置と呼ぶ.
それに対して,オブジェクトモジュールやセクションをどの番地に配置するかを,アプリケーションで用意するリンカスクリプトで決定する方法を,手動メモリ配置と呼ぶ.手動メモリ配置をサポートするかどうかは,ターゲット定義である【NGKI0608】.
【TOPPERS新世代カーネル統合仕様との関係】
手動メモリ配置の機能を新たに導入した.
2.4 処理単位の種類と実行順序
2.4.1 処理単位の種類
カーネルが実行を制御する処理単位の種類は次の通りである【NGKI0533】.
(a) タスク
(b) 割込みハンドラ
(b.1) 割込みサービスルーチン
(b.2) タイムイベントハンドラ
(c) CPU例外ハンドラ
(d) 拡張サービスコール
(e) 初期化ルーチン
(f) 終了処理ルーチン
ここで,タイムイベントハンドラとは,時間の経過をきっかけに起動される処理単位である周期ハンドラ,アラームハンドラ,オーバランハンドラの総称である.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,オーバランハンドラと拡張サービスコールをサポートしていない【ASPS0003】.ただし,オーバランハンドラ機能拡張パッケージを用いると,オーバランハンドラ機能を追加することができる【ASPS0004】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,オーバランハンドラと拡張サービスコールをサポートしていない【FMPS0002】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,オーバランハンドラをサポートしていない【HRPS0013】.ただし,オーバランハンドラ機能拡張パッケージを用いると,オーバランハンドラ機能を追加することができる【HRPS0014】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,オーバランハンドラをサポートしていない【HRMPS0003】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,タイムイベントハンドラと拡張サービスコールをサポートしていない【SSPS0002】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
タスク例外処理ルーチンを廃止した.
2.4.2 処理単位の実行順序
処理単位の実行順序を規定するために,ここでは,処理単位の優先順位を規定する.また,ディスパッチが起こるタイミングを規定するために,ディスパッチを行うカーネル内の処理であるディスパッチャの優先順位についても規定する.
タスクの優先順位は,ディスパッチャの優先順位よりも低い【NGKI0118】.タスク間では,高い優先度を持つ方が優先順位が高く,同じ優先度を持つタスク間では,別に規定がない限りは,先に実行できる状態となった方が優先順位が高い【NGKI0119】.詳しくは,「2.6.3 タスクのスケジューリング規則」の節を参照すること.
割込みハンドラの優先順位は,ディスパッチャの優先順位よりも高い【NGKI0121】.割込みハンドラ間では,高い割込み優先度を持つ方が優先順位が高く,同じ割込み優先度を持つ割込みハンドラ間では,先に実行開始された方が優先順位が高い【NGKI0122】.同じ割込み優先度を持つ割込みハンドラ間での実行開始順序は,この仕様では規定しない.詳しくは,「2.7.2 割込み優先度」の節を参照すること.
割込みサービスルーチンとタイムイベントハンドラの優先順位は,それを呼び出す割込みハンドラと同じである【NGKI0123】.
CPU例外ハンドラの優先順位は,CPU例外がタスクで発生した場合には,ディスパッチャの優先順位と同じであるが,ディスパッチャよりも先に実行される【NGKI0124】.CPU例外がその他の処理単位で発生した場合には,その処理単位の優先順位と同じであるが,その処理単位よりも先に実行される【NGKI0125】.
拡張サービスコールの優先順位は,それを呼び出した処理単位と同じであるが,それを呼び出した処理単位よりも先に実行される【NGKI0126】.
初期化ルーチンの実行順序については「2.9.1 システム初期化手順」の節で,終了処理ルーチンの実行順序については「2.9.2 システム終了手順」の節で説明する.
【仕様決定の理由】
終了処理ルーチンを,登録する静的APIを記述したのと逆順で実行するのは,終了処理は初期化の逆の順序で行うのがよいためである(システムコンフィギュレーションファイルを分割すると,終了処理ルーチンを登録する静的APIだけ逆順に記述するのは難しい).
2.4.3 カーネル処理の不可分性
カーネルのサービスコール処理やディスパッチャ,割込みハンドラとCPU例外ハンドラの入口処理と出口処理などのカーネル処理は不可分に実行されるのが基本である.実際には,カーネル処理の途中でアプリケーションが実行される場合はあるが,アプリケーションがサービスコールを用いて観測できる範囲で,カーネル処理が不可分に実行された場合と同様に振る舞うのが原則である【NGKI0133】.これを,カーネル処理の不可分性という.
ただし,マルチプロセッサ対応カーネルにおいては,カーネル処理が実行されているプロセッサ以外のプロセッサから,カーネル処理の途中の状態が観測できる場合がある.具体的には,1つのサービスコールにより複数のオブジェクトの状態が変化する場合に,一部のオブジェクトの状態のみが変化し,残りのオブジェクトの状態が変化していない過渡的な状態が観測できる場合がある【NGKI0134】.
【補足説明】
マルチプロセッサ対応でないカーネルでは,1つのサービスコールにより複数のタスクが実行できる状態になる場合,新しく実行状態となるべきタスクへのディスパッチは,すべてのタスクの状態遷移が完了した後に行われる.例えば,低優先度のタスクAが発行したサービスコールにより,中優先度のタスクBと高優先度のタスクCがこの順で待ち解除される場合,タスクBとタスクCが待ち解除された後に,タスクCへのディスパッチが行われる.
マルチプロセッサ対応カーネルでは,上のことは,1つのプロセッサ内では成り立つが,他のプロセッサに割り付けられたタスクに対しては成り立たない.例えば,プロセッサ1で低優先度のタスクAが実行されている時に,他のプロセッサ2で実行されているタスクが発行したサービスコールにより,プロセッサ1に割り付けられた中優先度のタスクBと高優先度のタスクCがこの順で待ち解除される場合,タスクCが待ち解除される前に,タスクBへディスパッチされる場合がある.
2.4.4 処理単位を実行するプロセッサ
マルチプロセッサ対応カーネルでは,処理単位を実行するプロセッサ(割付けプロセッサ)は,その処理単位が属するクラスの初期割付けプロセッサと割付け可能プロセッサから,次のように決まる.
タスク,周期ハンドラ,アラームハンドラは,登録時に,属するクラスの初期割付けプロセッサに割り付けられる【NGKI0135】.また,割付けプロセッサを変更するサービスコール(mact_tsk,mig_tsk,msta_cyc,msta_alm)によって,割付けプロセッサを,クラスの割付け可能プロセッサのいずれかに変更することができる【NGKI0136】.
割込みハンドラ,ローカル初期化ルーチン,ローカル終了処理ルーチンは,属するクラスの初期割付けプロセッサで実行される【NGKI0137】.クラスの割付け可能プロセッサの情報は用いられない.
割込みサービスルーチンは,属するクラスの割付け可能プロセッサのいずれかで実行される【NGKI0138】.この場合,クラスの初期割付けプロセッサの情報は用いられない.ただし,割込みを複数のプロセッサで受け付けることができないターゲットシステムでは,ターゲット定義で,割込みサービスルーチンは,属するクラスの初期割付けプロセッサのみで実行されるものとする【NGKI0656】.
CPU例外ハンドラは,CPU例外が発生したプロセッサで実行される【NGKI0660】.属するクラスの割付け可能プロセッサは,そのCPU例外が発生する可能性があるプロセッサと一致していなければならない【NGKI0308】.クラスの初期割付け可能プロセッサの情報は用いられない.
以上を整理すると,次の表の通りとなる.この表の中で,「○」はその情報が使用されることを,「△」はターゲットによってはその情報が使用される場合があることを,「−」はその情報が使用されないことを示す.
初期割付けプロセッサ |
割付け可能プロセッサ |
|
タスク |
○ |
○ |
割込みハンドラ |
○ |
− |
割込みサービスルーチン |
△ |
○ |
周期ハンドラ |
○ |
○ |
アラームハンドラ |
○ |
○ |
CPU例外ハンドラ |
− |
○ |
ローカル初期化ルーチン |
○ |
− |
ローカル終了処理ルーチン |
○ |
− |
オーバランハンドラ,拡張サービスコール,グローバル初期化ルーチン,グローバル終了処理ルーチンは,いずれのクラスにも属さない【NGKI0139】.オーバランハンドラは,オーバランを起こしたタスクの割付けプロセッサによって実行される【NGKI0140】.拡張サービスコールは,それを呼び出した処理単位の割付けプロセッサによって実行される【NGKI0141】.グローバル初期化ルーチンとグローバル終了処理ルーチンは,マスタプロセッサによって実行される【NGKI0142】.
【TOPPERS新世代カーネル統合仕様との関係】
割込みサービスルーチンを実行するプロセッサを,ターゲット定義で,属するクラスの初期割付けプロセッサのみとしても良いこととした.
複数のプロセッサで共通のCPU例外を許した(「2.8.1 CPU例外処理の流れ」の節を参照)ことに伴い,CPU例外が発生する可能性があるプロセッサを,CPU例外ハンドラが属するクラスの割付け可能プロセッサと一致させることとし,初期割付け可能プロセッサの情報は用いないこととした.また,CPU例外ハンドラを実行するプロセッサを,CPU例外が発生したプロセッサとした.
2.5 システム状態とコンテキスト
2.5.1 カーネル動作状態と非動作状態
カーネルの初期化が完了した後,カーネルの終了処理が開始されるまでの間を,カーネル動作状態と呼ぶ.それ以外の状態,すなわちカーネルの初期化完了前(初期化ルーチンの実行中を含む)と終了処理開始後(終了処理ルーチンの実行中を含む)を,カーネル非動作状態と呼ぶ.プロセッサは,カーネル動作状態かカーネル非動作状態のいずれかの状態を取る【NGKI0143】.
カーネル非動作状態では,原則として,NMIを除くすべての割込みがマスクされる【NGKI0144】.
カーネル非動作状態では,システムインタフェースレイヤのAPIとカーネル非動作状態を参照するサービスコール(sns_ker)のみを呼び出すことができる【NGKI0145】.カーネル非動作状態で,その他のサービスコールを呼び出した場合の動作は,保証されない【NGKI0146】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,カーネル動作状態かカーネル非動作状態のいずれかの状態を取る【NGKI0147】.
2.5.2 タスクコンテキストと非タスクコンテキスト
処理単位が実行される環境(用いるスタック領域やプロセッサの動作モードなど)をコンテキストと呼ぶ.
カーネル動作状態において,処理単位が実行されるコンテキストは,タスクコンテキストと非タスクコンテキストに分類される【NGKI0148】.
タスクが実行されるコンテキストは,タスクコンテキストに分類される【NGKI0149】.また,タスクコンテキストから呼び出した拡張サービスコールが実行されるコンテキストは,タスクコンテキストに分類される【NGKI0150】.
割込みハンドラ(割込みサービスルーチンおよびタイムイベントハンドラを含む)とCPU例外ハンドラが実行されるコンテキストは,非タスクコンテキストに分類される【NGKI0151】.また,非タスクコンテキストから呼び出した拡張サービスコールが実行されるコンテキストは,非タスクコンテキストに分類される【NGKI0152】.
タスクコンテキストで実行される処理単位は,別に規定がない限り,タスクのスタック領域を用いて実行される【NGKI0153】.非タスクコンテキストで実行される処理単位は,別に規定がない限り,非タスクコンテキスト用スタック領域を用いて実行される【NGKI0154】.
非タスクコンテキストからは,タスクコンテキスト専用のサービスコールを呼び出すことはできない.呼び出した場合にはE_CTXエラーとなる【NGKI0157】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
非タスクコンテキスト専用のサービスコールの概念を廃止し,非タスクコンテキストからも,タスクコンテキストと同じ名称のサービスコールを呼び出すこととした.
2.5.3 カーネルの振舞いに影響を与える状態
カーネル動作状態において,プロセッサは,カーネルの振舞いに影響を与える状態として,次の状態を持つ【NGKI0158】.
-
全割込みロックフラグ(全割込みロック状態と全割込みロック解除状態)
-
CPUロックフラグ(CPUロック状態とCPUロック解除状態)
-
割込み優先度マスク(割込み優先度マスク全解除状態と全解除でない状態)
-
ディスパッチ禁止フラグ(ディスパッチ禁止状態とディスパッチ許可状態)
これらの状態は,それぞれ独立な状態である.すなわち,プロセッサは上記の状態の任意の組合せを取ることができ,それぞれの状態を独立に変化させることができる【NGKI0159】.
2.5.4 全割込みロック状態と全割込みロック解除状態
プロセッサは,NMIを除くすべての割込みをマスクするための全割込みロックフラグを持つ【NGKI0160】.全割込みロックフラグがセットされた状態を全割込みロック状態,クリアされた状態を全割込みロック解除状態と呼ぶ.すなわち,全割込みロック状態では,NMIを除くすべての割込みがマスクされる.
全割込みロック状態では,システムインタフェースレイヤのAPIとカーネル非動作状態を参照するサービスコール(sns_ker),カーネルを終了するサービスコール(ext_ker)のみを呼び出すことができる【NGKI0161】.全割込みロック状態で,その他のサービスコール(拡張サービスコールを含む)を呼び出した場合の動作は,保証されない【NGKI0162】.また,全割込みロック状態で,実行中の処理単位からリターンしてはならない.リターンした場合の動作は保証されない【NGKI0164】.
保護機能対応カーネルでは,非特権モードで実行中に全割込みロック状態になることはない【NGKI0655】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,全割込みロックフラグを持つ【NGKI0165】.すなわち,プロセッサ毎に,全割込みロック状態か全割込みロック解除状態のいずれかの状態を取る.
2.5.5 CPUロック状態とCPUロック解除状態
プロセッサは,カーネル管理の割込み(「2.7.7 カーネル管理外の割込み」の節を参照)をすべてマスクするためのCPUロックフラグを持つ【NGKI0166】.CPUロックフラグがセットされた状態をCPUロック状態,クリアされた状態をCPUロック解除状態と呼ぶ.CPUロック状態では,すべてのカーネル管理の割込みがマスクされ,ディスパッチが保留される【NGKI0167】.
CPUロック状態で呼び出すことができるサービスコールは次の通り【NGKI0168】.
-
システムインタフェースレイヤのAPI
-
loc_cpu,unl_cpu
-
unl_spn(マルチプロセッサ対応カーネルのみ)
-
dis_int,ena_int,clr_int,ras_int,prb_int
-
sns_ter,sns_ctx,sns_loc,sns_dsp,sns_dpn,sns_ker
-
xsns_dpn(CPU例外ハンドラからのみ)
-
fch_hrt
-
ext_tsk,ext_ker
-
prb_mem(保護機能対応カーネルのみ)
-
cal_svc(保護機能対応カーネルのみ)
CPUロック状態で,その他のサービスコールを呼び出した場合には,E_CTXエラーとなる【NGKI0169】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,CPUロックフラグを持つ【NGKI0170】.すなわち,プロセッサ毎に,CPUロック状態かCPUロック解除状態のいずれかの状態を取る.
【補足説明】
NMI以外にカーネル管理外の割込みを設けない場合には,全割込みロックフラグとCPUロックフラグの機能は同一となるが,両フラグは独立に存在する.
マルチプロセッサ対応カーネルにおいて,あるプロセッサがCPUロック状態にある間は,そのプロセッサにおいてのみ,すべてのカーネル管理の割込みがマスクされ,ディスパッチが保留される.それに対して他のプロセッサにおいては,割込みはマスクされず,ディスパッチも起こるため,CPUロック状態を使って他のプロセッサで実行される処理単位との排他制御を実現することはできない.
2.5.6 割込み優先度マスク
プロセッサは,割込み優先度を基準に割込みをマスクするための割込み優先度マスクを持つ【NGKI0171】.割込み優先度マスクがTIPM_ENAALL(=0)の時は,いずれの割込み要求もマスクされない【NGKI0172】.この状態を割込み優先度マスク全解除状態と呼ぶ.割込み優先度マスクがTIPM_ENAALL(=0)以外の時は,割込み優先度マスクと同じかそれより低い割込み優先度を持つ割込みはマスクされ,ディスパッチは保留される【NGKI0173】.この状態を割込み優先度マスクが全解除でない状態と呼ぶ.
割込み優先度マスクが全解除でない状態では,別に規定がない限りは,自タスクを広義の待ち状態に遷移させる可能性のあるサービスコールを呼び出すことはできない.呼び出した場合には,E_CTXエラーとなる【NGKI0175】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,割込み優先度マスクを持つ【NGKI0176】.
2.5.7 ディスパッチ禁止状態とディスパッチ許可状態
プロセッサは,ディスパッチを保留するためのディスパッチ禁止フラグを持つ【NGKI0177】.ディスパッチ禁止フラグがセットされた状態をディスパッチ禁止状態,クリアされた状態をディスパッチ許可状態と呼ぶ.すなわち,ディスパッチ禁止状態では,ディスパッチは保留される.
ディスパッチ禁止状態では,別に規定がない限りは,自タスクを広義の待ち状態に遷移させる可能性のあるサービスコールを呼び出すことはできない.呼び出した場合には,E_CTXエラーとなる【NGKI0179】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,ディスパッチ禁止フラグを持つ【NGKI0180】.すなわち,プロセッサ毎に,ディスパッチ禁止状態かディスパッチ許可状態のいずれかの状態を取る.
【補足説明】
マルチプロセッサ対応カーネルにおいて,あるプロセッサがディスパッチ禁止状態にある間は,そのプロセッサにおいてのみ,ディスパッチが保留される.それに対して他のプロセッサにおいては,ディスパッチが起こるため,ディスパッチ禁止状態を使って他のプロセッサで実行されるタスクとの排他制御を実現することはできない.
2.5.8 ディスパッチ保留状態
非タスクコンテキストの実行中,CPUロック状態,割込み優先度マスクが全解除でない状態,ディスパッチ禁止状態では,ディスパッチが保留される【NGKI0181】.これらの状態を総称して,ディスパッチ保留状態と呼ぶ.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,ディスパッチ保留状態かそうでない状態のいずれかの状態を取る【NGKI0182】.
【補足説明】
全割込みロック状態はカーネルが管理しておらず,ディスパッチが保留されることをカーネルが保証できないため,ディスパッチ保留状態に含めていない.
2.5.9 カーネル管理外の状態
全割込みロック状態,カーネル管理外の割込みハンドラ実行中(「2.7.7 カーネル管理外の割込み」の節を参照),カーネル管理外のCPU例外ハンドラ実行中(「2.8.4 カーネル管理外のCPU例外」の節を参照)を総称して,カーネル管理外の状態と呼ぶ.
カーネル管理外の状態では,システムインタフェースレイヤのAPIとsns_ker,ext_kerのみ(カーネル管理外のCPU例外ハンドラからは,それに加えてxsns_dpn)を呼び出すことができ,その他のサービスコールを呼び出すことはできない【NGKI0543】.カーネル管理外の状態から,その他のサービスコールを呼び出した場合の動作は,保証されない【NGKI0544】.
カーネル管理外の状態では,少なくとも,カーネル管理の割込みはマスクされている【NGKI0545】.カーネル管理外の割込み(の一部)もマスクされている場合もある【NGKI0546】.
【補足説明】
保護機能対応カーネルでは,非特権モードで実行中にカーネル管理外の状態になることはない.
2.5.10 処理単位の開始・終了とシステム状態
各処理単位が実行開始されるシステム状態の条件(実行開始条件),各処理単位の実行開始時にカーネルによって行われるシステム状態の変更処理(実行開始時処理),各処理単位からのリターン前(または終了前)にアプリケーションが設定しておくべきシステム状態(リターン前または終了前),各処理単位からのリターン時(または終了時)にカーネルによって行われるシステム状態の変更処理(リターン時処理または終了時処理)は,次の表の通りである.
CPUロックフラグ |
割込み優先度マスク |
ディスパッチ禁止フラグ |
|
【タスク】【NGKI0183】 |
|||
実行開始条件 |
解除 |
全解除 |
許可 |
実行開始時処理 |
そのまま |
そのまま |
そのまま |
終了前 |
原則解除(*1) |
原則全解除(*1) |
原則許可(*1) |
終了時処理 |
解除する |
全解除する |
許可する |
【カーネル管理の割込みハンドラ】【NGKI0185】 |
|||
実行開始条件 |
解除 |
自優先度より低い |
任意 |
実行開始時処理 |
そのまま |
自優先度に(*2) |
そのまま |
リターン前 |
原則解除(*1) |
変更不可(*3) |
変更不可(*3) |
リターン時処理 |
解除する |
元に戻す |
そのまま |
【割込みサービスルーチン】【NGKI0566】 |
|||
【タイムイベントハンドラ】【NGKI0567】 |
|||
実行開始条件 |
解除 |
任意(*4) |
任意 |
実行開始時処理 |
そのまま |
そのまま(*4) |
そのまま |
リターン前 |
原則解除(*1) |
変更不可(*3) |
変更不可(*3) |
リターン時処理 |
解除する |
そのまま(*4) |
そのまま |
【CPU例外ハンドラ】【NGKI0188】 |
|||
実行開始条件 |
任意 |
任意 |
任意 |
実行開始時処理 |
そのまま(*6) |
そのまま |
そのまま |
リターン前 |
原則元に(*1) |
変更不可(*3) |
変更不可(*3) |
リターン時処理 |
元に戻す |
元に戻す(*5) |
そのまま |
【拡張サービスコール】【NGKI0189】 |
|||
実行開始条件 |
任意 |
任意 |
任意 |
実行開始時処理 |
そのまま |
そのまま |
そのまま |
リターン前 |
任意 |
任意 |
任意 |
リターン時処理 |
そのまま |
そのまま |
そのまま |
この表の中で「原則(*1)」とは,処理単位からのリターン前(または終了前)に,アプリケーションが指定された状態に設定しておくことが原則であるが,この原則に従わなくても,リターン時(または終了時)にカーネルによって状態が設定されるため,支障がないことを意味する.
「自優先度に(*2)」とは,割込みハンドラを起動した割込みの割込み優先度に変更することを意味する.
「変更不可(*3)」とは,その処理単位中で,そのシステム状態を変更するAPIが用意されていないことを示す.
【補足説明】
割込みサービスルーチンは,カーネル内の割込みハンドラから呼び出される.また,タイムイベントハンドラの内,周期ハンドラとアラームハンドラは高分解能タイマ割込みハンドラから,オーバランハンドラはオーバランタイマ割込みハンドラから,それぞれ呼び出される.割込み優先度マスクは,それらを呼び出す割込みハンドラでの状態のまま呼び出され,リターン時にも変更されない(*4).
【TOPPERS新世代カーネル統合仕様との関係】
割込みサービスルーチンおよびタイムイベントハンドラからのリターン時に,TOPPERS新世代カーネル統合仕様では割込み優先度マスクを元に戻すものとしていたが,この仕様では元に戻さない(そのままとする)ものとした.これは,ターゲットによっては,割込み優先度マスクを元に戻すためのオーバヘッドが大きいためである.
【仕様決定の理由】
CPU例外ハンドラ中で割込み優先度マスクを変更するAPIが用意されていないにもかかわらず,CPU例外ハンドラからのリターン時に元の状態に戻す(*5)理由は次の通りである.プロセッサによっては,割込み優先度マスクがステータスレジスタ等に含まれており,CPU例外ハンドラからのリターンで自然に元の状態に戻ってしまう.ターゲットによって振舞いが異なるのは望ましくないため,ターゲットによらず,元の状態に戻すこととしている.
CPU例外ハンドラの実行開始時には,CPUロックフラグは変更されない(*6)ことから,CPUロック状態でCPU例外が発生した場合,CPU例外ハンドラの実行開始直後はCPUロック状態となっている.CPUロック状態でCPU例外が発生した場合,起動されるCPU例外ハンドラはカーネル管理外のCPU例外ハンドラであり(xsns_dpnはtrueを返す),CPU例外ハンドラ中でunl_cpuを呼び出してCPUロック状態を解除しようとした場合の動作は保証されない.ただし,保証されないにも関わらずunl_cpuを呼び出した場合も考えられるため,リターン時には元に戻すこととしている.
2.6 タスクの状態遷移とスケジューリング規則
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
時間パーティショニングの機能とスケジューリング単位の概念を新たに導入した.
μITRON4.0/PX仕様で導入された待ち禁止状態,TOPPERS新世代カーネル統合仕様で導入されたタスク例外処理マスク状態の概念は廃止した.新たに導入したタスク終了要求フラグがセットされた状態が,待ち禁止状態の役割を兼ねている.
2.6.1 基本的なタスク状態
カーネルに登録したタスクは,実行できる状態,休止状態,広義の待ち状態のいずれかの状態を取る【NGKI0193】.また,実行できる状態と広義の待ち状態を総称して,起動された状態と呼ぶ.さらに,タスクをカーネルに登録していない仮想的な状態を,未登録状態と呼ぶ.
(a) 実行できる状態(runnable)
タスクを実行できる条件が,プロセッサが使用できるかどうかを除いて,揃っている状態.実行できる状態は,さらに,実行状態と実行可能状態に分類される.
(a.1) 実行状態(running)
タスクが実行されている状態.または,そのタスクの実行中に,割込みまたはCPU例外により非タスクコンテキストの実行が開始され,かつ,タスクコンテキストに戻った後に,そのタスクの実行を再開するという状態.
(a.2) 実行可能状態(ready)
タスク自身は実行できる状態にあるが,それよりも優先順位の高いタスクが実行状態にあるために,そのタスクが実行されない状態.
(b) 休止状態(dormant)
タスクが実行すべき処理がない状態.タスクの実行を終了した後,次に起動するまでの間は,タスクは休止状態となっている.タスクが休止状態にある時には,タスクの実行を再開するための情報(実行再開番地やレジスタの内容など)は保存されていない【NGKI0194】.
(c) 広義の待ち状態(blocked)
タスクが,処理の途中で実行を止められている状態.タスクが広義の待ち状態にある時には,タスクの実行を再開するための情報(実行再開番地やレジスタの内容など)は保存されており,タスクが実行を再開する時には,広義の待ち状態に遷移する前の状態に戻される【NGKI0195】.広義の待ち状態は,さらに,(狭義の)待ち状態,強制待ち状態,二重待ち状態に分類される.
(c.1) (狭義の)待ち状態(waiting)
タスクが何らかの条件が揃うのを待つために,自ら実行を止めている状態.
(c.2) 強制待ち状態(suspended)
他のタスクによって,強制的に実行を止められている状態.ただし,自タスクを強制待ち状態にすることも可能である.
(c.3) 二重待ち状態(waiting-suspended)
待ち状態と強制待ち状態が重なった状態.すなわち,タスクが何らかの条件が揃うのを待つために自ら実行を止めている時に,他のタスクによって強制的に実行を止められている状態.
単にタスクが「待ち状態である」といった場合には,二重待ち状態である場合を含み,「待ち状態でない」といった場合には,二重待ち状態でもないことを意味する.また,単にタスクが「強制待ち状態である」といった場合には,二重待ち状態である場合を含み,「強制待ち状態でない」といった場合には,二重待ち状態でもないことを意味する.
(d) 未登録状態(non-existent)
タスクをカーネルに登録していない仮想的な状態.タスクの生成前と削除後は,タスクは未登録状態にあるとみなす.
カーネルによっては,これらのタスク状態以外に,過渡的な状態が存在する場合がある【NGKI0196】.過渡的な状態については,「2.6.5 ディスパッチ保留状態で実行中のタスクに対する強制待ち」の節を参照すること.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,タスクが未登録状態になることはない【ASPS0005】.また,上記のタスク状態以外の過渡的な状態になることもない【ASPS0006】.ただし,動的生成機能拡張パッケージでは,タスクが未登録状態になる【ASPS0007】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,タスクが未登録状態になることはない【FMPS0003】.上記のタスク状態以外の過渡的な状態として,タスクが強制待ち状態[実行継続中]になることがある【FMPS0004】.詳しくは,「2.6.5 ディスパッチ保留状態で実行中のタスクに対する強制待ち」の節を参照すること.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,タスクが未登録状態になることはない【HRPS0002】.また,上記のタスク状態以外の過渡的な状態になることもない【HRPS0003】.ただし,動的生成機能拡張パッケージでは,タスクが未登録状態になる【HRPS0010】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,タスクが未登録状態になることはない【HRMPS0004】.上記のタスク状態以外の過渡的な状態として,タスクが強制待ち状態[実行継続中]になることがある【HRMPS0005】.詳しくは,「2.6.5 ディスパッチ保留状態で実行中のタスクに対する強制待ち」の節を参照すること.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,タスクが広義の待ち状態と未登録状態になることはない【SSPS0003】.また,上記のタスク状態以外の過渡的な状態になることもない【SSPS0004】.
2.6.2 タスクの状態遷移
タスクの状態遷移を図2-2に示す【NGKI0197】.

未登録状態のタスクをカーネルに登録することを,タスクを生成する(create)という.生成されたタスクは,休止状態に遷移する【NGKI0198】.また,タスク生成時の属性指定により,生成と同時にタスクを起動し,実行できる状態にすることもできる【NGKI0199】.逆に,登録されたタスクを未登録状態に遷移させることを,タスクを削除する(delete)という.
休止状態のタスクを,実行できる状態にすることを,タスクを起動する(activate)という.起動されたタスクは,実行できる状態になる【NGKI0200】.逆に,起動された状態のタスクを,休止状態(または未登録状態)に遷移させることを,タスクを終了する(terminate)という.
実行できる状態になったタスクは,まずは実行可能状態に遷移するが,そのタスクの優先順位が実行状態のタスクよりも高い場合には,ディスパッチ保留状態でない限りはただちにディスパッチが起こり,実行状態へ遷移する【NGKI0201】.この時,それまで実行状態であったタスクは実行可能状態に遷移する【NGKI0202】.この時,実行状態に遷移したタスクは,実行可能状態に遷移したタスクをプリエンプトしたという.逆に,実行可能状態に遷移したタスクは,プリエンプトされたという.
タスクを待ち解除するとは,タスクが待ち状態(二重待ち状態を除く)であれば実行できる状態に,二重待ち状態であれば強制待ち状態に遷移させることをいう.また,タスクを強制待ちから再開するとは,タスクが強制待ち状態(二重待ち状態を除く)であれば実行できる状態に,二重待ち状態であれば待ち状態に遷移させることをいう.
【補足説明】
タスクの実行開始とは,タスクが起動された後に最初に実行される(実行状態に遷移する)時のことをいう.
2.6.3 タスクのスケジューリング規則
実行できるタスクは,優先順位の高いものから順に実行される【NGKI0203】.すなわち,ディスパッチ保留状態でない限りは,実行できるタスクの中で最も高い優先順位を持つタスクが実行状態となり,他は実行可能状態となる.
タスクの優先順位は,タスクの優先度とタスクが実行できる状態になった順序から,次のように定まる.優先度の異なるタスクの間では,優先度の高いタスクが高い優先順位を持つ【NGKI0204】.優先度が同一のタスクの間では,別に規定がない限りは,先に実行できる状態になったタスクが高い優先順位を持つ【NGKI0205】.すなわち,同じ優先度を持つタスクは,FCFS(First Come First Served)方式でスケジューリングされる.ただし,サービスコールの呼出しにより,同じ優先度を持つタスク間の優先順位を変更することも可能である【NGKI0206】.
保護機能対応カーネルにおいて,カーネルドメインに属するタスクとユーザドメインに属するタスクが同一の優先度を持つ場合には,カーネルドメインに属するタスクが高い優先順位を持つ【NGKI0588】.カーネルドメイン内とユーザドメイン内では,別に規定がない限りは,先に実行できる状態になったタスクが高い優先順位を持つ【NGKI0589】.なお,時間パーティショニングを使用した場合のスケジューリング規則については,「2.6.7 時間パーティショニング使用時のスケジューリング規則」の節を参照すること.
サブ優先度機能をサポートするカーネルにおいては,サブ優先度を使用して優先順位を決定すると設定した同一の優先度を持つタスク(保護機能対応カーネルにおいては,さらに,同じ保護ドメインに属するもの)の間では,別に規定がない限りは,サブ優先度の高いタスクが高い優先順位を持つ【NGKI0560】.サブ優先度も同一のタスクの間では,先に実行できる状態になったタスクが高い優先順位を持つ【NGKI0561】.
最も高い優先順位を持つタスクが変化した場合には,ディスパッチ保留状態でない限りはただちにディスパッチが起こり,最も高い優先順位を持つタスクが実行状態となる【NGKI0207】.ディスパッチ保留状態においては,実行状態のタスクは切り換わらず,最も高い優先順位を持つタスクは実行可能状態にとどまる【NGKI0208】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,上記のスケジューリング規則を適用して,タスクスケジューリングを行う【NGKI0209】.すなわち,プロセッサがディスパッチ保留状態でない限りは,そのプロセッサに割り付けられた実行できるタスクの中で最も高い優先順位を持つタスクが実行状態となり,他は実行可能状態となる.そのため,実行状態のタスクは,プロセッサ毎に存在する.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
サブ優先度機能を追加した.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
保護機能対応カーネルにおいて,カーネルドメインに属するタスクは,ユーザドメインに属する同じ優先度のタスクよりも,高い優先順位を持つものとした.
2.6.4 待ち行列と待ち解除の順序
タスクが待ち解除される順序の管理のために,待ち状態のタスクがつながれているキューを,待ち行列と呼ぶ.また,タスクが同期・通信オブジェクトの待ち行列につながれている場合に,そのオブジェクトを,タスクの待ちオブジェクトと呼ぶ.
待ち行列にタスクをつなぐ順序には,FIFO順とタスクの優先度順がある.どちらの順序でつなぐかは,待ち行列毎に規定される【NGKI0210】.多くの待ち行列において,どちらの順序でつなぐかを,オブジェクト属性により指定できる【NGKI0211】.
FIFO順の待ち行列においては,新たに待ち状態に遷移したタスクは待ち行列の最後につながれる【NGKI0212】.それに対してタスクの優先度順の待ち行列においては,新たに待ち状態に遷移したタスクは,優先度の高い順に待ち行列につながれる【NGKI0213】.同じ優先度のタスクが待ち行列につながれている場合には,新たに待ち状態に遷移したタスクが,同じ優先度のタスクの中で最後につながれる【NGKI0214】.
待ち解除の条件がタスクによって異なる場合には,待ち行列の先頭のタスクは待ち解除の条件を満たさないが,後方のタスクが待ち解除の条件を満たす場合がある.このような場合の振舞いとして,次の2つのケースがある.どちらの振舞いをするかは,待ち行列毎に規定される【NGKI0215】.
(a) 待ち解除の条件を満たしたタスクの中で,待ち行列の前方につながれたものから順に待ち解除される【NGKI0216】.すなわち,待ち行列の前方に待ち解除の条件を満たさないタスクがあっても,後方のタスクが待ち解除の条件を満たしていれば,先に待ち解除される.
(b) タスクの待ち解除は,待ち行列につながれている順序で行われる【NGKI0217】.すなわち,待ち行列の前方に待ち解除の条件を満たさないタスクがあると,後方のタスクが待ち解除の条件を満たしても,待ち解除されない.
ここで,(b)の振舞いをする待ち行列においては,待ち行列につながれたタスクの強制終了,タスク優先度の変更(待ち行列がタスクの優先度順の場合のみ),待ち状態の強制解除が行われた場合に,タスクの待ち解除が起こることがある.具体的には,これらの操作により新たに待ち行列の先頭になったタスクが,待ち解除の条件を満たしていれば,ただちに待ち解除される【NGKI0218】.さらに,この待ち解除により新たに待ち行列の先頭になったタスクに対しても,同じ処理が繰り返される【NGKI0219】.
2.6.5 ディスパッチ保留状態で実行中のタスクに対する強制待ち
ディスパッチ保留状態において,実行状態のタスクを強制待ち状態へ遷移させるサービスコールを呼び出した場合,実行状態のタスクの切換えは,ディスパッチ保留状態が解除されるまで保留される【NGKI0226】.
この間,それまで実行状態であったタスクは,実行状態と強制待ち状態の間の過渡的な状態にあると考える【NGKI0227】.この状態を,強制待ち状態[実行継続中]と呼ぶ.一方,ディスパッチ保留状態が解除された後に実行すべきタスクは,実行可能状態にとどまる【NGKI0228】.
タスクが強制待ち状態[実行継続中]にある時に,ディスパッチ保留状態が解除されると,ただちにディスパッチが起こり,タスクは強制待ち状態に遷移する【NGKI0229】.
過渡的な状態も含めたタスクの状態遷移を図2-3に示す【NGKI0230】.

タスクが強制待ち状態[実行継続中]である時の扱いは次の通りである.
(a) プロセッサを占有して実行を継続する.
強制待ち状態[実行継続中]のタスクは,プロセッサを占有して,そのまま継続して実行される【NGKI0231】.
強制待ち状態[実行継続中]のタスクが,自タスクを終了させるサービスコールを発行すると,休止状態に遷移する【NGKI0629】.ただし,マルチプロセッサ対応カーネルでは,CPUロック状態で強制待ち状態[実行継続中]のタスクがext_tskを発行した場合には,強制待ち状態に遷移する場合もある【NGKI0648】.
(b) 実行状態のタスクに関する情報を参照するサービスコールでは,実行状態であるものと扱う.
実行状態のタスクに関する情報を参照するサービスコール(get_tid,get_did,sns_ter)では,強制待ち状態[実行継続中]のタスクが,それを実行するプロセッサにおいて実行状態のタスクであるものと扱う.具体的には,強制待ち状態[実行継続中]のタスクが実行されている時にget_tidを発行すると,そのタスクのID番号を参照する【NGKI0232】.また,get_didを発行するとそのタスクが属する保護ドメインのID番号を,sns_terを発行するとそのタスクのタスク終了禁止フラグを参照する【NGKI0534】.
(c) その他のサービスコールでは,強制待ち状態であるものと扱う.
その他のサービスコールでは,強制待ち状態[実行継続中]のタスクは,強制待ち状態であるものと扱う【NGKI0234】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,ディスパッチ保留状態において実行状態のタスクを強制待ち状態へ遷移させるサービスコールはサポートしていないため,タスクが強制待ち状態[実行継続中]になることはない【ASPS0008】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,ディスパッチ保留状態において実行状態のタスクを強制待ち状態へ遷移させるサービスコールを,他のプロセッサから呼び出すことができるため,タスクが強制待ち状態[実行継続中]になる場合がある【FMPS0005】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,ディスパッチ保留状態において実行状態のタスクを強制待ち状態へ遷移させるサービスコールはサポートしていないため,タスクが強制待ち状態[実行継続中]になることはない【HRPS0004】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,ディスパッチ保留状態において実行状態のタスクを強制待ち状態へ遷移させるサービスコールを,他のプロセッサから呼び出すことができるため,タスクが強制待ち状態[実行継続中]になる場合がある【HRMPS0006】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,タスクが広義の待ち状態になることはないため,タスクが強制待ち状態[実行継続中]になることもない【SSPS0005】.
【補足説明】
この仕様では,ディスパッチ保留状態において,実行状態のタスクを強制終了させるサービスコールはサポートしていない.そのため,実行状態と休止状態の間の過渡的な状態は存在しない.
【μITRON4.0仕様との関係】
μITRON4.0仕様では,過渡的な状態におけるタスクの扱いは,実装依存とされている.
【TOPPERS新世代カーネル統合仕様との関係】
強制待ち状態[実行継続中]のタスクが,自タスクを終了させるサービスコールを発行した場合の扱いを規定した.
2.6.6 制約タスク
制約タスク(restricted task)は,複数のタスクでスタック領域を共有することによるメモリ使用量の削減を目的に,通常のタスクに対して,広義の待ち状態を持たないなどの機能制限を加えたものである.具体的には,制約タスクには以下の機能制限がある.
(a) 広義の待ち状態に入ることができない【NGKI0235】.
(b) サービスコールによりベース優先度やサブ優先度を変更することができない【NGKI0236】.
(c) 対象優先度の中の先頭のタスクが制約タスクである場合には,タスクの優先順位の回転(rot_rdq,mrot_rdq)を行うことができない【NGKI0237】.
(d) マルチプロセッサ対応カーネルでは,割付けプロセッサを変更することができない【NGKI0238】.
制約タスクに対して,機能制限により使用できなくなったサービスコールを呼び出した場合には,E_NOSPTエラーとなる【NGKI0239】.E_NOSPTエラーが返ることに依存している場合を除いては,制約タスクを通常のタスクに置き換えることができる【NGKI0240】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,制約タスクをサポートしていない【ASPS0009】.ただし,制約タスク拡張パッケージを用いると,制約タスクの機能を追加することができる【ASPS0010】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,制約タスクをサポートしていない【FMPS0006】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,制約タスクをサポートしていない【HRPS0005】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,制約タスクをサポートしていない【HRMPS0007】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,制約タスクのみをサポートする【SSPS0006】.そのため,すべてのタスクと非タスクコンテキストがスタック領域を共有することができ,すべての処理単位で同一のスタック領域を使用している【SSPS0007】.このスタック領域を,共有スタック領域と呼ぶ.
【μITRON4.0仕様との関係】
制約タスクは,μITRON4.0仕様の自動車制御プロファイルで導入された機能である.この仕様における制約タスクは,μITRON4.0仕様の制約タスクよりも機能制限が少なくなっている.
2.6.7 時間パーティショニング使用時のスケジューリング規則
保護機能対応カーネルで,時間パーティショニングを使用する場合には,以下の規則に従ってタスクがスケジューリングされる.
プロセッサは,システム周期毎に,現在のシステム動作モードに対して登録されたタイムウィンドウを順に実行する(図2-4)【NGKI0590】.あるタイムウィンドウの実行中は,カーネルドメインに属する実行できる処理単位と,そのタイムウィンドウを割り当てられたユーザドメインに属する実行できるタスクの中で,優先順位の高いものから順に実行される【NGKI0591】.これらの保護ドメインに属する実行できる処理単位がない場合には,アイドルドメインに属する実行できるタスクの中で,優先順位の高いものから順に実行される【NGKI0592】.

実行中のタイムウィンドウが使用したプロセッサ時間(いずれの処理単位も実行していなかった時間も含む)から,カーネルドメインに属する処理単位(ユーザタスクから呼び出された拡張サービスコールを除く)が使用したプロセッサ時間を減じたものが,タイムウィンドウの長さに達すると,次のタイムウィンドウに切り換えられる(図2-5)【NGKI0593】.次のタイムウィンドウが設定されていない場合(言い換えると,実行中のタイムウィンドウが,現在のシステム動作モードに対して設定された最後のタイムウィンドウである場合)には,アイドルウィンドウに切り換えられる【NGKI0594】.アイドルウィンドウの実行中は,カーネルドメインに属する実行できる処理単位と,アイドルドメインに属する実行できるタスクの中で,優先順位の高いものから順に実行される【NGKI0595】.

システム周期の終了時刻になると,システム周期の切換え処理が行われる.具体的には,まず,アイドルウィンドウが実行中であるか(言い換えると,現在のシステム動作モードに対して設定されたタイムウィンドウの実行がすべて終わっているか)をチェックし,そうでない場合,カーネルはエミュレートされたCPU例外を発生させる【NGKI0596】.これを,システム周期オーバラン例外と呼ぶ.次に,システム動作モードを,次のシステム周期での遷移先システム動作モードに切り換える【NGKI0597】.その後に,新しいシステム周期を開始する.すなわち,新しいシステム動作モードに対して設定された最初のタイムウィンドウに切り換える【NGKI0598】.
システム動作モードがシステム周期停止モードである場合には,システム周期の切換えも,タイムウィンドウの実行も行われず,カーネルドメインに属する処理単位(ユーザタスクから呼び出された拡張サービスコールを除く)の中で,優先順位が高いものから順に実行される【NGKI0599】.
ユーザドメインに属するタイムイベントの処理(ユーザドメインに属する周期通知とアラーム通知の処理,ユーザドメインに属するタスクに対するタイムアウト処理と時間経過待ち状態からの待ち解除処理)は,そのユーザドメインに割り当てられたタイムウィンドウへの切換え時(厳密には,タイムウィンドウを切り換え,タイムウィンドウ通知を処理した後,タスクの実行を開始する前)に実行される【NGKI0600】.アイドルドメインに属するタイムイベントの処理は,アイドルウィンドウへの切換え時に実行される【NGKI0601】.
ディスパッチ保留状態では,システム周期の切換えとタイムウィンドウの切換えは保留される【NGKI0602】.
システム周期の切換えは,高分解能タイマ割込みをきっかけに実行される.そのため,高分解能タイマ割込みのマスクや,ディスパッチの保留によって,システム周期の切換えは遅れることになる.この場合,その遅れ時間の分,次のシステム周期(結果的には,その最後のアイドルウィンドウ)が短くなる【NGKI0650】.システム周期の切換えが,次のシステム周期末を超えて遅れる状況では,カーネルの動作は保証されない【NGKI0651】.
また,タイムウィンドウの切換えは,タイムウィンドウタイマ割込みをきっかけに実行される.そのため,タイムウィンドウタイマ割込みのマスクや,ディスパッチの保留によって,タイムウィンドウの切換えは遅れることになる.この場合,その遅れ時間の分,そのシステム周期の最後のアイドルウィンドウが短くなる【NGKI0652】.タイムウィンドウの切換えが,そのシステム周期末を超えて遅れる状況では,カーネルの動作は保証されない【NGKI0653】.
マルチプロセッサ対応カーネルでは,プロセッサ毎に,上記のスケジューリング規則を適用してタスクがスケジューリングされる【NGKI0625】.システム周期とシステム動作モードは,すべてのプロセッサで同一である【NGKI0626】.ただし,システム周期の切換え処理は,各プロセッサで同期して行われるわけではない.現在のシステム動作モードは,システム周期の切換え処理を最初に行ったプロセッサによって切り換えられる【NGKI0637】.そのため,他のプロセッサでは,一時的に,切換え前のシステム動作モードで実行している状況が生じる【NGKI0636】.なお,タイムウィンドウは,プロセッサ毎に登録することができる[NGKI0624].
マルチプロセッサ対応カーネルでは,また,アイドルドメインにまとめられていないユーザドメインに属するタスク,周期通知,アラーム通知を,そのユーザドメインに対してどのシステム動作モードにおいてもタイムウィンドウを割り当てられていないプロセッサに割り付けることはできない【NGKI0628】.そのため例えば,プロセッサAでタイムウィンドウを割り当てられており,プロセッサBでタイムウィンドウを割り当てられていないユーザドメインに属するタスクを,プロセッサBに割り付けることはできない.
なお,システム周期オーバラン例外は,カーネル管理外のCPU例外であり,その例外ハンドラ番号はターゲット定義である【NGKI0603】.システム周期オーバラン例外に対して登録したCPU例外ハンドラからリターンすると,実行中のタイムウィンドウは打ち切られ,システム周期の切換え処理が継続される【NGKI0635】.
【使用上の注意】
システム周期内で,カーネルとカーネルドメインに属する処理単位(ユーザタスクから呼び出された拡張サービスコールを除く)が使用するプロセッサ時間や,システム時刻の調整やドリフト量の設定によるシステム周期の短縮,タイマ割込みのマスクやディスパッチの保留によるシステム周期の切換えとタイムウィンドウの切換えの遅延を考慮し,十分な長さのアイドルウィンドウを確保するのは,アプリケーションの責任である.
ユーザドメインに割り当てられたタイムウィンドウの実行途中に,そのユーザドメインに属するタイムイベントの発生時刻になっても,タイムイベントはすぐには処理されない.タイムイベントが処理されるのは,そのユーザドメインに割り当てられた次のタイムウィンドウへの切換え時である.
2.6.8 スケジューリング単位
タスクのスケジューリングに関する以上の仕様より,タスクを,FCFS方式に基づく優先順位が管理される単位に分類することができる.この単位(タスクの集合)をスケジューリング単位と呼ぶ.カーネルの実装上は,スケジューリング単位毎にレディキューを持つ.
保護機能とマルチプロセッサのいずれにも対応しないカーネルは,唯一のスケジューリング単位を持つ.すなわち,すべてのタスクが1つのスケジューリング単位に属する.
保護機能とマルチプロセッサのいずれかまたは両方に対応するカーネルは,複数のスケジューリング単位を持つ.また,スケジューリング単位を指定して操作を行うサービスコールをサポートする.それらのサービスコールにおいて,スケジューリング単位を指定する番号を,スケジューリング単位番号と呼ぶ.スケジューリング単位番号は,符号付きの整数型であるID型で表す.
保護機能対応カーネルにおいては,カーネルドメイン,アイドルドメイン,アイドルドメインにまとめられていない各ユーザドメインがスケジューリング単位となる.スケジューリング単位番号には,保護ドメインIDまたは呼び出した処理単位が属する保護ドメインを表すTDOM_SELF(=0)を指定することができる【NGKI0630】.保護ドメインIDで指定したユーザドメインがアイドルドメインにまとめられている場合には,アイドルドメインを指定したものとする【NGKI0631】.
マルチプロセッサ対応カーネルにおいては,各プロセッサがスケジューリング単位となる.スケジューリング単位番号には,プロセッサIDを指定することができる【NGKI0632】.
保護機能とマルチプロセッサの両方に対応するカーネルにおいては,各プロセッサに対して,カーネルドメイン,アイドルドメイン,アイドルドメインにまとめられていない各ユーザドメインがスケジューリング単位となる.スケジューリング単位番号には,SCHEDNO(prcid, domid)を指定する【NGKI0633】.ここで,prcidはマルチプロセッサ対応カーネルにおけるスケジューリング単位番号,domidは保護機能対応カーネルにおけるスケジューリング単位番号,SCHEDNOは保護機能とマルチプロセッサの両方に対応するカーネルにおけるスケジューリング単位番号を構成するためのマクロである.
2.7 割込み処理モデル
TOPPERS第3世代カーネルにおける割込み処理モデルの概念図を図2-6に示す【NGKI0241】.この図は,割込み処理モデルの持つすべての機能が,ハードウェア(プロセッサおよび割込みコントローラ)で実現されているとして描いた概念図である.実際のハードウェアで不足している機能については,カーネル内の割込み処理のソフトウェアで実現される.

【μITRON4.0仕様との関係】
割込み処理モデルは,μITRON4.0仕様から大幅に拡張している.
2.7.1 割込み処理の流れ
周辺デバイス(以下,デバイスと呼ぶ)からの割込み要求は,割込みコントローラ(IRC)を経由して,プロセッサに伝えられる.デバイスから割込みコントローラに割込み要求を伝えるための信号線を,割込み要求ラインと呼ぶ.一般には,1つの割込み要求ラインに,複数のデバイスからの割込み要求が接続される.
プロセッサは,デバイスからの割込み要求を受け付ける条件が満たされた場合,割込み要求を受け付ける【NGKI0242】.受け付けた割込み要求が,カーネル管理の割込みである場合には,カーネル内の割込みハンドラの入口処理(割込み入口処理)を経由して,カーネル内の割込みハンドラを実行する【NGKI0243】.
カーネル内の割込みハンドラは,アプリケーションが割込み要求ラインに対して登録した割込みサービスルーチン(ISR)を呼び出す【NGKI0244】.割込みサービスルーチンは,プロセッサの割込みアーキテクチャや割込みコントローラに依存せず,割込みを要求したデバイスのみに依存して記述するのが原則である【NGKI0245】.1つの割込み要求ラインに対して複数のデバイスが接続されることから,1つの割込み要求ラインに対して複数の割込みサービスルーチンを登録することができる【NGKI0246】.
ただし,カーネルが標準的に用意している割込みハンドラで対応できない特殊なケースも考えられる.このような場合に対応するために,アプリケーションが用意した割込みハンドラをカーネルに登録することもできる【NGKI0247】.
カーネルが用いる高分解能タイマ,タイムウィンドウタイマ,オーバランタイマからの割込み要求の場合,カーネル内の割込みハンドラにより,タイムイベントの処理が行われる.具体的には,タイムアウト処理やタイムイベントの通知処理(タイムイベントハンドラの呼出しを含む),タイムウィンドウの切換え処理,オーバランハンドラの呼出しなどが行われる【NGKI0248】.
なお,受け付けた割込み要求に対して,割込みサービスルーチンも割込みハンドラも登録していない場合の振舞いは,ターゲット定義である【NGKI0249】.
2.7.2 割込み優先度
割込み要求は,割込み処理の優先順位を指定するための割込み優先度を持つ【NGKI0250】.プロセッサは,割込み優先度マスクの現在値よりも高い割込み優先度を持つ割込み要求のみを受け付ける【NGKI0251】.逆に言うと,割込み優先度マスクの現在値と同じか,それより低い割込み優先度を持つ割込みは,マスクされる.
プロセッサは,割込み要求を受け付けると,割込み優先度マスクを,受け付けた割込み要求の割込み優先度に設定する(ただし,受け付けた割込みがNMIである場合には例外とする)【NGKI0252】.また,割込み処理からのリターンにより,割込み優先度マスクを,割込み要求を受け付ける前の値に戻す【NGKI0253】.
これらのことから,他の方法で割込みをマスクしていない限り,ある割込み要求の処理中は,それと同じかそれより低い割込み優先度を持つ割込み要求は受け付けられず,それより高い割込み優先度を持つ割込み要求は受け付けられることになる.つまり,割込み優先度は,多重割込みを制御するためのものと位置付けることができる.それに対して,同時に発生している割込み要求の中で,割込み優先度の高い割込み要求が先に受け付けられるとは限らない【NGKI0254】.
割込み優先度は,PRI型で表現し,値が小さいほど優先度が高いものとするが,[NGKI0037]の原則には従わず,-1から連続した負の値を用いる【NGKI0255】.
割込み優先度の段階数は,ターゲット定義である【NGKI0256】.プロセッサが割込み優先度マスクを実現するための機能を持たないか,実現するために大きいオーバヘッドを生じる場合には,ターゲット定義で,割込み優先度の段階数を1にする(すなわち,多重割込みを許さない)場合がある.
【仕様決定の理由】
割込み優先度に-1から連続した負の値を用いるのは,割込み優先度とタスク優先度を比較できるようになることと,いずれの割込みもマスクしない割込み優先度マスクの値を0にできるためである.
2.7.3 割込み要求ラインの属性
各割込み要求ラインは,以下の属性を持つ.なお,1つの割込み要求ラインに複数のデバイスからの割込み要求が接続されている場合,それらの割込み要求は同一の属性を持つ【NGKI0257】.それらの割込み要求に別々の属性を設定することはできない.
(1) 割込み要求禁止フラグ
割込み要求ライン毎に,割込みをマスクするための割込み要求禁止フラグを持つ【NGKI0258】.割込み要求禁止フラグをセットすると,その割込み要求ラインによって伝えられる割込み要求はマスクされる【NGKI0259】.
プロセッサが割込み要求禁止フラグを実現するための機能を持たないか,実現するために大きいオーバヘッドを生じる場合には,ターゲット定義で,割込み要求禁止フラグをサポートしない場合がある【NGKI0260】.また,プロセッサの持つ割込み要求禁止フラグの機能がこの仕様に合致しない場合には,ターゲット定義で,割込み要求禁止フラグをサポートしないか,振舞いが異なるものとする場合がある【NGKI0261】.
(2) 割込み優先度
割込み要求ライン毎に,割込み優先度を設定することができる【NGKI0262】.割込み要求ラインに対して設定された割込み優先度が,それが伝える割込み要求の割込み優先度となる【NGKI0263】.
(3) トリガモードと割込み要求フラグ
割込み要求ラインに対する割込み要求が,レベルトリガであるかエッジトリガであるかを設定することができる【NGKI0264】.エッジトリガの場合には,さらに,ターゲット定義で,ポジティブエッジトリガかネガティブエッジトリガか両エッジトリガかを設定できる場合もある【NGKI0265】.また,レベルトリガの場合には,ターゲット定義で,ローレベルトリガかハイレベルトリガかを設定できる場合もある【NGKI0266】.
エッジトリガに設定された割込み要求ラインに対しては,割込み要求の有無を示す割込み要求フラグを持つ【NGKI0657】.割込み要求フラグは,割込み要求を示すエッジが検出されるとセットされ,割込みが受け付けられるとクリアされる【NGKI0658】.
プロセッサがトリガモードを設定するための機能を持たないか,設定するために大きいオーバヘッドを生じる場合には,ターゲット定義で,トリガモードの設定をサポートしない場合がある【NGKI0267】.
属性が設定されていない割込み要求ラインに対しては,割込み要求禁止フラグがセットされ,割込み要求はマスクされる【NGKI0268】.また,割込み要求禁止フラグをクリアすることもできない【NGKI0269】.
【使用上の注意】
アプリケーションが,割込み要求禁止フラグを動的にセット/クリアする機能を用いると,次の理由でソフトウェアの再利用性が下がる可能性があるため,注意が必要である.プロセッサによっては,この割込み処理モデルに合致した割込み要求禁止フラグの機能を実現できない場合がある.また,割込み要求禁止フラグをセットすることで,複数のデバイスからの割込みがマスクされる場合がある.ソフトウェアの再利用性を上げるためには,あるデバイスからの割込みのみをマスクしたい場合には,そのデバイス自身の機能を使ってマスクを実現すべきである.
複数のデバイスからの割込み要求が接続されている割込み要求ラインを,エッジトリガに設定することは推奨されない.これは,次のような状況において,割込み要求を取りこぼす可能性があるためである.ある割込み要求ラインに,デバイスAとデバイスBからの割込み要求が接続されており,デバイスAの割込み処理を先に行う場合を考える.この時,デバイスBからの割込み要求によって割込みハンドラが実行され,デバイスAの割込み処理を行った後,デバイスBの割込み処理を行う前に,デバイスAからの割込み要求が発生した場合に,デバイスAからの割込み要求を取りこぼしてしまう.
【TOPPERS新世代カーネル統合仕様との関係】
clr_int,ras_intの振舞いを明確化するために,割込み要求フラグの概念を導入した.
2.7.4 割込みを受け付ける条件
NMI以外の割込み要求は,次の4つの条件が揃った場合に受け付けられる【NGKI0270】.
(a) 割込み要求ラインに対する割込み要求禁止フラグがクリアされていること
(b) 割込み要求ラインに設定された割込み優先度が,割込み優先度マスクの現在値よりも高い(優先度の値としては小さい)こと
(c) 全割込みロックフラグがクリアされていること
(d) 割込み要求がカーネル管理の割込みである場合には,CPUロックフラグがクリアされていること
これらの条件が揃った割込み要求が複数ある場合に,どの割込み要求が最初に受け付けられるかは,この仕様では規定しない【NGKI0271】.すなわち,割込み優先度の高い割込み要求が先に受け付けられるとは限らない.
2.7.5 割込み番号と割込みハンドラ番号
割込み要求ラインを識別するための番号を,割込み番号と呼ぶ.割込み番号は,符号無しの整数型であるINTNO型で表し,ターゲットハードウェアの仕様から決まる自然な番号付けを基本として,ターゲット定義で付与される【NGKI0272】.そのため,1から連続した正の値であるとは限らない.
それに対して,アプリケーションが用意した割込みハンドラをカーネルに登録する場合に,割込みハンドラの登録対象となる割込みを識別するための番号を,割込みハンドラ番号と呼ぶ.割込みハンドラ番号は,符号無しの整数型であるINHNO型で表し,ターゲットハードウェアの仕様から決まる自然な番号付けを基本として,ターゲット定義で付与される【NGKI0273】.そのため,1から連続した正の値であるとは限らない.
割込みハンドラ番号は,割込み番号と1対1に対応するのが基本である(両者が一致する場合が多い)【NGKI0274】.
ただし,割込みを要求したデバイスが割込みベクタを生成してプロセッサに渡すアーキテクチャなどでは,割込み番号と割込みハンドラ番号の対応を,カーネルが管理していない場合がある【NGKI0275】.そこで,ターゲット定義で,割込み番号に対応しない割込みハンドラ番号や,割込みハンドラ番号に対応しない割込み番号を設ける場合もある【NGKI0276】.ただし,割込みサービスルーチンの登録対象にできる割込み番号は,割込みハンドラ番号との1対1の対応関係をカーネルが管理しているもののみである【NGKI0277】.
2.7.6 マルチプロセッサにおける割込み処理
この節では,マルチプロセッサにおける割込み処理について説明する.この節の内容は,マルチプロセッサ対応カーネルにのみ適用される.
マルチプロセッサ対応カーネルでは,割込み処理モデルの概念図(図2-6)の中で,破線に囲まれた部分はプロセッサ毎に持ち,それ以外の部分はシステム全体で1つのみ持つ【NGKI0278】.すなわち,全割込みロックフラグ,CPUロックフラグ,割込み優先度マスクはプロセッサ毎に持つのに対して,割込み要求ラインおよびその属性(割込み要求禁止フラグ,割込み優先度,トリガモード,割込み要求フラグ)はシステム全体で共通に持つ.
割込み番号は,割込み要求ラインを識別するための番号であることから,割込み要求ラインが複数のプロセッサに接続されている場合でも,1つの割込み要求ラインには1つの割込み番号を付与する【NGKI0279】.逆に,複数のプロセッサが同じ種類のデバイスを個別に持っている場合でも,別のデバイスからの割込み要求ラインには異なる割込み番号を付与する(図2-7)【NGKI0280】.図2-7において,ローカルIRCは個々のプロセッサに対する割込みを制御するための回路であり,グローバルIRCはデバイスからの割込みをプロセッサに分配するための回路である.グローバルIRCは,必ず備わっているとは限らない.

割込み要求禁止フラグは,この仕様上はシステム全体で共通に持つこととしているが,実際のターゲットハードウェア(特に,グローバルIRCを備えていないもの)では,プロセッサ毎に持っている場合がある.そのため,ターゲット定義で,あるプロセッサで割込み要求禁止フラグを動的にセット/クリアしても,他のプロセッサに対しては割込みがマスク/マスク解除されない場合があるものとする【NGKI0281】.
複数のプロセッサに接続された割込み要求ラインに対して登録された割込みサービスルーチンは,それらのプロセッサのいずれによっても実行することができる【NGKI0282】.ただし,その内のどのプロセッサで割込みサービスルーチンを実行するかは,割込みサービスルーチンが属するクラスの割付け可能プロセッサにより決定される(「2.4.4 処理単位を実行するプロセッサ」の節を参照).
割込みサービスルーチンが複数のプロセッサで実行できる場合に,連続して複数回の割込み要求があっても,割込みサービスルーチンが異なるプロセッサで同時に実行されることはない【NGKI0659】.
割込みサービスルーチンが属するクラスの割付け可能プロセッサは,登録対象の割込み要求ラインが接続されたプロセッサの集合に含まれていなければならない【NGKI0283】.また,同一の割込み要求ラインに対して登録する割込みサービスルーチンは,同一のクラスに属していなければならない【NGKI0284】.
それに対して,割込みハンドラはプロセッサ毎に登録する.そのため,同じ割込み要求に対応する割込みハンドラであっても,プロセッサ毎に異なる割込みハンドラ番号を付与する(図2-7)【NGKI0285】.割込みハンドラが属するクラスの初期割付けプロセッサは,割込みが要求されるプロセッサと一致していなければならない【NGKI0286】.
【補足説明】
マルチプロセッサ対応カーネルにおける割込み番号の付与方法は,すべてのプロセッサに接続された割込み要求ラインに対しては,割込み番号の上位ビットを0とし,1つのプロセッサのみに接続された割込み要求ラインに対しては,割込み番号の上位ビットに,接続されたプロセッサのID番号を含める方法を基本とする.また,割込みハンドラ番号の付与方法は,割込みハンドラ番号の上位ビットに,その割込みハンドラを実行するプロセッサのID番号を含める方法を基本とする(図2-7).
1つのプロセッサのみに接続された割込み要求ラインに対して登録された割込みサービスルーチンは,そのプロセッサのみを割付け可能プロセッサとするクラスに属していなければならない.
【TOPPERS新世代カーネル統合仕様との関係】
割込みサービスルーチンが異なるプロセッサで同時に実行されることはないこととした.
2.7.7 カーネル管理外の割込み
高い割込み応答性を求められるアプリケーションでは,カーネル内で割込みをマスクすることにより,割込み応答性の要求を満たせなくなる場合がある.このような要求に対応するために,カーネル内では,ある割込み優先度(これを,TMIN_INTPRIと書く)よりも高い割込み優先度を持つ割込みをマスクしないこととしている【NGKI0287】.TMIN_INTPRIを固定するか設定できるようにするか,設定できるようにする場合の設定方法は,ターゲット定義である【NGKI0288】.
TMIN_INTPRIよりも高い割込み優先度を持ち,カーネル内でマスクしない割込みを,カーネル管理外の割込みと呼ぶ.また,カーネル管理外の割込みによって起動される割込みハンドラを,カーネル管理外の割込みハンドラと呼ぶ.NMIは,カーネル管理外の割込みとして扱う.NMI以外にカーネル管理外の割込みを設けるか(設けられるようにするか)どうかは,ターゲット定義である【NGKI0289】.
それに対して,TMIN_INTPRIと同じかそれよりも低い割込み優先度を持つ割込みをカーネル管理の割込み,カーネル管理の割込みによって起動される割込みハンドラをカーネル管理の割込みハンドラと呼ぶ.
カーネル管理外の割込みハンドラは,カーネル内の割込み入口処理を経由せずに実行するのが基本である【NGKI0290】.ただし,すべての割込みで同じ番地に分岐するプロセッサでは,カーネル内の割込み入口処理を全く経由せずにカーネル管理外の割込みハンドラを実行することができず,入口処理の一部分を経由してカーネル管理外の割込みハンドラが実行されることになる【NGKI0291】.
カーネル管理外の割込みハンドラが実行開始される時のシステム状態とコンテキスト,割込みハンドラの終了時に行われる処理,割込みハンドラの記述方法は,ターゲット定義である【NGKI0292】.カーネル管理外の割込みハンドラからは,システムインタフェースレイヤのAPIとsns_ker,ext_kerのみを呼び出すことができ,その他のサービスコールを呼び出すことはできない【NGKI0293】.カーネル管理外の割込みハンドラから,その他のサービスコールを呼び出した場合の動作は,保証されない【NGKI0294】.
2.7.8 カーネル管理外の割込みの設定方法
カーネル管理外の割込みの設定方法は,ターゲット定義で,次の3つの方法のいずれかが採用される【NGKI0295】.
(a-1) NMI以外にカーネル管理外の割込みを設けない
(a-2) カーネル構築時に特定の割込みをカーネル管理外にすると決める
これら場合には,カーネル管理外とする割込みはカーネル構築時(ターゲット依存部の実装時やカーネルのコンパイル時)に決まるため,カーネル管理外とする割込みをアプリケーション側で設定する必要はない【NGKI0296】.ここで,カーネル管理外とされた割込みに対して,カーネルのAPIにより割込みハンドラを登録できるかと,割込み要求ラインの属性を設定できるかは,ターゲット定義である【NGKI0297】.割込みハンドラを登録できる場合には,それを定義するAPIにおいて,カーネル管理外であることを示す割込みハンドラ属性(TA_NONKERNEL)を指定する【NGKI0298】.また,割込み要求ラインの属性を設定できる場合には,設定する割込み優先度をTMIN_INTPRIよりも高い値とする【NGKI0299】.
(b) カーネル管理外とする割込みをアプリケーションで設定できるようにする
この場合には,カーネル管理外とする割込みの設定は,次の方法で行う.まず,カーネル管理外とする割込みハンドラを定義するAPIにおいて,カーネル管理外であることを示す割込みハンドラ属性(TA_NONKERNEL)を指定する【NGKI0300】.また,カーネル管理外とする割込みの割込み要求ラインに対して設定する割込み優先度を,TMIN_INTPRIよりも高い値とする【NGKI0301】.
いずれの場合にも,カーネル管理の割込みハンドラを定義するAPIにおいて,TA_NONKERNEL属性を指定してはならない【NGKI0654】.また,カーネル管理の割込みの割込み要求ラインに対して設定する割込み優先度は,TMIN_INTPRIより高い値であってはならない【NGKI0302】.
カーネル管理外の割込みに対して,割込みサービスルーチンを登録することはできない【NGKI0303】.
2.8 CPU例外処理モデル
プロセッサが検出するCPU例外の種類や,CPU例外検出時のプロセッサの振舞いは,プロセッサによって大きく異なる.そのため,CPU例外ハンドラをターゲットハードウェアに依存せずに記述することは,少なくとも現時点では困難である.そこでこの仕様では,CPU例外の処理モデルを厳密に標準化するのではなく,ターゲットハードウェアに依存せずに決められる範囲で規定する.
2.8.1 CPU例外処理の流れ
アプリケーションは,プロセッサが検出するCPU例外の種類毎に,CPU例外ハンドラを登録することができる【NGKI0304】.プロセッサがCPU例外の発生を検出すると,カーネル内のCPU例外ハンドラの入口処理(CPU例外入口処理)を経由して,発生したCPU例外に対して登録したCPU例外ハンドラが呼び出される【NGKI0305】.
CPU例外ハンドラの登録対象となるCPU例外を識別するための番号を,CPU例外ハンドラ番号と呼ぶ.CPU例外ハンドラ番号は,符号無しの整数型であるEXCNO型で表し,ターゲットハードウェアの仕様から決まる自然な番号付けを基本として,ターゲット定義で付与される【NGKI0306】.そのため,1から連続した正の値であるとは限らない.
マルチプロセッサ対応カーネルでは,異なるプロセッサで発生するCPU例外を異なるCPU例外であると扱い,CPU例外ハンドラをプロセッサ毎に登録する方法と,CPU例外を複数のプロセッサ(すべてのプロセッサでも良い)で共通のものと扱い,CPU例外ハンドラを複数のプロセッサに対して登録する方法がある【NGKI0307】.どちらの方法を採用するか,または両方の方法を併用するかは,ターゲット定義である【NGKI0661】.
CPU例外ハンドラにおいては,CPU例外が発生した状態からのリカバリ処理を行う【NGKI0309】.どのようなリカバリ処理を行うかは,アプリケーション要求と,CPU例外の種類やそれが発生したコンテキストおよび状態に依存するが,大きく次の3つの方法に分類できる【NGKI0310】.
(a) カーネルに依存しない形でCPU例外の原因を取り除き,実行を継続する.
(b) CPU例外を起こしたタスクより優先して実行されるタスクを起動または待ち解除し,そのタスクでリカバリ処理を行う(例えば,CPU例外を起こしたタスクを強制終了し,再度起動する).ただし,リカバリ処理を行うタスクを,CPU例外を起こしたタスクより優先して実行することができない場合には,この方法でリカバリ処理を行うことはできない【NGKI0311】.
(c) システム全体に対してリカバリ処理を行う(例えば,システムを再起動する).
この中で(a)と(c)の方法は,カーネルの機能を必要としないため,CPU例外が発生したコンテキストおよび状態に依存せずに常に行える【NGKI0312】.それに対して(b)の方法は,CPU例外ハンドラからそのためのサービスコールを呼び出せることが必要であり,それが行えるかどうかは,CPU例外が発生したコンテキストおよび状態に依存する【NGKI0313】.
なお,発生したCPU例外に対して,CPU例外ハンドラを登録していない場合の振舞いは,ターゲット定義である【NGKI0314】.
【使用上の注意】
CPU例外入口処理でCPU例外が発生し,それを処理するためのCPU例外ハンドラの入口処理で同じ原因でCPU例外が発生すると,CPU例外が繰り返し発生し,アプリケーションが登録したCPU例外ハンドラまで処理が到達しない状況が考えられる.このような状況が発生するかどうかはターゲットによるが,これが許容できない場合には,CPU例外入口処理を経由せずに,アプリケーションが用意したCPU例外ハンドラを直接実行するようにしなければならない.
【補足説明】
マルチプロセッサ対応カーネルにおけるCPU例外ハンドラ番号の付与方法は,プロセッサ毎のCPU例外に対しては,CPU例外ハンドラ番号の上位ビットにプロセッサのID番号を含める方法を,すべてのプロセッサで共通のCPU例外に対しては,CPU例外ハンドラ番号の上位ビットを0とする方法を基本とする.
リカバリ処理を行うタスクを優先して実行することができない状況[NGKI0311]は,保護機能対応でないカーネルで最高優先度のタスクがCPU例外を起こした場合と,保護機能対応のカーネルでカーネルドメインに属する最高優先度のタスクがCPU例外を起こした場合に限られる.これらの場合にも,リカバリ処理を行うタスクを最高優先度とし,そのタスクの起動または待ち解除後に優先順位を回転させることで,リカバリ処理を行える場合もあるが,CPU例外を起こしたタスクが制約タスクの場合には適用できないなど,推奨できる方法ではない.
【μITRON4.0仕様との関係】
μITRON4.0仕様では,CPU例外からのリカバリ処理の方法については,記述されていない.
【TOPPERS新世代カーネル統合仕様との関係】
タスク例外処理ルーチンを廃止したことで,タスク例外処理ルーチンでリカバリ処理を行う方法が使えなくなったため,それに関する記述を削除した.
マルチプロセッサ対応カーネルで,CPU例外を複数のプロセッサで共通のものと扱うことを許すこととした.
2.8.2 CPU例外ハンドラから呼び出せるサービスコール
CPU例外ハンドラからは,CPU例外発生時のディスパッチ保留状態を参照するサービスコール(xsns_dpn)を呼び出すことができる【NGKI0535】.
xsns_dpnは,CPU例外がタスクコンテキストで発生し,そのタスクがディスパッチできる状態であった場合にfalseを返す【NGKI0316】.xsns_dpnがfalseを返した場合,そのCPU例外ハンドラから,非タスクコンテキストから呼び出せるすべてのサービスコールを呼び出すことができ,[NGKI0311]の状況を除いては,(b)の方法によるリカバリ処理が可能である【NGKI0317】.
xsns_dpnがtrueを返した場合,そのCPU例外ハンドラからは,xsns_dpnに加えて,システムインタフェースレイヤのAPIとsns_ker,ext_kerのみを呼び出すことができ,その他のサービスコールを呼び出すことはできない【NGKI0321】.xsns_dpnがtrueを返したにもかかわらず,その他のサービスコールを呼び出した場合の動作は,保証されない【NGKI0322】.この場合には,(b)の方法によるリカバリ処理は行うことはできず,(a)または(c)の方法によるリカバリ処理を行うしかないことになる.
【μITRON4.0仕様との関係】
CPU例外ハンドラで行える操作に関しては,μITRON4.0仕様を見直し,全面的に修正した.
【TOPPERS新世代カーネル統合仕様との関係】
CPU例外発生時にタスク例外処理ルーチンを実行開始できない状態であったかを参照するサービスコール(xsns_xpn)を廃止した.
2.8.3 エミュレートされたCPU例外ハンドラ
エラーコードによってアプリケーションに通知できないエラーをカーネルが検出した場合に,アプリケーションが登録したエラー処理を,カーネルが呼び出す場合がある【NGKI0323】.この場合に,カーネルが検出するエラーをCPU例外と同等に扱うものとし,エミュレートされたCPU例外と呼ぶ【NGKI0324】.また,エラー処理のためのプログラムをエミュレートされたCPU例外ハンドラと呼び,CPU例外ハンドラと同等に扱うものとする【NGKI0325】.
具体的には,エミュレートされたCPU例外ハンドラに対してもCPU例外ハンドラ番号が付与され,CPU例外ハンドラと同じ方法で登録できる【NGKI0326】.また,エミュレートされたCPU例外ハンドラからも,CPU例外ハンドラから呼び出せるサービスコールを呼び出すことができ,CPU例外ハンドラと同様のリカバリ処理を行うことができる【NGKI0327】.
【μITRON4.0仕様との関係】
エミュレートされたCPU例外およびCPU例外ハンドラは,μITRON4.0仕様に定義されていない概念である.
2.8.4 カーネル管理外のCPU例外
カーネル非動作状態,カーネル内のクリティカルセクションの実行中,全割込みロック状態,CPUロック状態,カーネル管理外の割込みハンドラ実行中のいずれかで発生したCPU例外を,カーネル管理外のCPU例外と呼ぶ.また,それによって起動されるCPU例外ハンドラを,カーネル管理外のCPU例外ハンドラと呼ぶ.さらに,カーネル管理外のCPU例外ハンドラ実行中に発生したCPU例外も,カーネル管理外のCPU例外とする.
それに対して,カーネル管理外のCPU例外以外のCPU例外をカーネル管理のCPU例外,カーネル管理のCPU例外によって起動されるCPU例外ハンドラをカーネル管理のCPU例外ハンドラと呼ぶ.
カーネル管理外のCPU例外ハンドラにおいては,xsns_dpnはtrueを返す【NGKI0330】.そのため,「2.8.2 CPU例外ハンドラから呼び出せるサービスコール」の節で述べた制限[NGKI0321][NGKI0322]が課される.
【補足説明】
カーネル管理外のCPU例外は,カーネル管理外の割込みと異なり,特定のCPU例外をカーネル外とするわけではない.同じCPU例外であっても,CPU例外が起こる状況によって,カーネル管理となる場合とカーネル管理外となる場合がある.
2.9 システムの初期化と終了
2.9.1 システム初期化手順
システムのリセット後,最初に実行するプログラムを,スタートアップモジュールと呼ぶ.スタートアップモジュールはカーネルの管理外であり,アプリケーションで用意するのが基本であるが,スタートアップモジュールで行うべき処理を明確にするために,カーネルの配布パッケージの中に,標準のスタートアップモジュールが用意されている【NGKI0331】.
標準のスタートアップモジュールは,プロセッサのモードとスタックポインタ等の初期化,NMIを除くすべての割込みのマスク(全割込みロック状態と同等の状態にする),ターゲットシステム依存の初期化フックの呼出し,ゼロ初期化データセクション(bssセクション)のクリア,初期化データセクション(dataセクション)の初期化,ソフトウェア環境(ライブラリなど)依存の初期化フックの呼出しを行った後,カーネルの初期化処理へ分岐する【NGKI0332】.ここで呼び出すターゲットシステム依存の初期化フックでは,リセット後に速やかに行うべき初期化処理を行うことが想定されている.
マルチプロセッサ対応カーネルでは,すべてのプロセッサがスタートアップモジュールを実行し,カーネルの初期化処理へ分岐する【NGKI0333】.ただし,共有リソースの初期化処理(ゼロ初期化データセクションのクリア,初期化データセクションの初期化,ソフトウェア環境依存の初期化フックの呼出しなど)は,マスタプロセッサのみで実行する【NGKI0334】.各プロセッサがカーネルの初期化処理へ分岐するのは,共有リソースの初期化処理が完了した後でなければならないため,スレーブプロセッサは,カーネルの初期化処理へ分岐する前に,マスタプロセッサによる共有リソースの初期化処理の完了を待ち合わせる必要がある【NGKI0335】.
カーネルの初期化処理においては,まず,カーネル自身の初期化処理(カーネル内のデータ構造の初期化,カーネルが用いるデバイスの初期化など)と静的APIの処理(オブジェクトの登録など)が行われる【NGKI0336】.静的APIのパラメータに関するエラーは,コンフィギュレータによって検出されるのが原則であるが,コンフィギュレータで検出できないエラーが,この処理中に検出される場合もある【NGKI0337】.
静的APIの処理順序によりシステムの規定された振舞いが変化する場合には,システムコンフィギュレーションファイルにおける静的APIの記述順と同じ順序で静的APIが処理された場合と,同じ振舞いとなる【NGKI0338】.例えば,静的APIによって同じ優先度のタスクを複数生成・起動した場合,静的APIの記述順が先のタスクが高い優先順位を持つ.それに対して,最初の通知時刻が同じである複数の周期通知の通知順序は,同じシステム時刻で行うべき処理が複数ある場合の処理順序が規定されないことから(「4.6.1 システム時刻管理」の節を参照),静的APIの記述順となるとは限らない.
次に,静的API(ATT_INI)により登録した初期化ルーチンが,システムコンフィギュレーションファイルにおける静的APIの記述順と同じ順序で実行される【NGKI0339】.
マルチプロセッサ対応カーネルでは,初期化ルーチンには,クラスに属さないグローバル初期化ルーチンと,クラスに属するローカル初期化ルーチンがある【NGKI0129】.グローバル初期化ルーチンは,すべてのプロセッサがカーネル自身の初期化処理と静的APIの処理を完了した後に,マスタプロセッサによって実行される【NGKI0340】.ローカル初期化ルーチンは,グローバル初期化ルーチンの実行が完了した後に,それが属するクラスの初期割付けプロセッサによって実行される【NGKI0341】.
以上が終了すると,カーネル非動作状態から動作状態に遷移し(「2.5.1 カーネル動作状態と非動作状態」の節を参照),カーネルの動作が開始される【NGKI0342】.具体的には,システム状態が,全割込みロック解除状態・CPUロック解除状態・割込み優先度マスク全解除状態・ディスパッチ許可状態に設定され(すなわち,ディスパッチ保留状態が解除され),タスクの実行が開始される.
マルチプロセッサ対応カーネルでは,すべてのプロセッサがローカル初期化ルーチンの実行を完了した後に,カーネル非動作状態から動作状態に遷移し,カーネルの動作が開始される【NGKI0343】.マルチプロセッサ対応カーネルにおけるシステム初期化の流れと,各プロセッサが同期を取るタイミングを,図2-8に示す【NGKI0344】.

【μITRON4.0仕様との関係】
μITRON4.0仕様においては,初期化ルーチンの実行は静的APIの処理に含まれるものとしていたが,この仕様では,初期化ルーチンを登録する静的APIの処理は,初期化ルーチンを登録することのみを意味し,初期化ルーチンの実行は含まないものとした.
2.9.2 システム終了手順
カーネルを終了させるサービスコール(ext_ker)を呼び出すと,カーネル動作状態から非動作状態に遷移する(「2.5.1 カーネル動作状態と非動作状態」の節を参照)【NGKI0345】.具体的には,NMIを除くすべての割込みがマスクされ,タスクの実行が停止される.
マルチプロセッサ対応カーネルでは,カーネルを終了させるサービスコール(ext_ker)は,どのプロセッサからでも呼び出すことができる【NGKI0346】.1つのプロセッサでカーネルを終了させるサービスコールを呼び出すと,そのプロセッサがカーネル動作状態から非動作状態に遷移した後,他のプロセッサに対してカーネル終了処理の開始を要求する【NGKI0347】.複数のプロセッサから,カーネルを終了させるサービスコール(ext_ker)を呼び出してもよい【NGKI0348】.
次に,静的API(ATT_TER)により登録した終了処理ルーチンが,システムコンフィギュレーションファイルにおける静的APIの記述順と逆の順序で実行される【NGKI0349】.
マルチプロセッサ対応カーネルでは,終了処理ルーチンには,クラスに属さないグローバル終了処理ルーチンと,クラスに属するローカル終了処理ルーチンがある【NGKI0131】.ローカル終了処理ルーチンは,すべてのプロセッサがカーネル非動作状態に遷移した後に,それが属するクラスの初期割付けプロセッサによって実行される【NGKI0350】.グローバル終了処理ルーチンは,すべてのプロセッサでローカル終了処理ルーチンの実行が完了した後に,マスタプロセッサによって実行される【NGKI0351】.
以上が終了すると,ターゲットシステム依存の終了処理が呼び出される【NGKI0352】.ターゲットシステム依存の終了処理は,カーネルの管理外であり,アプリケーションで用意するのが基本であるが,カーネルの配布パッケージの中に,ターゲットシステム毎に標準的なルーチンが用意されている【NGKI0353】.標準のターゲットシステム依存の終了処理では,ソフトウェア環境(ライブラリなど)依存の終了処理フックを呼び出す【NGKI0354】.
マルチプロセッサ対応カーネルでは,すべてのプロセッサで,ターゲットシステム依存の終了処理が呼び出される【NGKI0355】.マルチプロセッサ対応カーネルにおけるシステム終了処理の流れと,各プロセッサが同期を取るタイミングを,図2-9に示す【NGKI0356】.

【使用上の注意】
マルチプロセッサ対応カーネルで,あるプロセッサからカーネルを終了させるサービスコール(ext_ker)を呼び出しても,他のプロセッサがカーネル動作状態で割込みをマスクしたまま実行し続けると,カーネルが終了しない.
プロセッサが割込みをマスクしたまま実行し続けないようにするのは,アプリケーションの責任である.例えば,ある時間を超えて割込みをマスクしたまま実行し続けていないかを,ウォッチドッグタイマを用いて監視する方法が考えられる.割込みをマスクしたまま実行し続けていた場合には,そのプロセッサからもカーネルを終了させるサービスコール(ext_ker)を呼び出すことで,カーネルを終了させることができる.
【μITRON4.0仕様との関係】
μITRON4.0仕様には,システム終了に関する規定はない.
2.10 オブジェクトの登録とその解除
2.10.1 ID番号で識別するオブジェクト
ID番号で識別するオブジェクトは,オブジェクトを生成する静的API(CRE_YYY)またはサービスコール(acre_yyy)によってカーネルに登録する【NGKI0357】.
オブジェクトを生成する静的API(CRE_YYY)は,生成するオブジェクトにID番号を割り付け,オブジェクトの識別名を割り付けたID番号にマクロ定義する【NGKI0359】.同じ識別名のオブジェクトが生成済みの場合には,E_OBJエラーとなる【NGKI0360】.
オブジェクトを生成するサービスコール(acre_yyy)は,割付け可能なID番号の数を指定する静的API(AID_YYY)によって確保されたID番号の中から,使用されていないID番号を1つ選び,生成するオブジェクトに割り付ける【NGKI0361】.割り付けたID番号は,サービスコールの返値としてアプリケーションに通知する【NGKI0362】.使用されていないID番号が残っていない場合には,E_NOIDエラーとなる【NGKI0363】.
割付け可能なID番号の数を指定する静的API(AID_YYY)は,システムコンフィギュレーションファイル中に複数記述することができる【NGKI0364】.その場合,各静的APIで指定した数の合計の数のID番号が確保される【NGKI0365】.
オブジェクトを生成するサービスコール(acre_yyy)によって登録したオブジェクトは,オブジェクトを削除するサービスコール(del_yyy)によって登録を解除することができる【NGKI0366】.登録解除したオブジェクトのID番号は,未使用の状態に戻され,新たに生成するオブジェクトに割り付けられる【NGKI0367】.この場合に,登録解除前のオブジェクトに対して行うつもりの操作が,新たに生成したオブジェクトに対して行われないように,注意が必要である.
オブジェクトを生成する静的APIによって登録したオブジェクトは,登録を解除することができない.登録を解除しようとした場合には,E_OBJエラーとなる【NGKI0369】.
タスク以外の処理単位は,その処理単位が実行されている間でも,登録解除することができる【NGKI0370】.この場合,登録解除された処理単位の実行が途中で終了させられることはなく,処理単位が自ら実行を終了するまで,処理単位の実行は継続される【NGKI0371】.
同期・通信オブジェクトを削除した時に,そのオブジェクトを待っているタスクがあった場合,それらのタスクは待ち解除され,待ち状態に遷移させたサービスコールはE_DLTエラーとなる【NGKI0372】.複数のタスクが待ち解除される場合には,待ち行列につながれていた順序で待ち解除される【NGKI0373】.削除した同期・通信オブジェクトが複数の待ち行列を持つ場合には,別の待ち行列で待っていたタスクの間の待ち解除の順序は,該当するサービスコール毎に規定する【NGKI0374】.
オブジェクトを再初期化するサービスコール(ini_yyy)は,指定したオブジェクトを削除した後に,同じパラメータで再度生成したのと等価の振舞いをする【NGKI0375】.ただし,オブジェクトを生成する静的APIによって登録したオブジェクトも,再初期化することができる【NGKI0376】.
なお,動的生成対応でないカーネルでは,オブジェクトを生成するサービスコール(acre_yyy),割付け可能なID番号の数を指定する静的API(AID_YYY),オブジェクトのアクセス許可ベクタを設定するサービスコール(sac_yyy),オブジェクトを削除するサービスコール(del_yyy)は,サポートされない【NGKI0377】.
【μITRON4.0仕様との関係】
ID番号を指定してオブジェクトを生成するサービスコール(cre_yyy)を廃止した.また,ID番号で識別するオブジェクトを,オブジェクトを追加する静的API(ATT_YYY)によってカーネルに登録する機能を廃止した.オブジェクトを生成する静的APIによって登録したオブジェクトは,登録解除できないこととした.
μITRON4.0仕様では,割付け可能なID番号の数を指定する静的API(AID_YYY)は規定されていない.
複数の待ち行列を持つ同期・通信オブジェクトを削除した時に,別の待ち行列で待っていたタスクの間の待ち解除の順序は,μITRON4.0仕様では実装依存とされている.
【μITRON4.0/PX仕様との関係】
アクセス許可ベクタを指定してオブジェクトを生成する静的API(CRA_YYY)は廃止し,オブジェクトの登録後にアクセス許可ベクタを設定する静的API(SAC_YYY)をサポートすることとした.これにあわせて,アクセス許可ベクタを指定してオブジェクトを登録するサービスコール(cra_yyy,acra_yyy,ata_yyy)も廃止した.
【TOPPERS新世代カーネル統合仕様との関係】
ID番号で識別するオブジェクトを,オブジェクトを追加する静的API(ATT_YYY)によってカーネルに登録する機能を廃止した.
【仕様決定の理由】
ID番号を指定してオブジェクトを生成するサービスコール(cre_yyy)とアクセス許可ベクタを指定してオブジェクトを登録するサービスコール(cra_yyy,acra_yyy,ata_yyy)を廃止したのは,必要性が低いと考えたためである.静的APIについても,サービスコールに整合するよう変更した.
2.10.2 オブジェクト番号で識別するオブジェクト
オブジェクト番号で識別するオブジェクトは,オブジェクトを定義する静的API(DEF_YYY)またはサービスコール(def_yyy)によってカーネルに登録する【NGKI0378】.
オブジェクトを定義するサービスコール(def_yyy)によって登録したオブジェクトは,同じサービスコールを,オブジェクトの定義情報を入れたパケットへのポインタをNULLとして呼び出すことによって,登録を解除することができる【NGKI0379】.登録解除したオブジェクト番号は,オブジェクト登録前の状態に戻され,同じオブジェクト番号に対して新たにオブジェクトを定義することができる【NGKI0380】.登録解除されていないオブジェクト番号に対して再度オブジェクトを登録しようとした場合には,E_OBJエラーとなる【NGKI0381】.
オブジェクトを定義する静的APIによって登録したオブジェクトは,登録を解除することができない【NGKI0382】.登録を解除しようとした場合には,E_OBJエラーとなる【NGKI0383】.
なお,動的生成対応でないカーネルでは,オブジェクトを定義するサービスコール(def_yyy)はサポートされない【NGKI0384】.
【μITRON4.0仕様との関係】
この仕様では,オブジェクトの定義を変更したい場合には,一度登録解除した後に,新たにオブジェクトを定義する必要がある.また,オブジェクトを定義する静的APIによって登録したオブジェクトは,この仕様では,登録解除できないこととした.
2.10.3 識別番号を持たないオブジェクト
識別する必要がないために,識別番号を持たないオブジェクトは,オブジェクトを追加する静的API(ATT_YYY)によってカーネルに登録する【NGKI0604】.
2.10.4 オブジェクト生成に必要なメモリ領域
オブジェクトを生成する際に必要なメモリ領域の内,サイズが一定のものについては,コンフィギュレータによって,オブジェクトの管理ブロックなどの形で確保される【NGKI0665】.
それに対して,オブジェクトを生成する際に,サイズが一定でないメモリ領域を必要とする場合には,オブジェクトを生成する静的APIおよびサービスコールに,使用するメモリ領域の先頭番地を渡すパラメータを設ける【NGKI0385】.
静的APIにおいて,使用するメモリ領域の先頭番地を渡すパラメータをNULLとした場合,必要なメモリ領域は,コンフィギュレータによって確保される【NGKI0386】.
保護機能対応カーネルでは,コンフィギュレータによって確保されるメモリ領域は,別に規定がない限りは,カーネルドメイン向け(マルチプロセッサ対応カーネルの場合には,さらに,オブジェクトが属するクラス向け)の標準RAMリージョン内に確保される【NGKI0649】.
サービスコールにおいて,使用するメモリ領域の先頭番地を渡すパラメータをNULLとした場合,必要なメモリ領域は,カーネルによって,別に規定がない限りは,カーネルメモリプール領域から確保される【NGKI0618】.保護機能対応カーネルまたはマルチプロセッサ対応カーネルで,どのカーネルメモリプール領域が使用されるかについては,「4.13 システム構成管理機能」の節を参照すること.
【TOPPERS新世代カーネル統合仕様との関係】
コンフィギュレータとカーネルが,オブジェクト生成に必要なメモリ領域をどこに確保するかを規定した.
2.10.5 オブジェクトが属する保護ドメインの設定
保護機能対応カーネルにおいて,オブジェクトが属する保護ドメインは,オブジェクトの登録時に決定し,登録後に変更することはできない【NGKI0387】.
オブジェクトを静的APIによって登録する場合には,オブジェクトを登録する静的APIを,そのオブジェクトを属させる保護ドメインの囲みの中に記述する[NGKI0459].無所属のオブジェクトを登録する静的APIは,保護ドメインの囲みの外に記述する[NGKI0460](「2.12.3 保護ドメインの指定」の節を参照).
オブジェクトをサービスコールによって登録する場合には,オブジェクト属性にTA_DOM(domid)を指定することにより,オブジェクトを属させる保護ドメインを設定する【NGKI0390】.ここでdomidは,そのオブジェクトを属させる保護ドメインのID番号であり,TDOM_KERNEL(=-1)を指定することでカーネルドメインに属させることができる.また,domidにTDOM_SELF(=0)を指定するか,オブジェクト属性にTA_DOM(domid)を指定しないことで,自タスクが属する保護ドメインに属させることができる.さらに,無所属のオブジェクトを登録する場合には,domidにTDOM_NONE(=-2)を指定する.
ただし,特定の保護ドメインのみに属することができるオブジェクトを登録するサービスコールの中には,オブジェクトを属させる保護ドメインをオブジェクト属性で設定する必要がないものもある【NGKI0391】.
割付け可能なID番号の数を指定する静的API(AID_YYY)で確保したID番号は,AID_YYYを保護ドメインの囲みの中に記述した場合には,その保護ドメインに属するオブジェクトに,保護ドメインの囲みの外に記述した場合には,無所属のオブジェクトに割り付けられる【NGKI0610】.
【補足説明】
この仕様では,カーネルオブジェクトが属する保護ドメインを参照する機能は用意していない.
【TOPPERS新世代カーネル統合仕様との関係】
割付け可能なID番号は保護ドメイン毎に確保することにし,AID_YYYを保護ドメインの囲みの中にも記述できることとした.
【仕様決定の理由】
オブジェクトをサービスコールによって登録する場合に,オブジェクトを属させる保護ドメインをオブジェクト属性で指定することにしたのは,保護機能対応でないカーネルとの互換性のためには,サービスコールのパラメータを増やさない方が望ましいためである.
2.10.6 オブジェクトが属するクラスの設定
マルチプロセッサ対応カーネルにおいて,オブジェクトが属するクラスは,オブジェクトの登録時に決定し,登録後に変更することはできない【NGKI0395】.
オブジェクトを静的APIによって登録する場合には,オブジェクトを登録する静的APIを,そのオブジェクトを属させるクラスの囲みの中に記述する[NGKI0470].クラスに属さないオブジェクトを登録する静的APIは,クラスの囲みの外に記述する[NGKI0397](「2.12.4 クラスの指定」の節を参照).
オブジェクトをサービスコールによって登録する場合には,オブジェクト属性にTA_CLS(clsid)を指定することにより,オブジェクトを属させるクラスを設定する【NGKI0398】.ここでclsidは,そのオブジェクトを属させるクラスのID番号であり,clsidにTCLS_SELF(=0)を指定するか,オブジェクト属性にTA_CLS(clsid)を指定しないことで,自タスクが属するクラスに属させることができる.
割付け可能なID番号の数を指定する静的API(AID_YYY)で確保したID番号は,AID_YYYを囲むクラスに属するオブジェクトにのみ割り付けられる【NGKI0399】.AID_YYYは,確保したID番号を割り付けるオブジェクトの属すべきクラスの囲みの中に記述しなければならない.クラスの囲みの外に記述した場合には,E_RSATRエラーとなる【NGKI0401】.
【補足説明】
この仕様では,カーネルオブジェクトが属するクラスを参照する機能は用意していない.
【仕様決定の理由】
オブジェクトをサービスコールによって登録する場合に,オブジェクトを属させるクラスをオブジェクト属性で指定することにしたのは,マルチプロセッサ対応でないカーネルとの互換性のためには,サービスコールのパラメータを増やさない方が望ましいためである.
2.10.7 オブジェクトの状態参照
ID番号で識別するオブジェクトのすべてと,オブジェクト番号で識別するオブジェクトの一部に対して,オブジェクトの状態を参照するサービスコール(ref_yyy,get_yyy)を用意する【NGKI0402】.
オブジェクトの状態を参照するサービスコールでは,オブジェクトの登録時に指定し,その後に変化しない情報(例えば,タスクのタスク属性や初期優先度)を参照するための機能は用意しないことを原則とする【NGKI0403】.自タスクの拡張情報を参照するサービスコール(get_inf)は,この原則に対する例外の一つである.
2.11 オブジェクトのアクセス保護
この節では,カーネルオブジェクトのアクセス保護について述べる.この節の内容は,保護機能対応カーネルにのみ適用される.
【μITRON4.0/PX仕様との関係】
システム時刻に対するアクセス許可ベクタと,それを設定する静的APIおよびサービスコールを廃止し,保護ドメインに対するアクセス許可ベクタと,それを設定する静的APIおよびサービスコールを追加した.また,システム状態に対して,アクセス許可ベクタを2つ持つこととした.
【TOPPERS新世代カーネル統合仕様との関係】
保護ドメインに対するアクセス許可ベクタと,それを設定する静的APIおよびサービスコールを追加した.また,システム状態に対して,アクセス許可ベクタを2つ持つこととした.
2.11.1 オブジェクトのアクセス保護とアクセス違反の通知
カーネルオブジェクトに対するアクセスは,そのオブジェクトに対して設定されたアクセス許可ベクタによって保護される【NGKI0405】.ただし,アクセス許可ベクタを持たないオブジェクトに対するアクセスや,特定のオブジェクトに関連しないシステムの状態に対する操作,オブジェクトを定義するサービスコールについては,スケジューリングに関係するものは保護ドメインに対するアクセス許可ベクタによって,その他はシステム状態に対するアクセス許可ベクタによって保護される【NGKI0568】.また,オブジェクトを生成するサービスコールは,生成するオブジェクトが属する保護ドメインに対するアクセス許可ベクタによって保護される【NGKI0612】.
アクセス許可ベクタ等によって許可されていないアクセス(アクセス違反)は,カーネルによって検出され,以下の方法によって通知される.
サービスコールにより,メモリオブジェクト以外のカーネルオブジェクトに対して,アクセス許可ベクタによって許可されていないアクセスを行おうとした場合,サービスコールからE_OACVエラーが返る【NGKI0408】.また,メモリオブジェクトに対して,アクセス許可ベクタによって許可されていない管理操作または参照操作を行おうとした場合も,サービスコールからE_OACVエラーが返る【NGKI0409】.
メモリオブジェクトに対して,通常のメモリアクセスにより,アクセス許可ベクタまたはメモリオブジェクト属性によって許可されていない書込みアクセスまたは読出しアクセス(実行アクセスを含む)を行おうとした場合,CPU例外ハンドラが起動される【NGKI0410】.どのCPU例外ハンドラが起動されるかは,ターゲット定義である【NGKI0411】.ターゲットによっては,エミュレートされたCPU例外ハンドラの場合もある.また,ターゲット定義で,アクセス違反の状況に応じて異なるCPU例外ハンドラが起動される場合もある.この(これらの)CPU例外ハンドラを,メモリアクセス違反ハンドラと呼ぶ.
メモリアクセス違反ハンドラで,アクセス違反を発生させたアクセスに関する情報(アクセスした番地,アクセスの種別,アクセスした命令の番地など)を参照する方法が,ターゲット定義で用意されている【NGKI0414】.
メモリオブジェクトに対して,サービスコールを通じて,アクセス許可ベクタまたはメモリオブジェクト属性によって許可されていない書込みアクセスまたは読出しアクセスを行おうとした場合,サービスコールからE_MACVエラーが返る【NGKI0412】.ただし,ターゲット定義で,E_MACVエラーが返るのに代えて,メモリアクセス違反ハンドラが起動される場合がある【NGKI0413】.
メモリオブジェクトとしてカーネルに登録されていないメモリ領域に対して,ユーザドメインから書込みアクセスまたは読出しアクセス(実行アクセスを含む)を行おうとした場合には,メモリオブジェクトに対するアクセスが許可されていない場合と同様に扱われる【NGKI0415】.
ユーザタスクから,サービスコールを通じて,メモリオブジェクトの境界を越えるメモリ領域にアクセスを行おうとした場合,サービスコールからE_MACVエラーが返る【NGKI0673】.ただし,ターゲット定義で,このエラーチェックが省略される場合がある【NGKI0674】.
ユーザタスクから,サービスコールを通じて,アラインされていないメモリアクセスを行おうとした場合,サービスコールからE_MACVエラーが返る【NGKI0670】.ただし,ターゲット定義で,E_MACVエラーが返るのに代えて,ターゲット定義のCPU例外ハンドラが起動される場合がある【NGKI0671】
【補足説明】
以下の状況における振舞いは,この仕様では規定されず,ターゲットに依存する.
-
メモリオブジェクトとしてカーネルに登録されていないメモリ領域に対して,カーネルドメインからアクセスしようとした場合
-
カーネルドメインに属する処理単位から,サービスコールを通じて,アラインされていないメモリアクセスを行おうとした場合
【μITRON4.0/PX仕様との関係】
μITRON4.0/PX仕様では,アクセス保護の実装定義の制限について規定しているが,この仕様では,メモリオブジェクトに対するアクセス許可ベクタのターゲット定義の制限以外については規定していない.
オブジェクトを生成するサービスコールの保護は,生成するオブジェクトが属する保護ドメインに対するアクセス許可ベクタによって行うものとした.
サービスコールを通じて,メモリオブジェクトの境界を越えるメモリ領域にアクセスを行おうとした場合と,アラインされていないメモリアクセスを行おうとした場合の振舞い明記した.
【TOPPERS新世代カーネル統合仕様との関係】
オブジェクトを生成するサービスコールの保護は,生成するオブジェクトが属する保護ドメインに対するアクセス許可ベクタによって行うものとした.これに伴って,オブジェクトを生成する際に使用するリソース(ID番号,カーネルメモリプール領域)の確保量についても,保護ドメイン毎に設定することとした.
サービスコールを通じて,メモリオブジェクトの境界を越えるメモリ領域にアクセスを行おうとした場合と,アラインされていないメモリアクセスを行おうとした場合の振舞い明記した.
【仕様決定の理由】
オブジェクトを登録するサービスコールを,そのオブジェクトのアクセス許可ベクタによって保護しないのは,オブジェクトを登録する前には,アクセス許可ベクタが設定されていないためである.
2.11.2 メモリオブジェクトに対するアクセス許可ベクタの制限
メモリオブジェクトの書込みアクセスと読出しアクセス(実行アクセスを含む)に対して設定できるアクセス許可パターンは,ターゲット定義で制限される場合がある【NGKI0417】.
ただし,少なくとも,次の5つの組み合わせの設定は,行うことができる.
(a) メモリオブジェクトが属する保護ドメインのみに,読出しアクセス(実行アクセスを含む)のみを許可する【NGKI0418】.これを,専有リードオンリー(private read only)と呼ぶ.
(b) メモリオブジェクトが属する保護ドメインのみに,書込みアクセスと読出しアクセス(実行アクセスを含む)を許可する【NGKI0419】.これを,専有リードライト(private read/write)と呼ぶ.
(c) すべての保護ドメインに,読出しアクセス(実行アクセスを含む)のみを許可する【NGKI0420】.これを,共有リードオンリー(shared read only)と呼ぶ.
(d) すべての保護ドメインに,書込みアクセスと読出しアクセス(実行アクセスを含む)を許可する【NGKI0421】.これを,共有リードライト(shared read/write)と呼ぶ.
(e) メモリオブジェクトが属する保護ドメインに,書込みアクセスと読出しアクセス(実行アクセスを含む)を許可し,他の保護ドメインには,読出しアクセス(実行アクセスを含む)のみを許可する【NGKI0422】.これを,共有リード専有ライト(shared read private write)と呼ぶ.
また,ターゲット定義で,1つの保護ドメインに登録できるメモリオブジェクトの数が制限される場合がある【NGKI0423】.
2.11.3 デフォルトのアクセス許可ベクタ
カーネルオブジェクトを登録した直後は,次に規定されるデフォルトのアクセス許可ベクタが設定される.
保護ドメインに属するカーネルオブジェクトに対しては,通常操作1,通常操作2,参照操作の3つの種別のアクセスが,その保護ドメインのみに許可される【NGKI0613】.すなわち,カーネルドメインに属するオブジェクトに対しては,上記の3つのアクセス種別のアクセス許可パターンがTACP_KERNELに,ユーザドメインに属するオブジェクトに対しては,上記の3つのアクセス種別のアクセス許可パターンがTACP(domid)(domidはオブジェクトが属する保護ドメインのID番号)に設定される.管理操作のアクセス許可パターンは,そのカーネルオブジェクトが属する保護ドメインに対する通常操作1のアクセス許可パターンと同じ値に設定される【NGKI0614】.
無所属のカーネルオブジェクトに対しては,通常操作1,通常操作2,参照操作の3つの種別のアクセスが,すべての保護ドメインに許可される【NGKI0615】.すなわち,上記の3つのアクセス種別のアクセス許可パターンが,TACP_SHAREDに設定される.管理操作のアクセス許可パターンは,無所属に対する通常操作1のアクセス許可パターンと同じ値に設定される【NGKI0616】.
保護ドメインのアクセス許可ベクタは,通常操作1,通常操作2,参照操作はその保護ドメインのみに許可され,管理操作はカーネルドメインのみに許可される【NGKI0569】.すなわち,カーネルドメインに対しては,4つのアクセス許可パターンがいずれもTACP_KERNELに,ユーザドメインに対しては,通常操作1,通常操作2,参照操作のアクセス許可パターンがTACP(domid)に,管理操作のアクセス許可パターンがTACP_KERNELに設定される.
無所属に対するアクセス許可ベクタは,通常操作1,通常操作2,参照操作はすべての保護ドメインに許可され,管理操作はカーネルドメインのみに許可される【NGKI0617】.すなわち,通常操作1,通常操作2,参照操作のアクセス許可パターンがTACP_SHAREDに,管理操作のアクセス許可パターンがTACP_KERNELに設定される.
システム状態1とシステム状態2のアクセス許可ベクタは,4つの種別のアクセスがいずれも,カーネルドメインのみに許可される【NGKI0426】.すなわち,8つのアクセス許可パターンがいずれも,TACP_KERNELに設定される.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
保護ドメイン以外のカーネルオブジェクトに対する管理操作のアクセス許可パターンを,そのカーネルオブジェクトが属する保護ドメインに対する通常操作1(無所属のカーネルドメイン場合は,無所属に対する通常操作1)のアクセス許可パターンと同じ値に設定されるものとした.
2.11.4 アクセス許可ベクタの設定
アクセス許可ベクタをデフォルト以外の値に設定するために,カーネルオブジェクトのアクセス許可ベクタを設定する静的API(SAC_YYY)と,保護ドメインのアクセス許可ベクタを設定する静的API(ACV_DOM),システム状態のアクセス許可ベクタを設定する静的API(SAC_SYS)が用意されている【NGKI0570】.
また,動的生成対応カーネルにおいては,カーネルオブジェクトのアクセス許可ベクタを設定するサービスコール(sac_yyy)と,保護ドメインのアクセス許可ベクタを設定するサービスコール(sac_dom),システム状態のアクセス許可ベクタを設定するサービスコール(sac_sys)が用意されている【NGKI0571】.ただし,静的APIによって登録したオブジェクトは,サービスコール(sac_yyy)によってアクセス許可ベクタを設定することができない.アクセス許可ベクタを設定しようとした場合には,E_OBJエラーとなる【NGKI0430】.
メモリオブジェクトに対しては,アクセス許可ベクタを設定する静的APIは用意されておらず,オブジェクトを追加する静的API(ATT_YYY)によって,登録と同時にアクセス許可ベクタを設定することができる【NGKI0605】.アクセス許可ベクタの記述を省略した場合には,デフォルトのアクセス許可ベクタが設定される【NGKI0606】.
オブジェクトに対するアクセスが許可されているかは,そのオブジェクトにアクセスするサービスコールを呼び出した時点でチェックされる【NGKI0432】.そのため,アクセス許可ベクタを変更しても,変更以前に呼び出されたサービスコールの振舞いには影響しない.例えば,待ち行列を持つ同期・通信オブジェクトのアクセス許可ベクタを変更しても,呼び出した時点ですでに待ち行列につながれているタスクには影響しない.また,ミューテックスのアクセス許可ベクタを変更しても,呼び出した時点ですでにミューテックをロックしていたタスクには影響しない.
この仕様では,カーネルオブジェクトに設定されたアクセス許可ベクタを参照する機能は用意していない.
【使用上の注意】
カーネルオブジェクトのアクセス許可ベクタをデフォルト以外の値に設定する際に,オブジェクトに対して同じ保護ドメインに属する処理単位からアクセスできるようにするには,その保護ドメインからアクセスできることを明示的に指定する必要がある.
【μITRON4.0/PX仕様との関係】
アクセス許可ベクタを指定してオブジェクトを生成する静的API(CRA_YYY)は廃止し,オブジェクトの登録後にアクセス許可ベクタを設定する静的API(SAC_YYY)をサポートすることとした.
静的APIによって登録したオブジェクトは,サービスコール(sac_yyy)によってアクセス許可ベクタを設定することができないこととした.
オブジェクトの状態参照するサービスコール(ref_yyy)により,オブジェクトに設定されたアクセス許可ベクタを参照する機能サポートしないこととした.
【TOPPERS新世代カーネル統合仕様との関係】
メモリオブジェクトに対しては,オブジェクトを追加する静的API(ATT_YYY)によって,オブジェクトの登録と同時にアクセス許可ベクタを設定することができるようにし,登録と同時にアクセス許可ベクタを設定する静的API(ATA_YYY)は廃止した.
2.11.5 カーネルの管理領域のアクセス保護
カーネルオブジェクトの生成に必要なメモリ領域(「2.10.4 オブジェクト生成に必要なメモリ領域」の節を参照)の中で,カーネルの内部およびカーネルドメインに属する処理単位のみからアクセスされるものを,カーネルの管理領域と呼ぶ.
ユーザドメインに属する処理単位からカーネルを保護するためには,カーネルの管理領域にアクセスできるのは,カーネルドメインのみでなければならない.そのため,カーネルの管理領域は,書込みアクセスおよび読出しアクセスが可能で,4つの種別のアクセスがカーネルドメインのみに許可されたメモリオブジェクト(これを,カーネル専用のメモリオブジェクトと呼ぶ)の中に置かれる【NGKI0433】.
カーネルの管理領域として,カーネル専用のメモリオブジェクトに含まれないメモリ領域を指定した場合,E_OBJエラーとなる【NGKI0434】.また,カーネルの管理領域の先頭番地にNULLを指定した場合,必要なメモリ領域が,カーネル専用のメモリオブジェクトの中に確保される【NGKI0435】.
【補足説明】
以下のメモリ領域が,カーネルの管理領域に該当する.
-
システムタスクのスタック領域
-
ユーザタスクのシステムスタック領域
-
データキュー管理領域
-
優先度データキュー管理領域
-
メッセージバッファ管理領域
-
固定長メモリプール管理領域
-
非タスクコンテキスト用のスタック領域
-
カーネルメモリプール領域
ユーザタスクのユーザスタック領域と固定長メモリプール領域は,ユーザドメインに属する処理単位からもアクセスされるため,カーネルの管理領域には該当しない.
2.11.6 ユーザタスクのユーザスタック領域
ユーザタスクが非特権モードで実行する間に用いるスタック領域を,システムスタック領域(「4.1 タスク管理機能」の節を参照)と対比させて,ユーザスタック領域と呼ぶ.ユーザスタック領域は,そのタスクと同じ保護ドメインに属する1つのメモリオブジェクトとしてカーネルに登録される【NGKI0437】.ただし,他のメモリオブジェクトとは異なり,次のように扱われる.
タスクのユーザスタック領域に対しては,そのタスクのみが書込みアクセスおよび読出しアクセスを行うことができる【NGKI0438】.そのため,通常操作1(書込みアクセス)と通常操作2(読出し・実行アクセス)に対するアクセス許可パターンは意味を持たない【NGKI0439】.管理操作と参照操作に対するアクセス許可パターンは,タスクと同じ値に設定される【NGKI0609】.また,ユーザスタック領域に対する実行アクセスは,禁止する【NGKI0663】.ただし,ターゲットハードウェアの制約によって実行アクセスを禁止できない場合には,ターゲット定義で,実行アクセスを禁止しないこととする【NGKI0440】.
ただし,上記の仕様を実現するために大きいオーバヘッドを生じる場合には,ターゲット定義で,タスクのユーザスタック領域を,そのタスクが属する保護ドメイン全体からアクセスできるものとする場合がある【NGKI0441】.
【μITRON4.0/PX仕様との関係】
この仕様では,タスクのユーザスタック領域は,そのタスクのみがアクセスできるものとした.
2.12 システムコンフィギュレーション手順
2.12.1 システムコンフィギュレーションファイル
カーネルやシステムサービスが管理するオブジェクトの生成情報や初期状態などを記述するファイルを,システムコンフィギュレーションファイル(system configuration file)と呼ぶ.また,システムコンフィギュレーションファイルを解釈して,カーネルやシステムサービスの構成・初期化情報を含むファイルなどを生成するツールを,コンフィギュレータ(configurator)と呼ぶ.
システムコンフィギュレーションファイルには,カーネルの静的API,システムサービスの静的API,保護ドメインの囲み,クラスの囲み,コンフィギュレータに対するINCLUDEディレクティブ,C言語プリプロセッサのインクルードディレクティブ(#include)と条件ディレクティブ(#if,#ifdefなど)のみを記述することができる【NGKI0442】.
コンフィギュレータに対するINCLUDEディレクティブは,システムコンフィギュレーションファイルを複数のファイルに分割して記述するために用いるもので,その文法は次の通りである【NGKI0619】.
INCLUDE("ファイル名");
コンフィギュレータは,INCLUDEディレクティブによって指定されたファイル中の記述を,システムコンフィギュレーションファイルの一部分として解釈する【NGKI0444】.すなわち,INCLUDEディレクティブによって指定されたファイル中には,カーネルの静的API,システムサービスの静的API,保護ドメインの囲み,クラスの囲み,コンフィギュレータに対するINCLUDEディレクティブ,C言語プリプロセッサのインクルードディレクティブと条件ディレクティブのみを記述することができる.
C言語プリプロセッサのインクルードディレクティブは,静的APIのパラメータを解釈するために必要なC言語のヘッダファイルを指定するために用いる【NGKI0445】.コンフィギュレータが生成するファイルでは,インクルードディレクティブは先頭に集められる【NGKI0447】.
C言語プリプロセッサの条件ディレクティブは,有効とする静的APIとC言語プリプロセッサのディレクティブを選択するために用いることができる【NGKI0620】.1つの静的APIの記述の途中に,条件ディレクティブを記述することはできない【NGKI0448】.
コンフィギュレータは,システムコンフィギュレーションファイル中の静的APIを,その記述順に解釈する【NGKI0449】.そのため例えば,タスクを生成する静的APIの前に,そのタスクにアクセス許可ベクタを設定する静的APIが記述されていた場合,アクセス許可ベクタを設定する静的APIがE_NOEXSエラーとなる.
【使用上の注意】
C言語プリプロセッサのインクルードディレクティブは,コンフィギュレータが生成するファイルでは先頭に集められるため,インクルードするC言語のヘッダファイル中でマクロの定義を変更(定義を解除した後に,定義し直す)した場合,意図しない動作をする可能性がある.
C言語プリプロセッサの条件ディレクティブは,保護ドメインの囲みを無効にしない.そのため,条件ディレクティブで囲みが選択されなかった保護ドメインに対しても,保護ドメインIDが割り付けられる.
【μITRON4.0仕様との関係】
システムコンフィギュレーションファイルにおけるC言語プリプロセッサのディレクティブの扱いを全面的に見直し,コンフィギュレータに対するINCLUDEディレクティブを設けた.また,共通静的APIを廃止した.μITRON4.0仕様における#includeディレクティブの役割は,この仕様ではINCLUDEディレクティブに置き換わる.逆に,μITRON4.0仕様におけるINCLUDE静的APIの役割は,この仕様では#includeディレクティブに置き換わる.
【TOPPERS新世代カーネル統合仕様との関係】
C言語プリプロセッサの条件ディレクティブは,有効とするC言語プリプロセッサのディレクティブの選択にも用いることができるものとした.
2.12.2 静的APIの文法とパラメータ
静的APIは,次に述べる例外を除いては,C言語の関数呼出しと同様の文法で記述する【NGKI0450】.すなわち,静的APIの名称に続けて,静的APIの各パラメータを","で区切って列挙したものを"("と")"で囲んで記述し,最後に";"を記述する.ただし,静的APIのパラメータに構造体(または構造体へのポインタ)を記述する場合には,構造体の各フィールドを","で区切って列挙したものを"{"と"}"で囲んだ形で記述する【NGKI0451】.
サービスコールに対応する静的APIの場合,静的APIのパラメータは,対応するサービスコールのパラメータと同一とすることを原則とする【NGKI0452】.
静的APIのパラメータは,次の4種類に分類される.
(a) オブジェクト識別名
オブジェクトのID番号を表す識別名を指定するパラメータ.単一の識別名のみを記述することができる.
コンフィギュレータは,オブジェクト生成のための静的API(CRE_YYY)を処理する際に,オブジェクトにID番号を割り付け,構成・初期化ヘッダファイルに,指定された識別名を割り付けたID番号にマクロ定義するC言語プリプロセッサのディレクティブ(#define)を生成する【NGKI0453】.
オブジェクト生成以外の静的APIが,オブジェクトのID番号をパラメータに取る場合(カーネルの静的APIでは,SAC_TSKのtskidパラメータ等がこれに該当する)には,パラメータとして記述する識別名は,生成済みのオブジェクトの名称を表す識別名でなければならない.そうでない場合には,コンフィギュレータがエラーを報告する【NGKI0455】.
静的APIの整数定数式パラメータの記述に,オブジェクト識別名を使用することはできない【NGKI0456】.
(b) 整数定数式パラメータ
オブジェクト番号や機能コード,オブジェクト属性,サイズや数,優先度など,整数値を指定するパラメータ.プログラムが配置される番地に依存せずに値の決まる整数定数式を記述することができる.
整数定数式の解釈に必要な定義や宣言等は,システムコンフィギュレーションファイルからC言語プリプロセッサのインクルードディレクティブによってインクルードするファイルに含まれていなければならない【NGKI0457】.
(c) 一般定数式パラメータ
処理単位のエントリ番地,メモリ領域の先頭番地,拡張情報など,番地を指定する可能性のあるパラメータ.任意の定数式を記述することができる.
定数式の解釈に必要な定義や宣言等は,システムコンフィギュレーションファイルからC言語プリプロセッサのインクルードディレクティブによってインクルードするファイルに含まれていなければならない【NGKI0458】.
NULLを指定することが特別な意味を持つ一般定数式パラメータにおいて,NULLの意味を持たせたい場合には,静的APIのパラメータに「NULL」と記述しなければならない【NGKI0638】.NULLに展開されるマクロを記述しても,NULLの意味にはならないので注意すること.
(d) 文字列パラメータ
オブジェクトモジュール名やセクション名など,文字列を指定するパラメータ.任意の文字列を,C言語の文字列の記法で記述することができる.
【μITRON4.0仕様との関係】
μITRON4.0仕様においては,静的APIのパラメータを次の4種類に分類していたが,コンフィギュレータの仕組みを見直したことに伴い全面的に見直した.
(A) 自動割付け対応整数値パラメータ
(B) 自動割付け非対応整数値パラメータ
(C) プリプロセッサ定数式パラメータ
(D) 一般定数式パラメータ
この仕様の(a)が,おおよそμITRON4.0仕様の(A)に相当するが,(a)には整数値を記述できない点が異なる.(b)〜(c)と(B)〜(D)の間には単純な対応関係がないが,記述できる定数式の範囲には,(B)⊂(C)⊂(b)⊂(c)=(D)の関係がある.
μITRON4.0仕様では,静的APIのパラメータは基本的には(D)とし,コンフィギュレータが値を知る必要があるパラメータを(B),構成・初期化ファイルに生成するC言語プリプロセッサの条件ディレクティブ(#if)中に含めたい可能性のあるパラメータを(C)としていた.
それに対して,この仕様におけるコンフィギュレータの処理モデル(「2.12.5 コンフィギュレータの処理モデル」の節を参照)では,コンフィギュレータのパス2において定数式パラメータの値を知ることができるため,(B)〜(D)の区別をする必要がない.そのため,静的APIのパラメータは基本的には(b)とし,パス2で値を知ることのできない定数式パラメータのみを(c)としている.
2.12.3 保護ドメインの指定
保護機能対応カーネルでは,オブジェクトを登録する静的API等を,そのオブジェクトを属させる保護ドメインの囲みの中に記述する【NGKI0459】.無所属のオブジェクトを登録する静的APIは,保護ドメインの囲みの外に記述する【NGKI0460】.保護ドメインに属すべきオブジェクトを登録する静的API等を,保護ドメインの囲みの外に記述した場合には,コンフィギュレータがE_RSATRエラーを報告する【NGKI0461】.
ユーザドメインの囲みの文法は次の通り【NGKI0462】.
DOMAIN(保護ドメイン名) {
ユーザドメインに属するオブジェクトを登録する静的API等
}
保護ドメイン名には,ユーザドメインの名称を表す単一の識別名のみを記述することができる【NGKI0463】.
コンフィギュレータは,ユーザドメインの囲みを処理する際に,ユーザドメインに保護ドメインIDを割り付け,構成・初期化ヘッダファイルに,指定された保護ドメイン名を割り付けた保護ドメインIDにマクロ定義するC言語プリプロセッサのディレクティブ(#define)を生成する【NGKI0464】.また,ユーザドメインの囲みの中およびそれ以降に記述する静的APIの整数定数式パラメータの記述に保護ドメイン名を記述すると,割り付けた保護ドメインIDの値に評価される【NGKI0465】.
ユーザドメインの囲みの中を空にすることで,ユーザドメインへの保護ドメインIDの割付けのみを行うことができる【NGKI0466】.
カーネルドメインの囲みの文法は次の通り【NGKI0467】.
KERNEL_DOMAIN {
カーネルドメインに属するオブジェクトを登録する静的API等
}
同じ保護ドメイン名を指定したユーザドメインの囲みや,カーネルドメインの囲みを,複数回記述してもよい【NGKI0468】.保護機能対応でないカーネルで保護ドメインの囲みを記述した場合や,保護ドメインの囲みの中に保護ドメインの囲みを記述した場合には,コンフィギュレータがエラーを報告する【NGKI0469】.
【μITRON4.0/PX仕様との関係】
保護ドメインの囲みの文法を変更した.
【仕様決定の理由】
保護ドメインに属すべきオブジェクトを登録する静的API等を保護ドメインの囲みの外に記述した場合のエラーコードをE_RSATRとしたのは,オブジェクトを動的に登録するAPIにおいては,オブジェクトの属する保護ドメインを,オブジェクト属性によって指定するためである.
2.12.4 クラスの指定
マルチプロセッサ対応カーネルでは,オブジェクトを登録する静的API等を,そのオブジェクトを属させるクラスの囲みの中に記述する【NGKI0470】.クラスに属さないオブジェクトを登録する静的API等は,クラスの囲みの外に記述する【NGKI0397】.クラスに属すべきオブジェクトを登録する静的API等を,クラスの囲みの外に記述した場合や,クラスに属さないオブジェクトを登録する静的API等を,クラスの囲みの中に記述した場合には,コンフィギュレータがE_RSATRエラーを報告する【NGKI0471】.
クラスの囲みの文法は次の通り【NGKI0472】.
CLASS(クラスID) {
クラスに属するオブジェクトを登録する静的API等
}
クラスIDには,静的APIの整数定数式パラメータと同等の定数式を記述することができる【NGKI0473】.使用できないクラスIDを指定した場合には,コンフィギュレータがE_IDエラーを報告する【NGKI0474】.
同じクラスIDを指定したクラスの囲みを複数回記述してもよい【NGKI0475】.マルチプロセッサ対応でないカーネルでクラスの囲みを記述した場合や,クラスの囲みの中にクラスの囲みを記述した場合には,コンフィギュレータがエラーを報告する【NGKI0476】.
なお,保護機能とマルチプロセッサの両方に対応するカーネルでは,保護ドメインの囲みとクラスの囲みはどちらが外側になっていてもよい【NGKI0477】.
【仕様決定の理由】
クラスに属すべきオブジェクトを登録する静的API等をクラスの囲みの外に記述した場合のエラーコードをE_RSATRとしたのは,オブジェクトを動的に登録するAPIにおいては,オブジェクトの属するクラスを,オブジェクト属性によって指定するためである.
2.12.5 コンフィギュレータの処理モデル
コンフィギュレータは,次の3つないしは4つのパスにより,システムコンフィギュレーションファイルを解釈し,構成・初期化情報を含むファイルなどを生成する(図2-10).

最初のパス1では,システムコンフィギュレーションファイルを解釈し,そこに含まれる静的APIの整数定数式パラメータの値をCコンパイラを用いて求めるために,パラメータ計算用C言語ファイル(cfg1_out.c)を生成する.この時,システムコンフィギュレーションファイルに含まれるC言語プリプロセッサのインクルードディレクティブは,パラメータ計算用C言語ファイルの先頭に集めて生成する.また,条件ディレクティブは,順序も含めて,そのままの形でパラメータ計算用C言語ファイルに出力する.システムコンフィギュレーションファイルに文法エラーや未サポートの記述があった場合,オブジェクトの識別名に重複があった場合,ユーザドメインの数が制限を超えた場合には,この段階でエラーが検出される.
次に,Cコンパイラおよび関連ツールを用いて,パラメータ計算用C言語ファイルをコンパイルし,パラメータの計算結果を含むロードモジュール(パラメータ計算結果ファイル,cfg1_out)を生成する.静的APIの整数定数式パラメータに解釈できない式が記述された場合には,この段階でエラーが検出される.
コンフィギュレータのパス2では,パス1で生成されたロードモジュールから,C言語プリプロセッサの条件ディレクティブによりどの静的APIが有効となったかと,それらの静的APIの整数定数式パラメータの値を取り出し,カーネルおよびシステムサービスの構成・初期化ファイル(kernel_cfg.c)と構成・初期化ヘッダファイル(kernel_cfg.h)を生成する.構成・初期化ヘッダファイルには,登録できるオブジェクトの数(動的生成対応でないカーネルでは,静的APIによって登録されたオブジェクトの数に一致)やオブジェクトのID番号などの定義を出力する.静的APIの整数定数式パラメータに不正がある場合には,この段階でエラーが検出される.
パス2で生成されたファイルを,他のソースファイルやオブジェクトファイルとあわせてコンパイルし,アプリケーションのロードモジュールを生成する.静的APIの一般定数式パラメータに解釈できない式が記述された場合には,この段階でエラーが検出される.
コンフィギュレータのパス3では,パス2で生成されたロードモジュールから,静的APIのパラメータの値などを取り出し,妥当性のチェックを行う.静的APIの一般定数式パラメータに不正がある場合には,この段階でエラーが検出される.
保護機能対応カーネルで自動メモリ配置の場合には,メモリ配置を決定し,メモリ保護のための設定情報を生成するために,さらに以下の処理を行う(図2-11).

コンフィギュレータは,決定したメモリ配置に従ってロードモジュールを生成するために,リンカスクリプト(ldscript.ld)を生成する.また,メモリ保護のための設定情報を,メモリ構成・初期化ファイル(kernel_mem.c)に生成する.これらのファイルを生成するためには,パス3以降で初めて得られる情報が必要となるため,これらのファイルはパス3以降でしか生成できず,最終的なロードモジュールも,パス3以降で生成する.
そのため,パス2で生成されたロードモジュールは,仮のロードモジュールという位置付けになる.ここで,パス3以降で必要な情報を取り出し,最終的なロードモジュールのサイズを割り出せるように,パス3以降でメモリ構成・初期化ファイルに生成するのと同様のデータ構造を,パス2において仮のメモリ構成・初期化ファイル(kernel_mem2.c)に生成する.また,これをリンクするための仮のリンカスクリプト(cfg2_out.ld)を生成し,これらを用いて仮のロードモジュール(cfg2_out)を生成する.
パス3は,ターゲット依存で用いるパスで,メモリ配置やメモリ保護のための設定情報のサイズを最適化するための処理を行う.パス2で生成された仮のロードモジュールから必要な情報を取り出し,再度,仮のメモリ構成・初期化ファイル(kernel_mem3.c)と仮のリンカスクリプト(cfg3_out.ld)を生成する.また,これらを用いて仮のロードモジュール(cfg3_out)を生成する.この段階で,メモリオブジェクトに重なりがあるなどのエラーが検出される場合もある.
パス4では,パス3(パス3を用いない場合はパス2)で生成された仮のロードモジュールから必要な情報を取り出し,最終的なメモリ構成・初期化ファイル(kernel_mem.c)とリンカスクリプト(ldscript.ld)を生成する.またパス4では,保護機能対応でないカーネルにおいてパス3で行っていた静的APIパラメータの値などの妥当性のチェックも行う.そのため,静的APIの一般定数式パラメータに不正がある場合には,この段階でエラーが検出される.
パス4で生成されたファイルを,他のソースファイルとあわせてコンパイルし,アプリケーションの最終的なロードモジュールを生成する.
最後に,最終的なロードモジュールが,パス3(パス3を用いない場合はパス2)で生成された仮のロードモジュールと同じメモリ配置であることをチェックする.両者のメモリ配置が異なっていた場合には,ロードモジュールが正しく生成されていない可能性があるが,これは,コンフィギュレーション処理の不具合を示すものである.
なお,コンフィギュレータがロードモジュールから情報を取り出す際には,ロードモジュールからダンプファイル(Sレコードフォーマットなどファイル)とシンボルファイル(ロードモジュール中の各シンボルとアドレスの対応表を含むファイル)を生成し,それらのファイルを読み込む.
【μITRON4.0仕様との関係】
コンフィギュレータの処理モデルは全面的に変更した.
2.12.6 静的APIのパラメータに関するエラー検出
静的APIのパラメータに関するエラー検出は,同じものがサービスコールとして呼ばれた場合と同等とすることを原則とする【NGKI0478】.言い換えると,サービスコールによっても検出できないエラーは,静的APIにおいても検出しない.静的APIの機能説明中の「E_XXXXXエラーとなる」または「E_XXXXXエラーが返る」という記述は,コンフィギュレータがそのエラーを検出することを意味する.
ただし,エラーの種類によっては,サービスコールと同等のエラー検出を行うことが難しいため,そのようなものについては例外とする【NGKI0479】.例えば,メモリ不足をコンフィギュレータによって検出するのは容易ではない.
逆に,オブジェクト属性については,サービスコールより強力なエラーチェックを行える可能性がある.例えば,タスク属性にTA_STAと記述されている場合,サービスコールではエラーを検出できないが,コンフィギュレータでは検出できる可能性がある.ただし,このようなエラー検出を完全に行おうとするとコンフィギュレータが複雑になるため,このようなエラーを検出することは必須とせず,検出できた場合には警告メッセージを出力する【NGKI0480】.
なお,コンフィギュレータは,この仕様で警告メッセージを出力すると規定されている以外の状況でも,警告メッセージを出力する場合がある【NGKI0641】.
【μITRON4.0仕様との関係】
μITRON4.0仕様では,静的APIのパラメータに関するエラー検出について規定されていない.
2.12.7 オブジェクトのID番号の指定
アプリケーション設計者がオブジェクトのID番号を指定するために,コンフィギュレータのオプション機能として,以下の機能が用意されている.
コンフィギュレータのオプション指定により,オブジェクト識別名とID番号の対応表を含むファイルを渡すと,コンフィギュレータはそれに従ってオブジェクトにID番号を割り付ける【NGKI0481】.それに従ったID番号割付けができない場合(ID番号に抜けができる場合など)には,コンフィギュレータはエラーを報告する【NGKI0482】.
またコンフィギュレータは,オプション指定により,オブジェクト識別名とコンフィギュレータが割り付けたID番号の対応表を含むファイルを,コンフィギュレータに渡すファイルと同じフォーマットで生成する【NGKI0483】.
【μITRON4.0仕様との関係】
μITRON4.0仕様では,オブジェクト生成のための静的APIのID番号を指定するパラメータに整数値を記述できるため,このような機能は用意されていない.
2.13 TOPPERSネーミングコンベンション
この節では,TOPPERSソフトウェアのAPIの構成要素の名称に関するネーミングコンベンションについて述べる.このネーミングコンベンションは,モジュール間のインタフェースに関わる名称に適用することを想定しているが,モジュール内部の名称に適用してもよい.
(1) モジュール識別名
異なるモジュールのAPIの構成要素の名称が衝突することを避けるために,各モジュールに対して,それを識別するためのモジュール識別名を定める.モジュール識別名は,英文字と数字で構成し,2〜8文字程度の長さとする.
カーネルのモジュール識別名は"kernel",システムインタフェースレイヤのモジュール識別名は"sil"とする.
APIの構成要素の名称には,モジュール識別名を含めることを原則とするが,カーネルのAPIなど,頻繁に使用されて衝突のおそれが少ない場合には,モジュール識別名を含めない名称を使用する.
以下では,モジュール識別名の英文字を英小文字としたものをwww,英大文字としたものをWWWと表記する.
(2) データ型名
各サイズの整数型など,データの意味を定めない基本データ型の名称は,英小文字,数字,"_"で構成する.データ型であることを明示するために,末尾が"_t"である名称とする.
複合データ型やデータの意味を定めるデータ型の名称は,英大文字,数字,"_"で構成する.データ型であることを明示するために,先頭が"T_"または末尾が"_T"である名称とする場合もある.
データ型の種類毎に,次のネーミングコンベンションを定める.
(A) パケットのデータ型
T_CYYY |
acre_yyyに渡すパケットのデータ型 |
|
T_DYYY |
def_yyyに渡すパケットのデータ型 |
|
T_RYYY |
ref_yyyに渡すパケットのデータ型 |
|
T_WWW_CYYY |
www_acre_yyyに渡すパケットのデータ型 |
|
T_WWW_DYYY |
www_def_yyyに渡すパケットのデータ型 |
|
T_WWW_RYYY |
www_ref_yyyに渡すパケットのデータ型 |
(3) 関数名
関数の名称は,英小文字,数字,"_"で構成する.
関数の種類毎に,次のネーミングコンベンションを定める.
(A) サービスコール
サービスコールは,xxx_yyyまたはwww_xxx_yyyの名称とする.ここで,xxxは操作の方法,yyyは操作の対象を表す.xxx_yyyまたはwww_xxx_yyyから派生したサービスコールは,それぞれzxxx_yyyまたはwww_zxxx_yyyの名称とする.ここでzは,派生したことを表す文字である.派生したことを表す文字を2つ付加する場合には,zzxxx_yyyまたはwww_zzxxx_yyyの名称となる.
非タスクコンテキストから呼び出せるサービスコールは,サービスコールの名称に"i"を付加した,ixxx_yyy,izxxx_yyy,www_ixxx_yyy,www_izxxx_yyyといった名称で呼び出すこともできる【NGKI0562】.
【補足説明】
サービスコールの名称を構成する省略名(xxx,yyy,z)の元になった英語については,「5.10 省略名の元になった英語」の節を参照すること.
【μITRON4.0仕様,μITRON4.0/PX仕様との関係】
「2.5.2 タスクコンテキストと非タスクコンテキスト」の節で述べた通り,非タスクコンテキストからもタスクコンテキストと同じ名称のサービスコールを呼び出すこととしたが,過去との互換性のために,"i"を付加した名称で呼び出すこともできるものとした.
(B) コールバック
コールバックの名称は,サービスコールのネーミングコンベンションに従う.
(4) 変数名
変数(const修飾子のついたものを含む)の名称は,英小文字,数字,"_"で構成する.データ型が異なる変数には,異なる名称を付けることを原則とする.
変数の名称に関して,次のガイドラインを設ける.
〜id |
〜ID(オブジェクトのID番号,ID型) |
|
〜no |
〜番号(オブジェクト番号) |
|
〜atr |
〜属性(オブジェクト属性,ATR型) |
|
〜stat |
〜状態(オブジェクト状態,STAT型) |
|
〜mode |
〜モード(サービスコールの動作モード,MODE型) |
|
〜pri |
〜優先度(優先度,PRI型) |
|
〜sz |
〜サイズ(単位はバイト数,size_t型またはuint_t型) |
|
〜cnt |
〜の個数(単位は個数,uint_t型) |
|
〜ptn |
〜パターン |
|
〜tim |
〜時刻,〜時間 |
|
〜cd |
〜コード |
|
i〜 |
〜の初期値 |
|
max〜 |
〜の最大値 |
|
min〜 |
〜の最小値 |
|
left〜 |
〜の残り |
また,ポインタ変数(関数ポインタを除く)の名称に関して,次のガイドラインを設ける.
p_〜 |
ポインタ |
|
pp_〜 |
ポインタを入れる領域へのポインタ |
|
pk_〜 |
パケットへのポインタ |
|
ppk_〜 |
パケットへのポインタを入れる領域へのポインタ |
変数の種類毎に,次のネーミングコンベンションを定める.
(A) パケットへのポインタ
pk_cyyy |
acre_yyyに渡すパケットへのポインタ |
|
pk_dyyy |
def_yyyに渡すパケットへのポインタ |
|
pk_ryyy |
ref_yyyに渡すパケットへのポインタ |
|
pk_www_cyyy |
www_acre_yyyに渡すパケットへのポインタ |
|
pk_www_dyyy |
www_def_yyyに渡すパケットへのポインタ |
|
pk_www_ryyy |
www_ref_yyyに渡すパケットへのポインタ |
(5) 定数名
定数(C言語プリプロセッサのマクロ定義によるもの)の名称は,英大文字,数字,"_"で構成する.
定数の種類毎に,次のネーミングコンベンションを定める.
(A) メインエラーコード
メインエラーコードは,先頭が"E_"である名称とする.
(B) 機能コード
TFN_XXX_YYY |
xxx_yyyの機能コード |
|
TFN_WWW_XXX_YYY |
www_xxx_yyyの機能コード |
(C) その他の定数
その他の定数は,先頭がTUU_またはTUU_WWW_である名称とする.ここでUUは,定数の種類またはデータ型を表す.同じパラメータまたはリターンパラメータに用いられる定数の名称については,UUを同一にすることを原則とする.
また,定数の名称に関して,次のガイドラインを設ける.
TA_〜 |
オブジェクトの属性値 |
|
TSZ_〜 |
〜のサイズ |
|
TBIT_〜 |
〜のビット数 |
|
TMAX_〜 |
〜の最大値 |
|
TMIN_〜 |
〜の最小値 |
(6) マクロ名
マクロ(C言語プリプロセッサのマクロ定義によるもの)の名称は,それが表す構成要素のネーミングコンベンションに従う.すなわち,関数を表すマクロは関数のネーミングコンベンションに,定数を表すマクロは定数のネーミングコンベンションに従う.ただし,簡単な関数を表すマクロや,副作用があるなどの理由でマクロであることを明示したい場合には,英大文字,数字,"_"で構成する場合もある.
マクロの種類毎に,次のネーミングコンベンションを定める.
(A) 構成マクロ
構成マクロの名称は,英大文字,数字,"_"で構成し,次のガイドラインを設ける.
TSZ_〜 |
〜のサイズ |
|
TBIT_〜 |
〜のビット数 |
|
TMAX_〜 |
〜の最大値 |
|
TMIN_〜 |
〜の最小値 |
(7) 静的API名
静的APIの名称は,英大文字,数字,"_"で構成し,対応するサービスコールの名称中の英小文字を英大文字で置き換えたものとする.対応するサービスコールがない場合には,サービスコールのネーミングコンベンションに従って定めた名称中の英小文字を英大文字で置き換えたものとする.
(8) ファイル名
ファイルの名称は,英小文字,数字,"_","."で構成する.英大文字と英小文字を区別しないファイルシステムに対応するために,英大文字は使用しない.また,"-"も使用しない.
ファイルの種類毎に,次のネーミングコンベンションを定める.
(A) ヘッダファイル
モジュールを用いるために必要な定義を含むヘッダファイルは,そのモジュールのモジュール識別名の末尾に".h"を付加した名前(すなわち,www.h)とする.
(9) モジュール内部の名称の衝突回避
モジュール内部の名称が,他のモジュール内部の名称と衝突することを避けるために,次のガイドラインを設ける.
モジュール内部に閉じて使われる関数や変数などの名称で,オブジェクトファイルのシンボル表に登録されて外部から参照できる名称は,C言語レベルで,先頭が_www_または_WWW_である名称とする.例えば,カーネルの内部シンボルは,C言語レベルで,先頭が"_kernel_"または"_KERNEL_"である名称とする.
また,モジュールを用いるために必要な定義を含むヘッダファイル中に用いる名称で,それをインクルードする他のモジュールで使用する名称と衝突する可能性のある名称は,"TOPPERS_"で始まる名称とする.
2.14 TOPPERS共通定義
TOPPERSソフトウェアに共通に用いる定義を,TOPPERS共通定義と呼ぶ.
2.14.1 TOPPERS共通ヘッダファイル
TOPPERS共通定義(共通データ型,共通定数,共通マクロ)は,TOPPERS共通ヘッダファイル(t_stddef.h)およびそこからインクルードされるファイルに含まれている【NGKI0484】.TOPPERS共通定義を用いる場合には,TOPPERS共通ヘッダファイルをインクルードする【NGKI0485】.
TOPPERS共通ヘッダファイルは,カーネルヘッダファイル(kernel.h)やシステムインタフェースレイヤヘッダファイル(sil.h)からインクルードされるため,これらのファイルをインクルードする場合には,TOPPERS共通ヘッダファイルを直接インクルードする必要はない【NGKI0486】.
2.14.2 TOPPERS共通データ型
C90に規定されているデータ型以外で,TOPPERSソフトウェアで共通に用いるデータ型は次の通りである(一部,C90に規定されているものも含む)【NGKI0542】.
int8_t |
符号付き8ビット整数(オプション,C99準拠) |
|
uint8_t |
符号無し8ビット整数(オプション,C99準拠) |
|
int16_t |
符号付き16ビット整数(C99準拠) |
|
uint16_t |
符号無し16ビット整数(C99準拠) |
|
int32_t |
符号付き32ビット整数(C99準拠) |
|
uint32_t |
符号無し32ビット整数(C99準拠) |
|
int64_t |
符号付き64ビット整数(オプション,C99準拠) |
|
uint64_t |
符号無し64ビット整数(オプション,C99準拠) |
|
int128_t |
符号付き128ビット整数(オプション,C99準拠) |
|
uint128_t |
符号無し128ビット整数(オプション,C99準拠) |
int_least8_t |
8ビット以上の符号付き整数(C99準拠) |
|
uint_least8_t |
int_least8_t型と同じサイズの符号無し整数(C99準拠) |
float32_t |
IEEE754準拠の32ビット単精度浮動小数点数(オプション) |
|
double64_t |
IEEE754準拠の64ビット倍精度浮動小数点数(オプション) |
bool_t |
真偽値(trueまたはfalse) |
|
int_t |
16ビット以上の符号付き整数 |
|
uint_t |
int_t型と同じサイズの符号無し整数 |
|
long_t |
32ビット以上かつint_t型以上のサイズの符号付き整数 |
|
ulong_t |
long_t型と同じサイズの符号無し整数 |
size_t |
メモリ領域のサイズを表す符号無し整数(C90準拠) |
|
intptr_t |
ポインタを格納できるサイズの符号付き整数(C99準拠) |
|
uintptr_t |
intptr_t型と同じサイズの符号無し整数(C99準拠) |
FN |
機能コード(符号付き整数,int_tに定義) |
|
ER |
正常終了(E_OK)またはエラーコード(符号付き整数,int_tに定義) |
|
ID |
オブジェクトのID番号(符号付き整数,int_tに定義) |
|
ATR |
オブジェクト属性(符号無し整数,uint_tに定義) |
|
STAT |
オブジェクトの状態(符号無し整数,uint_tに定義) |
|
MODE |
サービスコールの動作モード(符号無し整数,uint_tに定義) |
|
PRI |
優先度(符号付き整数,int_tに定義) |
|
TMO |
タイムアウト指定(符号無し32ビット整数,単位はマイクロ秒,uint32_tに定義) |
|
EXINF |
拡張情報(ポインタまたは32ビット以上のサイズの整数を格納できるサイズの型) |
|
RELTIM |
相対時間(符号無し32ビット整数,単位はマイクロ秒,uint32_tに定義) |
|
SYSTIM |
システム時刻(符号無し整数,単位はマイクロ秒,uint64_tまたはuint32_tに定義) |
|
PRCTIM |
プロセッサ時間(符号無し整数,単位はマイクロ秒,uint32_tに定義) |
|
HRTCNT |
高分解能タイマのカウント値(符号無し整数,uint32_tまたはuint64_tに定義) |
FP |
プログラムの起動番地(型の定まらない関数ポインタ) |
ER_BOOL |
エラーコードまたは真偽値(符号付き整数,int_tに定義) |
|
ER_ID |
エラーコードまたはID番号(符号付き整数,int_tに定義,負のID番号は格納できない) |
|
ER_UINT |
エラーコードまたは符号無し整数(符号付き整数,int_tに定義,符号無し整数を格納する場合の有効ビット数はuint_tより1ビット短い) |
MB_T |
オブジェクト管理領域を確保するためのデータ型 |
ACPTN |
アクセス許可パターン(符号無し32ビット整数,uint32_tに定義) |
|
ACVCT |
アクセス許可ベクタ |
ここで,データ型が「AまたはB」とは,AかBのいずれかの値を取ることを示す.例えばER_BOOLは,エラーコードまたは真偽値のいずれかの値を取る.
int8_t,uint8_t,int64_t,uint64_t,int128_t,uint128_t,float32_t,double64_tが使用できるかどうかは,ターゲット定義である【NGKI0488】.これらが使用できるかどうかは,それぞれ,INT8_MAX,UINT8_MAX,INT64_MAX,UINT64_MAX,INT128_MAX,UINT128_MAX,FLOAT32_MAX,DOUBLE64_MAXがマクロ定義されているかどうかで判別することができる【NGKI0489】.IEEE754準拠の浮動小数点数がサポートされていない場合には,ターゲット定義で,float32_tとdouble64_tは使用できないものとする【NGKI0490】.
【μITRON4.0仕様との関係】
B,UB,H,UH,W,UW,D,UD,VP_INTに代えて,C99準拠のint8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,int64_t,uint64_t,intptr_tを用いることにした.また,uintptr_t,int128_t,uint128_tを用意することにした.
メモリ領域のサイズを表すデータ型として,SIZEに代えて,C90準拠のsize_tを用いることにした.
データタイプが定まらないものへのポインタを表すデータ型であるVPは,void*と等価であるため,用意しないことにした.また,ターゲットシステムにより振舞いが一定しないことから,VB,VH,VW,VDに代わるデータ型は用意しないことにした.
INT,UINTに代えて,C99の型名と相性が良いint_t,uint_tを用いることにした.また,32ビット以上かつint_t型(またはuint_t型)以上のサイズが保証される整数型として,long_t,ulong_tを用意し,8ビット以上のサイズで必ず存在する整数型として,C99準拠のint_least8_t,uint_least8_tを導入することにした.int_least16_t,uint_least16_t,int_least32_t,uint_least32_tを導入しなかったのは,16ビットおよび32ビットの整数型があることを仮定しており,それぞれint16_t,uint16_t,int32_t,uint32_tで代用できるためである.
TECSとの整合性を取るために,BOOLに代えて,bool_tを用いることにした.また,IEEE754準拠の単精度浮動小数点数を表す型としてfloat32_t,IEEE754準拠の倍精度浮動小数点数を表す型としてdouble64_tを導入した.
高分解能タイマのカウント値のデータ型としてHRTCNTを,オブジェクト管理領域を確保するためのデータ型としてMB_Tを用意することにした.
【TOPPERS新世代カーネル統合仕様との関係】
メモリ領域のサイズを表すデータ型として,SIZEに代えて,C90準拠のsize_tを用いることにした.
性能評価用システム時刻のためのデータ型であるSYSUTMを廃止し,高分解能タイマのカウント値のデータ型であるHRTCNTを追加した.
2.14.3 TOPPERS共通定数
C90に規定されている定数以外で,TOPPERSソフトウェアで共通に用いる定数は次の通りである(一部,C90に規定されているものも含む).
(1) 一般定数【NGKI0491】
NULL |
無効ポインタ |
true |
1 |
真 |
|
false |
0 |
偽 |
E_OK |
0 |
正常終了 |
【μITRON4.0仕様との関係】
BOOLをbool_tに代えたことから,TRUEおよびFALSEに代えて,trueおよびfalseを用いることにした.
(2) 整数型に格納できる最大値と最小値【NGKI0492】
INT8_MAX |
int8_tに格納できる最大値(オプション,C99準拠) |
|
INT8_MIN |
int8_tに格納できる最小値(オプション,C99準拠) |
|
UINT8_MAX |
uint8_tに格納できる最大値(オプション,C99準拠) |
|
INT16_MAX |
int16_tに格納できる最大値(C99準拠) |
|
INT16_MIN |
int16_tに格納できる最小値(C99準拠) |
|
UINT16_MAX |
uint16_tに格納できる最大値(C99準拠) |
|
INT32_MAX |
int32_tに格納できる最大値(C99準拠) |
|
INT32_MIN |
int32_tに格納できる最小値(C99準拠) |
|
UINT32_MAX |
uint32_tに格納できる最大値(C99準拠) |
|
INT64_MAX |
int64_tに格納できる最大値(オプション,C99準拠) |
|
INT64_MIN |
int64_tに格納できる最小値(オプション,C99準拠) |
|
UINT64_MAX |
uint64_tに格納できる最大値(オプション,C99準拠) |
|
INT128_MAX |
int128_tに格納できる最大値(オプション,C99準拠) |
|
INT128_MIN |
int128_tに格納できる最小値(オプション,C99準拠) |
|
UINT128_MAX |
uint128_tに格納できる最大値(オプション,C99準拠) |
INT_LEAST8_MAX |
int_least8_tに格納できる最大値(C99準拠) |
|
INT_LEAST8_MIN |
int_least8_tに格納できる最小値(C99準拠) |
|
UINT_LEAST8_MAX |
uint_least8_tに格納できる最大値(C99準拠) |
|
INT_MAX |
int_tに格納できる最大値(C90準拠) |
|
INT_MIN |
int_tに格納できる最小値(C90準拠) |
|
UINT_MAX |
uint_tに格納できる最大値(C90準拠) |
|
LONG_MAX |
long_tに格納できる最大値(C90準拠) |
|
LONG_MIN |
long_tに格納できる最小値(C90準拠) |
|
ULONG_MAX |
ulong_tに格納できる最大値(C90準拠) |
|
SIZE_MAX |
size_tに格納できる最大値(C99準拠) |
FLOAT32_MIN |
float32_tに格納できる最小の正規化された正の浮動小数点数(オプション) |
|
FLOAT32_MAX |
float32_tに格納できる表現可能な最大の有限浮動小数点数(オプション) |
|
DOUBLE64_MIN |
double64_tに格納できる最小の正規化された正の浮動小数点数(オプション) |
|
DOUBLE64_MAX |
double64_tに格納できる表現可能な最大の有限浮動小数点数(オプション) |
(3) 整数型のビット数【NGKI0493】
CHAR_BIT |
char型のビット数(C90準拠) |
(4) オブジェクト属性【NGKI0494】
TA_NULL |
0U |
オブジェクト属性を指定しない |
(5) タイムアウト指定【NGKI0555】
TMO_POL |
0U |
ポーリング |
|
TMO_FEVR |
UINT32_MAX |
永久待ち |
|
TMO_NBLK |
UINT32_MAX-1 |
ノンブロッキング |
(6) アクセス許可パターン[NGKI0089]
TACP_KERNEL |
0U |
カーネルドメインのみにアクセスを許可 |
|
TACP_SHARED |
~0U |
すべての保護ドメインにアクセスを許可 |
2.14.4 TOPPERS共通エラーコード
TOPPERSソフトウェアで共通に用いるメインエラーコードは次の通りである【NGKI0540】.
(A) 内部エラークラス(EC_SYS,-5〜-8)
E_SYS |
-5 |
システムエラー |
(B) 未サポートエラークラス(EC_NOSPT,-9〜-16)
E_NOSPT |
-9 |
未サポート機能 |
|
E_RSFN |
-10 |
予約機能コード |
|
E_RSATR |
-11 |
予約属性 |
(C) パラメータエラークラス(EC_PAR,-17〜-24)
E_PAR |
-17 |
パラメータエラー |
|
E_ID |
-18 |
不正ID番号 |
(D) 呼出しコンテキストエラークラス(EC_CTX,-25〜-32)
E_CTX |
-25 |
コンテキストエラー |
|
E_MACV |
-26 |
メモリアクセス違反 |
|
E_OACV |
-27 |
オブジェクトアクセス違反 |
|
E_ILUSE |
-28 |
サービスコール不正使用 |
(E) 資源不足エラークラス(EC_NOMEM,-33〜-40)
E_NOMEM |
-33 |
メモリ不足 |
|
E_NOID |
-34 |
ID番号不足 |
|
E_NORES |
-35 |
資源不足 |
(F) オブジェクト状態エラークラス(EC_OBJ,-41〜-48)
E_OBJ |
-41 |
オブジェクト状態エラー |
|
E_NOEXS |
-42 |
オブジェクト未登録 |
|
E_QOVR |
-43 |
キューイングオーバフロー |
(G) 待ち解除エラークラス(EC_RLWAI,-49〜-56)
E_RLWAI |
-49 |
待ち状態の強制解除 |
|
E_TMOUT |
-50 |
ポーリング失敗またはタイムアウト |
|
E_DLT |
-51 |
待ちオブジェクトの削除または再初期化 |
|
E_CLS |
-52 |
待ちオブジェクトの状態変化 |
|
E_RASTER |
-53 |
タスクの終了要求 |
(H) 警告クラス(EC_WARN,-57〜-64)
E_WBLK |
-57 |
ノンブロッキング受付け |
|
E_BOVR |
-58 |
バッファオーバフロー |
このエラークラスに属するエラーコードは,警告を表すエラーコードであり,[NGKI0019]の原則では例外としている.
(I) 通信エラークラス(EC_COMM,-65〜-72)
E_COMM |
-65 |
通信エラー |
このエラークラスに属するエラーコードは,通信エラー表すエラーコードであり,[NGKI0019]の原則では例外としている.
【μITRON4.0仕様との関係】
通信エラークラスは,μITRON4.0仕様に規定されていないエラークラスである.E_NORES,E_RASTER,E_COMMは,μITRON4.0仕様に規定されていないエラーコードである.
【TOPPERS新世代カーネル統合仕様との関係】
通信エラークラスは,TOPPERS新世代カーネル統合仕様に規定されていないエラークラスである.E_RASTER,E_COMMは,TOPPERS新世代カーネル統合仕様に規定されていないエラーコードである.
2.14.5 TOPPERS共通マクロ
【μITRON4.0仕様,μITRON4.0/PX仕様との関係】
μITRON4.0仕様では,エラーコード構成・分解マクロ(ERCD,MERCD,SERCD)のみが定義されており,μITRON4.0/PX仕様で,アクセス許可パターン構成マクロ(TACP)が追加定義されている.他は追加定義したものである.
(1) 整数定数を作るマクロ【NGKI0498】
INT8_C(val) |
int_least8_t型の定数を作るマクロ(C99準拠) |
|
UINT8_C(val) |
uint_least8_t型の定数を作るマクロ(C99準拠) |
|
INT16_C(val) |
int16_t型の定数を作るマクロ(C99準拠) |
|
UINT16_C(val) |
uint16_t型の定数を作るマクロ(C99準拠) |
|
INT32_C(val) |
int32_t型の定数を作るマクロ(C99準拠) |
|
UINT32_C(val) |
uint32_t型の定数を作るマクロ(C99準拠) |
|
INT64_C(val) |
int64_t型の定数を作るマクロ(オプション,C99準拠) |
|
UINT64_C(val) |
uint64_t型の定数を作るマクロ(オプション,C99準拠) |
|
INT128_C(val) |
int128_t型の定数を作るマクロ(オプション,C99準拠) |
|
UINT128_C(val) |
uint128_t型の定数を作るマクロ(オプション,C99準拠) |
UINT_C(val) |
uint_t型の定数を作るマクロ |
|
ULONG_C(val) |
ulong_t型の定数を作るマクロ |
【仕様決定の理由】
C99に用意されていないUINT_CとULONG_Cを導入したのは,アセンブリ言語からも参照する定数を記述するためである.C言語のみで用いる定数をこれらのマクロを使って記述する必要はない.
(2) 型に関する情報を取り出すためのマクロ【NGKI0499】
offsetof(structure, field) |
構造体structure中のフィールドfieldのバイト位置を返すマクロ(C90準拠) |
alignof(type) |
型typeのアラインメント単位を返すマクロ |
ALIGN_TYPE(addr, type) |
番地addrが型typeに対してアラインしているかどうかを返すマクロ |
(3) assertマクロ【NGKI0500】
assert(exp) |
expが成立しているかを検査するマクロ(C90準拠) |
(4) コンパイラの拡張機能のためのマクロ【NGKI0501】
inline |
インライン関数 |
|
Inline |
ファイルローカルなインライン関数 |
|
asm |
インラインアセンブラ |
|
Asm |
インラインアセンブラ(最適化抑止) |
|
throw() |
例外を発生しない関数 |
|
NoReturn |
リターンしない関数 |
(5) エラーコード構成・分解マクロ[NGKI0015]
ERCD(mercd, sercd) |
メインエラーコードmercdとサブエラーコードsercdから,エラーコードを構成するためのマクロ |
MERCD(ercd) |
エラーコードercdからメインエラーコードを抽出するためのマクロ |
|
SERCD(ercd) |
エラーコードercdからサブエラーコードを抽出するためのマクロ |
(6) アクセス許可パターン構成マクロ[NGKI0088]
TACP(domid) |
domidで指定されるユーザドメインのみにアクセスを許可するアクセス許可パターンを構成するためのマクロ |
ここで,TACPのパラメータ(domid)には,ユーザドメインのID番号のみを指定することができる【NGKI0504】.TDOM_SELF,TDOM_KERNEL,TDOM_NONEを指定した場合,どのようなアクセス許可パターンが構成されるかは保証されない【NGKI0505】.
2.15 カーネル共通定義
カーネルの複数の機能で共通に用いる定義を,カーネル共通定義と呼ぶ.
2.15.1 カーネルヘッダファイル
カーネルを用いるために必要な定義は,カーネルヘッダファイル(kernel.h)およびそこからインクルードされるファイルに含まれている【NGKI0507】.カーネルを用いる場合には,カーネルヘッダファイルをインクルードする【NGKI0508】.
ただし,カーネルを用いるために必要な定義の中で,コンフィギュレータによって生成されるものは,カーネル構成・初期化ヘッダファイル(kernel_cfg.h)に含まれる【NGKI0509】.具体的には,登録できるオブジェクトの数(TNUM_YYY)やオブジェクトのID番号などの定義が,これに該当する.これらの定義を用いる場合には,カーネル構成・初期化ヘッダファイルをインクルードする【NGKI0510】.
μITRON4.0仕様で規定されており,この仕様で廃止されたデータ型および定数を用いる場合には,ITRON仕様互換ヘッダファイル(itron.h)をインクルードする【NGKI0511】.
【μITRON4.0仕様との関係】
この仕様では,コンフィギュレータが生成するヘッダファイルに,オブジェクトのID番号の定義に加えて,登録できるオブジェクトの数(TNUM_YYY)の定義が含まれることとした.これに伴い,ヘッダファイルの名称を,μITRON4.0仕様の自動割付け結果ヘッダファイル(kernel_id.h)から,カーネル構成・初期化ヘッダファイル(kernel_cfg.h)に変更した.
2.15.2 カーネル共通定数
(1) オブジェクト属性【NGKI0512】
TA_TPRI |
0x01U |
タスクの待ち行列をタスクの優先度順に |
【μITRON4.0仕様との関係】
値が0のオブジェクト属性(TA_HLNG,TA_TFIFO,TA_WSGL)は,デフォルトの扱いにして廃止した.これは,「(tskatr & TA_HLNG) != 0U」のような間違いを防ぐためである.TA_ASMは,有効な使途がないために廃止した.メールボックス機能を廃止したため,TA_MPRIとTA_MFIFOは廃止した.
(2) 保護ドメインID【NGKI0513】
TDOM_SELF |
0 |
呼び出した処理単位が属する保護ドメイン |
|
TDOM_KERNEL |
-1 |
カーネルドメイン |
|
TDOM_NONE |
-2 |
無所属(保護ドメインに属さない) |
(3) その他のカーネル共通定数【NGKI0514】
TSOM_STP |
-1 |
システム周期の停止 |
TCLS_SELF |
0 |
自タスクの属するクラス |
TPRC_NONE |
0 |
割付けプロセッサの指定がない |
|
TPRC_INI |
0 |
初期割付けプロセッサ |
TSK_SELF |
0 |
自タスク指定 |
|
TSK_NONE |
0 |
該当するタスクがない |
TPRI_SELF |
0 |
自タスクのベース優先度の指定 |
|
TPRI_INI |
0 |
タスクの起動時優先度の指定 |
TIPM_ENAALL |
0 |
割込み優先度マスク全解除 |
(4) カーネルで用いるメインエラーコード
「2.14.4 TOPPERS共通エラーコード」の節で定義したメインエラーコードの中で,E_CLS,E_WBLK,E_BOVR,E_COMMの4つは,カーネルでは使用しない【NGKI0541】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,サービスコールから,E_RSFN,E_RSATR,E_MACV,E_OACV,E_NOMEM,E_NOID,E_NORES,E_NOEXSが返る状況は起こらない【ASPS0011】.E_RSATRは,コンフィギュレータによって検出される【ASPS0012】.ただし,動的生成機能拡張パッケージでは,サービスコールから,E_RSATR,E_NOMEM,E_NOID,E_NOEXSが返る状況が起こる【ASPS0013】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,サービスコールから,E_RSFN,E_RSATR,E_MACV,E_OACV,E_NOMEM,E_NOID,E_NORES,E_NOEXSが返る状況は起こらない【FMPS0007】.E_RSATRとE_NORESは,コンフィギュレータによって検出される【FMPS0008】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,サービスコールから,E_RSATR,E_NOID,E_NORESが返る状況は起こらない【HRPS0006】.E_RSATRは,コンフィギュレータによって検出される【HRPS0007】.ただし,動的生成機能拡張パッケージでは,サービスコールから,E_RSATR,E_NOIDが返る状況が起こる【HRPS0011】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,サービスコールから,E_RSATR,E_NOID,E_NORESが返る状況は起こらない【HRMPS0008】.E_RSATRとE_NORESは,コンフィギュレータによって検出される【HRMPS0009】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,サービスコールから,E_RSFN,E_RSATR,E_MACV,E_OACV,E_ILUSE,E_NOMEM,E_NOID,E_NORES,E_NOEXS,E_RLWAI,E_TMOUT,E_DLTが返る状況は起こらない【SSPS0008】.E_RSATRは,コンフィギュレータによって検出される【SSPS0009】.
2.15.3 カーネル共通マクロ
(1) スタック領域をアプリケーションで確保するためのデータ型とマクロ
スタック領域をアプリケーションで確保するために,次のデータ型とマクロを用意している【NGKI0516】.
STK_T |
スタック領域を確保するためのデータ型 |
COUNT_STK_T(sz) |
サイズszのスタック領域を確保するために必要なSTK_T型の配列の要素数 |
|
ROUND_STK_T(sz) |
要素数COUNT_STK_T(sz)のSTK_T型の配列のサイズ(szを,STK_T型のサイズの倍数になるように大きい方に丸めた値) |
これらを用いて,サイズszのスタック領域を確保する方法は次の通り【NGKI0517】.
STK_T <スタック領域の変数名>[COUNT_STK_T(sz)];
この方法で確保したスタック領域を,サービスコールまたは静的APIに渡す場合,スタック領域のサイズにはROUND_STK_T(sz)を,スタック領域の先頭番地には<スタック領域の変数名>を指定する【NGKI0518】.
ただし,保護機能対応カーネルにおいては,上の方法によりタスクのユーザスタック領域を確保することはできない【NGKI0519】.詳しくは,「4.1 タスク管理機能」の節のCRE_TSKの機能の項を参照すること.
(2) オブジェクト属性を作るマクロ
保護機能対応カーネルでは,オブジェクトが属する保護ドメインを指定するためのオブジェクト属性を作るマクロとして,次のマクロを用意している【NGKI0520】.
TA_DOM(domid) |
domidで指定される保護ドメインに属する |
マルチプロセッサ対応カーネルでは,オブジェクトが属するクラスを指定するためのオブジェクト属性を作るマクロとして,次のマクロを用意している【NGKI0521】.
TA_CLS(clsid) |
clsidで指定されるクラスに属する |
(3) サービスコールの呼出し方法を指定するマクロ
保護機能対応カーネルでは,サービスコールの呼出し方法を指定するためのマクロとして,次のマクロを用意している【NGKI0522】.
SVC_CALL(svc) |
svcで指定されるサービスコールを関数呼出しによって呼び出すための名称 |
(4) スケジューリング単位番号を構成するマクロ
保護機能とマルチプロセッサのいずれかまたは両方に対応するカーネルでは,スケジューリング単位番号を構成するためのマクロとして,次のマクロを用意している【NGKI0634】.
SCHEDNO(prcid, domid) |
マルチプロセッサ対応カーネルにおけるスケジューリング単位番号prcidと,保護機能対応カーネルにおけるスケジューリング単位番号domidから,保護機能とマルチプロセッサの両方に対応するカーネルにおけるスケジューリング単位番号を構成するためのマクロ |
【TOPPERS新世代カーネル統合仕様との関係】
スケジューリング単位番号を構成するマクロ(SCHEDNO)を追加した.
2.15.4 カーネル共通構成マクロ
(1) サポートする機能【NGKI0523】
TOPPERS_SUPPORT_PROTECT |
保護機能対応のカーネル |
|
TOPPERS_SUPPORT_MULTI_PRC |
マルチプロセッサ対応のカーネル |
|
TOPPERS_SUPPORT_DYNAMIC_CRE |
動的生成対応のカーネル |
(2) 優先度の範囲【NGKI0524】
TMIN_TPRI |
タスク優先度の最小値(=1) |
|
TMAX_TPRI |
タスク優先度の最大値 |
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,タスク優先度の最大値(TMAX_TPRI)は16に固定されている【ASPS0014】.ただし,タスク優先度拡張パッケージを用いると,TMAX_TPRIを256に拡張することができる【ASPS0015】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,タスク優先度の最大値(TMAX_TPRI)は16に固定されている【FMPS0009】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,タスク優先度の最大値(TMAX_TPRI)は16に固定されている【HRPS0008】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,タスク優先度の最大値(TMAX_TPRI)は16に固定されている【HRMPS0010】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,タスク優先度の最大値(TMAX_TPRI)は16に固定されている【SSPS0010】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
メールボックス機能を廃止したため,メッセージ優先度の最小値(TMIN_MPRI)と最大値(TMAX_MPRI)は廃止した.
(3) プロセッサの数
マルチプロセッサ対応カーネルでは,プロセッサの数を知るためのマクロとして,次の構成マクロを用意している[NGKI0643].
TNUM_PRCID |
プロセッサの数 |
(4) 特殊な役割を持ったプロセッサ
マルチプロセッサ対応カーネルでは,特殊な役割を持ったプロセッサを知るためのマクロとして,次の構成マクロを用意している【NGKI0526】.
TOPPERS_MASTER_PRCID |
マスタプロセッサのID番号 |
|
TOPPERS_TEPP_PRC |
タイムイベント処理プロセッサの集合 |
ここでTOPPERS_TEPP_PRCは,タイムイベント処理プロセッサの集合をビットマップとして表す符号無し整数型の数値で,プロセッサIDがNのプロセッサがタイムイベント処理プロセッサである場合に下位からN番目のビットが1,そうでない場合には下位からN番目のビットが0となっている.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,すべてのプロセッサがタイムイベント処理プロセッサであるため,TOPPERS_TEPP_PRCは用意していない【HRMPS0012】.
【TOPPERS新世代カーネル統合仕様との関係】
TOPPERS_SYSTIM_PRCID(システム時刻管理プロセッサのID番号),TOPPERS_SYSTIM_LOCAL(ローカルタイマ方式),TOPPERS_SYSTIM_GLOBAL(グローバルタイマ方式)を廃止した.TOPPERS_TEPP_PRCを追加した.
(5) メモリ配置の方法
保護機能対応カーネルでは,自動メモリ配置と手動メモリ配置のどちらが使われているかを知るためのマクロとして,次の構成マクロを用意している【NGKI0607】.
TOPPERS_ML_AUTO |
自動メモリ配置の場合にマクロ定義 |
|
TOPPERS_ML_MANUAL |
手動メモリ配置の場合にマクロ定義 |
(6) バージョン情報【NGKI0528】
TKERNEL_MAKER |
カーネルのメーカコード(=0x0118) |
|
TKERNEL_PRID |
カーネルの識別番号 |
|
TKERNEL_SPVER |
カーネル仕様のバージョン番号 |
|
TKERNEL_PRVER |
カーネルのバージョン番号 |
カーネルのメーカコード(TKERNEL_MAKER)は,TOPPERSプロジェクトから配布するカーネルでは,TOPPERSプロジェクトを表す値(0x0118)に設定されている.
カーネルの識別番号(TKERNEL_PRID)は,TOPPERSカーネルの種類を表す.
0x0001 |
TOPPERS/JSPカーネル |
|
0x0002 |
予約(IIMPカーネル) |
|
0x0003 |
予約(IDLカーネル) |
|
0x0004 |
TOPPERS/FI4カーネル |
|
0x0005 |
TOPPERS/FDMPカーネル |
|
0x0006 |
TOPPERS/HRPカーネル(TOPPERS/HRP2カーネル,TOPPERS/HRP3カーネルを含む) |
|
0x0007 |
TOPPERS/ASPカーネル(TOPPERS/ASP3カーネルを含む) |
|
0x0008 |
TOPPERS/FMPカーネル(TOPPERS/FMP3カーネルを含む) |
|
0x0009 |
TOPPERS/SSPカーネル(TOPPERS/SSP3カーネルを含む) |
|
0x000a |
TOPPERS/ASP Safetyカーネル |
|
0x000b |
TOPPRES/HRMPカーネル(TOPPERS/HRMP3カーネル) |
カーネル仕様のバージョン番号(TKERNEL_SPVER)は,上位8ビット(0xf6)がTOPPERS第3世代カーネル(ITRON系)仕様であることを,中位4ビットがメジャーバージョン番号,下位4ビットがマイナーバージョン番号を表す.
カーネルのバージョン番号(TKERNEL_PRVER)は,上位4ビットがメジャーバージョン番号,中位8ビットがマイナーバージョン番号,下位4ビットがパッチレベルを表す.
第3章 システムインタフェースレイヤAPI仕様
3.1 システムインタフェースレイヤの概要
システムインタフェースレイヤ(この章では,SILと略記する)は,デバイスを直接操作するプログラムが用いるための機能である.ITRONデバイスドライバ設計ガイドラインの一部分として検討されたものをベースに,TOPPERSプロジェクトにおいて修正を加えて用いている.
SILの機能は,プロセッサの特権モードで実行されているプログラムが使用することを想定している【NGKI0801】.非特権モードで実行されているプログラムからSILの機能を呼び出した場合の動作は,次の例外を除いては保証されない【NGKI0802】.
-
エンディアンの取得のためのマクロを参照すること
-
メモリ空間アクセス関数により,アクセスを許可されたメモリ領域にアクセスすること
-
I/O空間アクセス関数により,アクセスを許可されたI/O領域にアクセスすること
【μITRON4.0仕様との関係】
μITRON4.0仕様では,システムインタフェースレイヤAPI仕様は規定されていなかった.
3.2 SILヘッダファイル
SILを用いるために必要な定義は,SILヘッダファイル(sil.h)およびそこからインクルードされるファイルに含まれている【NGKI0803】.SILを用いる場合には,SILヘッダファイルをインクルードする【NGKI0804】.
3.3 全割込みロック状態の制御
デバイスを扱うプログラムの中では,すべての割込み(NMIを除く,以下同じ)をマスクしたい場合がある.カーネルで制御できるCPUロック状態は,カーネル管理外の割込み(NMI以外にカーネル管理外の割込みがあるかはターゲット定義)をマスクしないため,このような場合に用いることはできない.
そこで,SILでは,すべての割込みをマスクする全割込みロック状態を制御するための以下の機能を用意している.
(1) SIL_PRE_LOC
全割込みロック状態の制御に必要な変数を宣言するマクロ【NGKI0805】.通常は,型と変数名を並べたもので,最後に";"を含まない.
このマクロは,SIL_LOC_INT,SIL_UNL_INTを用いる関数またはブロックの先頭の変数宣言部に記述しなければならない【NGKI0806】.SIL_LOC_INT,SIL_UNL_INTを1つの関数内でネストして用いることは可能であるが,その場合には,ネストレベル毎にブロックを作り,そのブロックの先頭の変数宣言部にSIL_PRE_LOCを記述しなければならない【NGKI0807】.そのように記述しなかった場合の動作は保証されない【NGKI0808】.
(2) SIL_LOC_INT()
全割込みロックフラグをセットすることで,NMIを除くすべての割込みをマスクし,全割込みロック状態に遷移する【NGKI0809】.
(3) SIL_UNL_INT()
全割込みロックフラグを,対応するSIL_LOC_INTを実行する前の状態に戻す【NGKI0810】.SIL_LOC_INTを実行せずにSIL_UNL_INTを呼び出した場合の動作は保証されない【NGKI0811】.
なお,全割込みロック状態で呼び出せるサービスコールなどの制限事項については,「2.5.4 全割込みロック状態と全割込みロック解除状態」の節を参照すること.
【補足説明】
全割込みロック状態の制御機能の使用例は次の通り.
{
SIL_PRE_LOC;
SIL_LOC_INT();
// この間はNMIを除くすべての割込みがマスクされる.
// この間にサービスコールを呼び出してはならない(一部例外あり).
SIL_UNL_INT();
}
3.4 SILスピンロック
マルチプロセッサシステムにおいて,カーネルの機能を用いずに,他のプロセッサとの間でも排他制御を実現したい場合がある.そこでSILでは,割込みのマスクとプロセッサ間ロックの取得により排他制御を行うためのスピンロックの機能を用意している.これを,カーネルのスピンロック機能と区別するために,SILスピンロックと呼ぶ.
SILスピンロックで用いるプロセッサ間ロックは,システムに唯一存在する【NGKI0815】.この節でプロセッサ間ロックと言った場合には,SILスピンロックで用いるプロセッサ間ロックのことを指す.
プロセッサ間ロックを取得している間は,全割込みロック状態にすることですべての割込み(NMIを除く)がマスクされる【NGKI0812】.ロックが他のプロセッサに取得されている場合には,ロックが取得できるまでループによって待つ【NGKI0813】.ロックの取得を待つ間は,割込みはマスクされない(ただし,ロックの取得を試みる前からマスクしていた割込みは,マスクしたままとなる)【NGKI0814】.プロセッサ間ロックを取得し割込みをマスクすることを,SILスピンロックを取得するという.また,プロセッサ間ロックを返却し割込みをマスク解除することを,SILスピンロックを返却するという.
(1) SIL_PRE_LOC
全割込みロック状態の制御に必要な変数を宣言するマクロであるが,SILスピンロックの取得・解放にも兼用する【NGKI0816】.
このマクロは,SIL_LOC_SPN,SIL_UNL_SPNを用いる関数またはブロックの先頭の変数宣言部に記述しなければならない【NGKI0817】.SIL_LOC_SPN,SIL_UNL_SPNを,同じ関数内のSIL_LOC_INT,SIL_UNL_INTとネストして用いることは可能であるが,その場合には,ネストレベル毎にブロックを作り,そのブロックの先頭の変数宣言部にSIL_PRE_LOCを記述しなければならない【NGKI0818】.そのように記述しなかった場合の動作は保証されない【NGKI0819】.
(2) SIL_LOC_SPN()
プロセッサ間ロックが取得されていない状態である場合には,ロックの取得を試みる【NGKI0820】.ロックが他のプロセッサに取得されている状態である場合や,他のプロセッサがロックの取得に成功した場合には,ロックが返却されるまでループによって待ち,返却されたらロックの取得を試みる【NGKI0821】.ロックの取得に成功した場合には,全割込みロックフラグをセットし,全割込みロック状態に遷移する【NGKI0822】.
プロセッサ間ロックが,SIL_LOC_SPNを呼び出したプロセッサによって取得されている状態である場合には,全割込みロック状態への遷移のみを行う【NGKI0852】.
(3) SIL_UNL_SPN()
プロセッサ間ロックの取得状態と,全割込みロックフラグを,対応するSIL_LOC_SPNを実行する前の状態に戻す【NGKI0823】.SIL_LOC_SPNを実行せずにSIL_UNL_SPNを呼び出した場合の動作は保証されない【NGKI0825】.
なお,SILスピンロック取得中は全割込みロック状態となっているため,SILスピンロック取得中に呼び出せるサービスコールなどについては,「2.5.4 全割込みロック状態と全割込みロック解除状態」の節の制限事項が適用される.
なお,マルチプロセッサシステム以外では,SIL_LOC_SPNとSIL_UNL_SPNは用意されていない【NGKI0826】.
【使用上の注意】
全割込ロック状態やCPUロック状態でSIL_LOC_SPNを呼び出すことはできるが,割込みがマスクされている時間が長くなるために,そのような使い方は避けるべきである.
【補足説明】
SILスピンロック機能の使用例は次の通り.
{
SIL_PRE_LOC;
SIL_LOC_SPN();
// この間はSILスピンロックを取得している.
// この間はNMIを除くすべての割込みがマスクされる.
// この間にサービスコールを呼び出してはならない(一部例外あり).
SIL_UNL_SPN();
}
3.5 微少時間待ち
デバイスをアクセスする際に,微少な時間待ちを入れなければならない場合がある.そのような場合に,NOP命令をいくつか入れるなどの方法で対応すると,ポータビリティを損なうことになる.そこで,SILでは,微少な時間待ちを行うための以下の機能を用意している.
(1) void sil_dly_nse(ulong_t dlytim)
dlytimで指定された以上の時間(単位はナノ秒),ループなどによって待つ【NGKI0827】.指定した値によっては,指定した時間よりもかなり長く待つ場合があるので注意すること.
3.6 エンディアンの取得
プロセッサのバイトエンディアンを取得するためのマクロとして,SILでは,以下のマクロを定義している.
(1) SIL_ENDIAN_BIG,SIL_ENDIAN_LITTLE
ビッグエンディアンプロセッサではSIL_ENDIAN_BIGを,リトルエンディアンプロセッサではSIL_ENDIAL_LITTLEを,マクロ定義している【NGKI0828】.
3.7 メモリ空間アクセス関数
メモリ空間にマッピングされたデバイスレジスタや,デバイスとの共有メモリをアクセスするために,SILでは,以下の関数を用意している.
(1) uint8_t sil_reb_mem(const uint8_t *mem)
memで指定されるアドレスから8ビット単位で読み出した値を返す【NGKI0829】.
(2) void sil_wrb_mem(uint8_t *mem, uint8_t data)
memで指定されるアドレスにdataで指定される値を8ビット単位で書き込む【NGKI0830】.
(3) uint16_t sil_reh_mem(const uint16_t *mem)
memで指定されるアドレスから16ビット単位で読み出した値を返す【NGKI0831】.
(4) void sil_wrh_mem(uint16_t *mem, uint16_t data)
memで指定されるアドレスにdataで指定される値を16ビット単位で書き込む【NGKI0832】.
(5) uint16_t sil_reh_lem(const uint16_t *mem)
memで指定されるアドレスから16ビット単位でリトルエンディアンで読み出した値を返す【NGKI0833】.リトルエンディアンプロセッサでは,sil_reh_memと一致する.ビッグエンディアンプロセッサでは,sil_reh_memが返す値を,エンディアン変換した値を返す.
(6) void sil_wrh_lem(uint16_t *mem, uint16_t data)
memで指定されるアドレスにdataで指定される値を16ビット単位でリトルエンディアンで書き込む【NGKI0834】.リトルエンディアンプロセッサでは,sil_wrh_memと一致する.ビッグエンディアンプロセッサでは,dataをエンディアン変換した値を,sil_wrh_memで書き込むのと同じ結果となる.
(7) uint16_t sil_reh_bem(const uint16_t *mem)
memで指定されるアドレスから16ビット単位でビッグエンディアンで読み出した値を返す【NGKI0835】.ビッグエンディアンプロセッサでは,sil_reh_memと一致する.リトルエンディアンプロセッサでは,sil_reh_memが返す値を,エンディアン変換した値を返す.
(8) void sil_wrh_bem(uint16_t *mem, uint16_t data)
memで指定されるアドレスにdataで指定される値を16ビット単位でビッグエンディアンで書き込む【NGKI0836】.ビッグエンディアンプロセッサでは,sil_wrh_memと一致する.リトルエンディアンプロセッサでは,dataをエンディアン変換した値を,sil_wrh_memで書き込むのと同じ結果となる.
(9) uint32_t sil_rew_mem(const uint32_t *mem)
memで指定されるアドレスから32ビット単位で読み出した値を返す【NGKI0837】.
(10) void sil_wrw_mem(uint32_t *mem, uint32_t data)
memで指定されるアドレスにdataで指定される値を32ビット単位で書き込む【NGKI0838】.
(11) uint32_t sil_rew_lem(const uint32_t *mem)
memで指定されるアドレスから32ビット単位でリトルエンディアンで読み出した値を返す【NGKI0839】.リトルエンディアンプロセッサでは,sil_rew_memと一致する.ビッグエンディアンプロセッサでは,sil_rew_memが返す値を,エンディアン変換した値を返す.
(12) void sil_wrw_lem(uint32_t *mem, uint32_t data)
memで指定されるアドレスにdataで指定される値を32ビット単位でリトルエンディアンで書き込む【NGKI0840】.リトルエンディアンプロセッサでは,sil_wrw_memと一致する.ビッグエンディアンプロセッサでは,dataをエンディアン変換した値を,sil_wrw_memで書き込むのと同じ結果となる.
(13) uint32_t sil_rew_bem(const uint32_t *mem)
memで指定されるアドレスから32ビット単位でビッグエンディアンで読み出した値を返す【NGKI0841】.ビッグエンディアンプロセッサでは,sil_rew_memと一致する.リトルエンディアンプロセッサでは,sil_rew_memが返す値を,エンディアン変換した値を返す.
(14) void sil_wrw_bem(uint32_t *mem, uint32_t data)
memで指定されるアドレスにdataで指定される値を32ビット単位でビッグエンディアンで書き込む【NGKI0842】.ビッグエンディアンプロセッサでは,sil_wrw_memと一致する.リトルエンディアンプロセッサでは,dataをエンディアン変換した値を,sil_wrw_memで書き込むのと同じ結果となる.
また,デバイスレジスタやメモリへの書込みが完了するまで待つために,以下のメモリ空間同期書込み関数を用意している.
(15) void sil_swrb_mem(uint8_t *mem, uint8_t data)
memで指定されるアドレスにdataで指定される値を8ビット単位で書き込み,書込みが完了するまで待つ【NGKI0845】.
(16) void sil_swrh_mem(uint16_t *mem, uint16_t data)
memで指定されるアドレスにdataで指定される値を16ビット単位で書き込み,書込みが完了するまで待つ【NGKI0846】.
(17) void sil_swrh_lem(uint16_t *mem, uint16_t data)
memで指定されるアドレスにdataで指定される値を16ビット単位でリトルエンディアンで書き込み,書込みが完了するまで待つ【NGKI0847】.
(18) void sil_swrh_bem(uint16_t *mem, uint16_t data)
memで指定されるアドレスにdataで指定される値を16ビット単位でビッグエンディアンで書き込み,書込みが完了するまで待つ【NGKI0848】.
(19) void sil_swrw_mem(uint32_t *mem, uint32_t data)
memで指定されるアドレスにdataで指定される値を32ビット単位で書き込み,書込みが完了するまで待つ【NGKI0849】.
(20) void sil_swrw_lem(uint32_t *mem, uint32_t data)
memで指定されるアドレスにdataで指定される値を32ビット単位でリトルエンディアンで書き込み,書込みが完了するまで待つ【NGKI0850】.
(21) void sil_swrw_bem(uint32_t *mem, uint32_t data)
memで指定されるアドレスにdataで指定される値を32ビット単位でビッグエンディアンで書き込み,書込みが完了するまで待つ【NGKI0851】.
【TOPPERS新世代カーネル統合仕様との関係】
メモリ空間同期書込み関数群を追加した.
3.8 I/O空間アクセス関数
メモリ空間とは別にI/O空間を持つプロセッサでは,I/O空間にあるデバイスレジスタをアクセスするために,メモリ空間アクセス関数と同等の以下の関数を用意している【NGKI0843】.
(1) uint8_t sil_reb_iop(const uint8_t *iop)
(2) void sil_wrb_iop(uint8_t *iop, uint8_t data)
(3) uint16_t sil_reh_iop(const uint16_t *iop)
(4) void sil_wrh_iop(uint16_t *iop, uint16_t data)
(5) uint16_t sil_reh_lep(const uint16_t *iop)
(6) void sil_wrh_lep(uint16_t *iop, uint16_t data)
(7) uint16_t sil_reh_bep(const uint16_t *iop)
(8) void sil_wrh_bep(uint16_t *iop, uint16_t data)
(9) uint32_t sil_rew_iop(const uint32_t *iop)
(10) void sil_wrw_iop(uint32_t *iop, uint32_t data)
(11) uint32_t sil_rew_lep(const uint32_t *iop)
(12) void sil_wrw_lep(uint32_t *iop, uint32_t data)
(13) uint32_t sil_rew_bep(const uint32_t *iop)
(14) void sil_wrw_bep(uint32_t *iop, uint32_t data)
(15) void sil_swrb_iop(uint8_t *iop, uint8_t data)
(16) void sil_swrh_iop(uint16_t *iop, uint16_t data)
(17) void sil_swrh_lep(uint16_t *iop, uint16_t data)
(18) void sil_swrh_bep(uint16_t *iop, uint16_t data)
(19) void sil_swrw_iop(uint32_t *iop, uint32_t data)
(20) void sil_swrw_lep(uint32_t *iop, uint32_t data)
(21) void sil_swrw_bep(uint32_t *iop, uint32_t data)
【TOPPERS新世代カーネル統合仕様との関係】
I/O空間同期書込み関数群を追加した.
3.9 プロセッサIDの参照
マルチプロセッサシステムにおいては,プログラムがどのプロセッサで実行されているかを参照するために,以下の関数を用意している.
(1) void sil_get_pid(ID *p_prcid)
この関数を呼び出したプログラムを実行しているプロセッサのID番号を参照し,p_prcidで指定したメモリ領域に返す【NGKI0844】.
【使用上の注意】
タスクは,sil_get_pidを用いて,自タスクを実行しているプロセッサを正しく参照できるとは限らない.これは,sil_get_pidを呼び出し,自タスクを実行しているプロセッサのID番号を参照した直後に割込みが発生した場合,sil_get_pidから戻ってきた時には自タスクを実行しているプロセッサが変化している可能性があるためである.
第4章 カーネルAPI仕様
この章では,カーネルのAPI仕様について規定する.
【μITRON4.0仕様との関係】
TOPPERS共通データ型に従い,パラメータのデータ型を次の通り変更した.
INT → int_t |
|
UINT → uint_t |
|
VP → void * |
|
VP_INT → intptr_t |
|
SIZE → size_t |
ただし,拡張情報の型(μITRON4.0仕様ではVP_INT)については,EXINFに変更した.
タスク例外処理機能を廃止し,それに代えて,タスク終了要求機能を追加した.これに関連して,待ち状態に入るすべてのサービスコールから,E_RASTERエラーが返る場合ある.
非タスクコンテキスト専用のサービスコールの概念を廃止し,非タスクコンテキストからも,タスクコンテキストと同じ名称のサービスコールを呼び出すこととした.
以上の変更については,個別のAPI仕様では記述しない.
【μITRON4.0/PX仕様との関係】
ID番号で識別するオブジェクトのアクセス許可ベクタをデフォルト以外に設定する場合には,オブジェクトを生成した後に設定することとし,アクセス許可ベクタを設定する静的API(SAC_YYY)を新設した.逆に,アクセス許可ベクタを指定してオブジェクトを生成する機能(CRA_YYY,cra_yyy,acra_yyy)は廃止した.これらの変更については,個別のAPI仕様では記述しない.
【TOPPERS新世代カーネル統合仕様との関係】
TOPPERS共通データ型の変更に従い,パラメータのデータ型を次の通り変更した.
SIZE → size_t |
また,拡張情報の型を,EXINFに変更した.
タスク例外処理機能を廃止し,それに代えて,タスク終了要求機能を追加した.これに関連して,待ち状態に入るすべてのサービスコールから,E_RASTERエラーが返る場合ある.
非タスクコンテキスト専用のサービスコールの概念を廃止し,非タスクコンテキストからも,タスクコンテキストと同じ名称のサービスコールを呼び出すこととした.
以上の変更については,個別のAPI仕様では記述しない.
4.1 タスク管理機能
タスクは,プログラムの並行実行の単位で,カーネルが実行を制御する処理単位である.タスクは,タスクIDと呼ぶID番号によって識別する【NGKI1001】.
タスク管理機能に関連して,各タスクが持つ情報は次の通り【NGKI1002】.
-
タスク属性
-
タスク状態
-
ベース優先度
-
現在優先度
-
サブ優先度(サブ優先度機能をサポートするカーネルの場合)
-
起動要求キューイング数
-
割付けプロセッサ(マルチプロセッサ対応カーネルの場合)
-
次回起動時の割付けプロセッサ(マルチプロセッサ対応カーネルの場合)
-
拡張情報
-
メインルーチンの先頭番地
-
起動時優先度
-
実行時優先度(TOPPERS/SSP3カーネルの場合)
-
スタック領域
-
システムスタック領域(保護機能対応カーネルの場合)
-
アクセス許可ベクタ(保護機能対応カーネルの場合)
-
属する保護ドメイン(保護機能対応カーネルの場合)
-
属するクラス(マルチプロセッサ対応カーネルの場合)
タスクのベース優先度は,タスクの現在優先度を決定するために使われる優先度であり,タスクの起動時に起動時優先度に初期化される【NGKI1003】.
タスクの現在優先度は,タスクの優先順位を決定するために使われる優先度である.単にタスクの優先度と言った場合には,現在優先度のことを指す.タスクがミューテックスをロックしていない間は,タスクの現在優先度はベース優先度に一致する【NGKI1004】.ミューテックスをロックしている間のタスクの現在優先度については,「4.4.5 ミューテックス」の節を参照すること.
タスクのサブ優先度は,優先度が同一のタスクの間の優先順位を決定するために使われる値であり,タスクの生成時に最低値(=UINT_MAX)に初期化される【NGKI3681】.
タスクの起動要求キューイング数は,処理されていないタスクの起動要求の数であり,タスクの生成時に0に初期化される【NGKI1005】.
割付けプロセッサは,マルチプロセッサ対応カーネルにおいて,タスクを実行するプロセッサで,タスクの生成時に,タスクが属するクラスの初期割付けプロセッサに初期化される【NGKI1006】.
次回起動時の割付けプロセッサは,マルチプロセッサ対応カーネルにおいて,タスクの起動要求がmact_tskによりキューイングされている状況で,タスクが次に起動される時に割り付けられるプロセッサである.タスクの生成時に未設定の状態に初期化され,タスクの起動要求キューイング数が0の間は,未設定の状態になっている【NGKI1007】.
保護機能対応カーネルにおいては,スタック領域の扱いは,ユーザタスクとシステムタスクで異なる.ユーザタスクのスタック領域は,ユーザスタック領域と呼び,ユーザタスクが非特権モードで実行する間に用いる【NGKI1010】.その扱いについては,「2.11.6 ユーザタスクのユーザスタック領域」の節を参照すること.システムタスクのスタック領域は,カーネルの管理領域として扱われる【NGKI1011】.
システムスタック領域は,保護機能対応カーネルにおいてユーザタスクが持つもので,ユーザタスクがサービスコール(拡張サービスコールを含む)を呼び出し,特権モードで実行する間に用いる【NGKI1012】.システムスタック領域は,カーネルの管理領域として扱われる【NGKI1013】.
タスク属性には,次の属性を指定することができる【NGKI3526】.
TA_ACT |
0x01U |
タスクの生成時にタスクを起動する |
|
TA_NOACTQUE |
0x02U |
タスクに対する起動要求をキューイングしない |
|
TA_RSTR |
0x04U |
生成するタスクを制約タスクとする |
TA_ACTを指定しない場合,タスクの生成直後には,タスクは休止状態となる【NGKI1015】.また,ターゲットによっては,ターゲット定義のタスク属性を指定できる場合がある【NGKI1016】.ターゲット定義のタスク属性として,次の属性を予約している【NGKI1017】.
TA_FPU |
FPUレジスタをコンテキストに含める |
C言語によるタスクの記述形式は次の通り【NGKI1018】.
void task(EXINF exinf)
{
タスク本体
ext_tsk();
}
exinfには,タスクの拡張情報が渡される【NGKI1019】.ext_tskを呼び出さず,タスクのメインルーチンからリターンした場合,ext_tskを呼び出した場合と同じ動作をする【NGKI1020】.
タスク管理機能に関連するカーネル構成マクロは次の通り.
TMAX_ACTCNT |
タスクの起動要求キューイング数の最大値【NGKI1021】 |
TNUM_TSKID |
登録できるタスクの数(動的生成対応でないカーネルでは,静的APIによって登録されたタスクの数に一致)【NGKI1022】 |
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,TMAX_ACTCNTは1に固定されている【ASPS0101】.また,制約タスクはサポートしない[ASPS0009].ただし,制約タスク拡張パッケージを用いると,制約タスクの機能を追加することができる[ASPS0010].
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,TMAX_ACTCNTは1に固定されている【FMPS0101】.また,制約タスクはサポートしない[FMPS0006].
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,TMAX_ACTCNTは1に固定されている【HRPS0101】.また,制約タスクはサポートしない[HRPS0005].
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,TMAX_ACTCNTは1に固定されている【HRMPS0101】.また,制約タスクはサポートしない[HRMPS0007].
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,TMAX_ACTCNTは1に固定されている【SSPS0101】.
SSP3カーネルは,制約タスクのみをサポートすることから,すべてのタスクでスタック領域を共有しており,タスク毎にスタック領域の情報を持たない【SSPS0102】.
SSP3カーネルにおける追加機能として,タスクに対して,実行時優先度の情報を持つ【SSPS0103】.SSP3カーネルにおいては,タスクが起動された後,最初に実行状態になる時に,タスクのベース優先度が,タスクの実行時優先度に設定される【SSPS0104】.実行時優先度の機能は,起動時優先度よりも高い優先度でタスクを実行することで,同時期に共有スタック領域を使用している状態になるタスクの組み合わせを限定し,スタック領域を節約するための機能である.
タスクの実行時優先度は,実行時優先度を定義する静的API(DEF_EPR)によって設定する【SSPS0105】.実行時優先度を定義しない場合,タスクの実行時優先度は,起動時優先度と同じ値に設定される【SSPS0106】.
いずれのタスクにも実行時優先度が設定されていない場合には,すべてのタスクが同時期に共有スタック領域を使用している状態になる可能性がある.そのため,共有スタック領域に必要なサイズは,すべてのタスクのスタック領域のサイズの和に,非タスクコンテキスト用のスタック領域のサイズを加えたものとなる.
タスクAに対して実行時優先度が設定されており,タスクAの起動時優先度よりも高く,タスクAの実行時優先度と同じかそれよりも低い起動時優先度を持つタスクBがある場合,タスクAとタスクBは同時期に共有スタック領域を使用している状態にならない.そのため,タスクAとタスクBの内,サイズが小さい方のスタック領域のサイズは,共有スタック領域のサイズに加える必要がなくなり,スタック領域を節約できることになる.
【μITRON4.0仕様との関係】
起動コードを指定してタスクを起動するサービスコール(sta_tsk),タスクを終了と同時に削除するサービスコール(exd_tsk),タスクの状態を参照するサービスコールの簡易版(ref_tst)を廃止し,自タスクの拡張情報の参照するサービスコール(get_inf),タスク状態を参照するサービスコール(get_tst),タスクのサブ優先度を変更するサービスコール(chg_spr)を追加した.
タスク属性に,TA_NOACTQUEを追加した.
TNUM_TSKIDは,μITRON4.0仕様に規定されていないカーネル構成マクロである.
【TOPPERS新世代カーネル統合仕様との関係】
タスク状態を参照するサービスコール(get_tst)とタスクのサブ優先度を変更するサービスコール(chg_spr)を追加した.
タスク属性に,TA_NOACTQUEを追加した.TA_ACTの値を変更した.
CRE_TSK |
タスクの生成〔S〕【NGKI1023】 |
acre_tsk |
タスクの生成〔TD〕【NGKI1024】 |
【静的API】
*保護機能対応でないカーネルの場合
CRE_TSK(ID tskid, { ATR tskatr, EXINF exinf, TASK task,
PRI itskpri, size_t stksz, STK_T *stk })
※ stkの記述は省略することができる【NGKI3900】.
*保護機能対応カーネルの場合
CRE_TSK(ID tskid, { ATR tskatr, EXINF exinf, TASK task, PRI itskpri,
size_t stksz, STK_T *stk, size_t sstksz, STK_T *sstk })
※ stk,sstksz,sstkの記述は省略することができる【NGKI1025】.
【C言語API】
ER_ID tskid = acre_tsk(const T_CTSK *pk_ctsk)
【パラメータ】
ID |
tskid |
生成するタスクの識別名(CRE_TSKの場合) |
|
T_CTSK * |
pk_ctsk |
タスクの生成情報を入れたパケットへのポインタ(acre_tskの場合) |
*タスクの生成情報(パケットの内容)
ATR |
tskatr |
タスク属性 |
|
EXINF |
exinf |
タスクの拡張情報 |
|
TASK |
task |
タスクのメインルーチンの先頭番地 |
|
PRI |
itskpri |
タスクの起動時優先度 |
|
size_t |
stksz |
タスクのスタック領域のサイズ(バイト数) |
|
STK_T * |
stk |
タスクのスタック領域の先頭番地 |
|
size_t |
sstksz |
タスクのシステムスタック領域のサイズ(バイト数,保護機能対応カーネルの場合) |
|
STK_T * |
sstk |
タスクのシステムスタック領域の先頭番地(保護機能対応カーネルの場合) |
【リターンパラメータ】
ER_ID |
tskid |
生成されたタスクのID番号(正の値)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_RSATR |
予約属性 |
|
E_PAR |
パラメータエラー |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_NOID |
ID番号不足 |
|
E_NOMEM |
メモリ不足 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
各パラメータで指定したタスクの生成情報に従って,タスクを生成する【NGKI5188】.タスクの生成時には,以下の処理を行う.
まず,stkとstkszからタスクが用いるスタック領域が設定される【NGKI1041】.ただし,保護機能対応カーネルで,生成するタスクがシステムタスクの場合には,スタック領域の設定にsstkszも用いられる(具体的な仕様は後述する).設定されるスタック領域のサイズがターゲット定義の最小値よりも小さくなる時は,E_PARエラーとなる【NGKI1042】.
また,保護機能対応カーネルで,生成するタスクがユーザタスクの場合には,sstkとsstkszからシステムスタック領域が設定される【NGKI1043】.この場合,sstkszにターゲット定義の最小値よりも小さい値を指定した時は,E_PARエラーとなる【NGKI1044】.
次に,生成されたタスクに対してタスク生成時に行うべき初期化処理が行われ,生成されたタスクは休止状態になる【NGKI1045】.さらに,tskatrにTA_ACTを指定した場合には,タスク起動時に行うべき初期化処理が行われ,生成されたタスクは実行できる状態になる【NGKI1046】.
静的APIにおいては,tskidはオブジェクト識別名,tskatr,itskpri,stksz,sstkszは整数定数式パラメータ,exinf,task,stk,sstkは一般定数式パラメータである【NGKI1047】.ただし,保護機能対応カーネルで手動メモリ配置の場合には,stkは整数定数式パラメータである【NGKI3906】.コンフィギュレータは,静的APIのメモリ不足(E_NOMEM)エラーを検出することができない【NGKI1048】.
保護機能とマルチプロセッサの両方に対応するカーネルでは,生成するタスクがユーザタスクの場合に,[NGKI0628]の制約が課される.具体的には,生成するタスクが属するユーザドメインが,アイドルドメインにまとめられておらず,属するクラスの初期割付けプロセッサでタイムウィンドウを割り当てられていない場合,E_PARエラーとなる【NGKI5108】.
stkにNULLを指定するか,静的APIにおいてstkの記述を省略した場合,stkszで指定したサイズのスタック領域が,コンフィギュレータまたはカーネルにより確保される【NGKI1049】.stkszにターゲット定義の制約に合致しないサイズを指定した時には,ターゲット定義の制約に合致するように大きい方に丸めたサイズで確保される【NGKI1050】.
保護機能対応カーネルにおいて,生成するタスクがユーザタスクの場合,コンフィギュレータにより確保されるスタック領域(ユーザスタック領域)は,タスクが属する保護ドメイン向け(マルチプロセッサ対応カーネルの場合には,さらに,タスクが属するクラス向け)の標準スタックリージョン内に配置され,「2.11.6 ユーザタスクのユーザスタック領域」の節の規定に従って,メモリオブジェクトとしてカーネルに登録される【NGKI1051】.
ただし,保護機能対応カーネルで手動メモリ配置の場合で,生成するタスクがユーザタスクの場合には,stkがNULLであってはならず,静的APIにおいてstkの記述を省略することができない.stkがNULLであった場合や,stkの記述を省略した場合には,E_PARエラーとなる【NGKI3907】.
保護機能対応カーネルにおいて,生成するタスクがシステムタスクの場合,コンフィギュレータにより確保されるスタック領域は,カーネルドメイン向け(マルチプロセッサ対応カーネルの場合には,さらに,タスクが属するクラス向け)の標準スタックリージョン内に配置される【NGKI5203】.
静的APIにより制約タスクを生成する場合(tskatrにTA_RSTRを指定して生成する場合),スタック領域は,制約タスクの起動時優先度毎に確保され,同じ起動時優先度を持つ制約タスクで共有される【NGKI1052】.確保されるスタック領域のサイズは,それを共有する制約タスクのスタック領域のサイズ(stksz)の最大値となる【NGKI1053】.マルチプロセッサ対応カーネルでは,以上のスタック領域の確保処理を,制約タスクの初期割付けプロセッサ毎に行う【NGKI1054】.
stkにNULL以外を指定した場合,stkとstkszで指定したスタック領域は,アプリケーションで確保しておく必要がある【NGKI1055】.スタック領域をアプリケーションで確保する方法については,「2.15.3 カーネル共通マクロ」の節を参照すること.その方法に従わず,stkやstkszにターゲット定義の制約に合致しない先頭番地やサイズを指定した時には,E_PARエラーとなる【NGKI1056】.
保護機能対応カーネルにおいて,生成するタスクがシステムタスクの場合に,stkとstkszで指定したスタック領域がカーネル専用のメモリオブジェクトに含まれない場合,E_OBJエラーとなる【NGKI1057】.
保護機能対応カーネルにおいて,生成するタスクがユーザタスクの場合,stkとstkszで指定したスタック領域(ユーザスタック領域)は,「2.11.6 ユーザタスクのユーザスタック領域」の節の規定に従って,メモリオブジェクトとしてカーネルに登録される【NGKI1058】.そのため,上の方法を用いてスタック領域を確保しても,ターゲット定義の制約に合致する先頭番地とサイズとなるとは限らず,スタック領域をアプリケーションで確保する方法は,ターゲット定義である【NGKI1059】.また,stkとstkszで指定したスタック領域が,登録済みのメモリオブジェクトとメモリ領域が重なる場合には,E_OBJエラーとなる【NGKI1060】.
保護機能対応カーネルにおけるsstkとsstkszの扱いは,生成するタスクがユーザタスクの場合とシステムタスクの場合で異なる.
生成するタスクがユーザタスクの場合の扱いは次の通り.
sstkにNULLを指定するか,静的APIにおいてsstkの記述を省略した場合,sstkszで指定したサイズのシステムスタック領域が,コンフィギュレータまたはカーネルにより確保される【NGKI1061】.sstkszにターゲット定義の制約に合致しないサイズを指定した時には,ターゲット定義の制約に合致するように大きい方に丸めたサイズで確保される【NGKI1062】.sstkszの記述も省略した場合には,ターゲット定義のデフォルトのサイズで確保される【NGKI1063】.
ここで,コンフィギュレータにより確保されるシステムスタック領域は,カーネルドメイン向け(マルチプロセッサ対応カーネルの場合には,さらに,タスクが属するクラス向け)の標準スタックリージョン内に配置される【NGKI5204】.
sstkにNULL以外を指定した場合,sstkとsstkszで指定したシステムスタック領域は,アプリケーションで確保しておく必要がある【NGKI1064】.システムスタック領域をアプリケーションで確保する方法については,「2.15.3 カーネル共通マクロ」の節を参照すること.その方法に従わず,sstkやsstkszにターゲット定義の制約に合致しない先頭番地やサイズを指定した時には,E_PARエラーとなる【NGKI1065】.また,sstkとsstkszで指定したシステムスタック領域がカーネル専用のメモリオブジェクトに含まれない場合,E_OBJエラーとなる【NGKI1066】.
生成するタスクがシステムタスクの場合の扱いは次の通り.
sstkに指定することができるのは,NULLのみである.sstkにNULL以外を指定した場合には,E_PARエラーとなる【NGKI1068】.
sstkszに0以外の値を指定した場合で,stkがNULLの場合には,コンフィギュレータまたはカーネルにより確保されるスタック領域のサイズに,sstkszが加えられる【NGKI1069】.stkszにsstkszを加えた値が,ターゲット定義の制約に合致しないサイズになる時には,ターゲット定義の制約に合致するように大きい方に丸めたサイズで確保される【NGKI1070】.
sstkszに0以外の値を指定した場合で,stkがNULLでない場合には,E_PARエラーとなる【NGKI1071】.
静的APIでsstkszの記述を省略するか,sstkszに0を指定した場合,これらの処理は行わず,E_PARエラーにもならない【NGKI1072】.
この仕様では,タスクのスタック領域に,他のタスクからアクセスできるとは限らない【NGKI5166】.実際,保護機能対応カーネルでは,ユーザタスクのユーザスタック領域には,他のユーザタスクはアクセスすることができないのが基本である.また,マルチプロセッサ対応カーネルでは,スタック領域が他のプロセッサからアクセスできない領域に配置される場合もある.そのため,ローカル変数へのポインタを渡すなどして,他のタスクからローカル変数にアクセスさせることは推奨しない.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,acre_tskをサポートする【ASPS0105】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,acre_tskをサポートする【HRPS0175】.ただし,生成するタスクがユーザタスクの場合,stkとstkszで指定するユーザスタック領域の扱いは,以下の点でCRE_TSKと異なる.
-
stkにNULLが指定されるとカーネルがスタック領域を確保する機能はサポートしない.stkにNULLを指定した場合には,E_NOSPTエラーとなる【HRPS0176】.
-
ユーザスタック領域をアプリケーションで確保する方法は,ターゲット定義で,CRE_TSKとは異なる場合がある【HRPS0240】.その方法に従わず,指定したユーザスタック領域がターゲット定義の制約に合致しない場合には,E_OBJエラーとなる【HRPS0241】.
-
指定したユーザスタック領域は,カーネルにメモリオブジェクトとして登録されない【HRPS0242】.そのため,指定したユーザスタック領域が,動的に生成された他のタスクのユーザスタック領域と重なる場合のエラーチェックは行われない【HRPS0243】.同時に起動される他のタスクのユーザスタック領域と重ならないようにするのは,アプリケーションの責任である.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,複数のタスクに対して,同じ起動時優先度を設定することはできない.設定した場合には,コンフィギュレータがE_PARエラーを報告する【SSPS0109】.
SSP3カーネルでは,制約タスクのみをサポートするため,タスク属性にTA_RSTRを指定しない場合でも,生成されるタスクは制約タスクとなる【SSPS0110】.
SSP3カーネルでは,stkにはNULLを指定しなくてはならず,その場合でも,コンフィギュレータはタスクのスタック領域を確保しない【SSPS0111】.これは,SSP3カーネルでは,すべての処理単位が共有スタック領域を使用し,タスク毎にスタック領域を持たないためである.stkにNULL以外を指定した場合には,E_PARエラーとなる【SSPS0112】.
共有スタック領域の設定方法については,DEF_STKの項を参照すること.
【μITRON4.0仕様との関係】
taskのデータ型をTASKに,stkのデータ型をSTK_T *に変更した.COUNT_STK_TとROUND_STK_Tを新設し,スタック領域をアプリケーションで確保する方法を規定した.
【μITRON4.0/PX仕様との関係】
sstkのデータ型をSTK_T *に変更した.システムスタック領域をアプリケーションで確保する方法を規定した.
アクセス権を制御するためのアクセスの種別を,保護ドメインに対する通常操作1に変更した.
【TOPPERS新世代カーネル統合仕様との関係】
アクセス権を制御するためのアクセスの種別を,保護ドメインに対する通常操作1に変更した.
保護機能対応カーネルにおいて,コンフィギュレータが,スタック領域をどこに確保するかを規定した.
【未決定事項】
サービスコール(acre_tsk)で,stkにNULLを指定して制約タスクを生成する場合のスタック領域の確保方法については,今後の課題である.
保護機能対応カーネルにおいて,サービスコール(acre_tsk)で,tskにNULLを指定してユーザタスクを生成する場合のユーザスタック領域の確保方法については,今後の課題である.
【仕様決定の理由】
保護機能対応カーネルにおいて,sstkszおよびsstkの記述は省略することができることとしたのは,保護機能対応でないカーネル用のシステムコンフィギュレーションファイルを,保護機能対応カーネルにも変更なしに使えるようにするためである.
AID_TSK |
割付け可能なタスクIDの数の指定〔SD〕【NGKI1073】 |
【静的API】
AID_TSK(uint_t notsk)
【パラメータ】
uint_t |
notsk |
割付け可能なタスクIDの数 |
【エラーコード】
E_RSATR |
予約属性 |
【機能】
notskで指定した数のタスクIDを,タスクを生成するサービスコールによって割付け可能なタスクIDとして確保する【NGKI1076】.
notskは整数定数式パラメータである【NGKI1077】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,AID_TSKをサポートする【ASPS0210】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,AID_TSKをサポートする【HRPS0211】.
SAC_TSK |
タスクのアクセス許可ベクタの設定〔SP〕【NGKI1078】 |
sac_tsk |
タスクのアクセス許可ベクタの設定〔TPD〕【NGKI1079】 |
【静的API】
SAC_TSK(ID tskid, { ACPTN acptn1, ACPTN acptn2,
ACPTN acptn3, ACPTN acptn4 })
【C言語API】
ER ercd = sac_tsk(ID tskid, const ACVCT *p_acvct)
【パラメータ】
ID |
tskid |
対象タスクの識別名(SAC_TSKの場合)またはID番号(sac_tskの場合) |
|
ACVCT * |
p_acvct |
アクセス許可ベクタを入れたパケットへのポインタ(sac_tskの場合) |
*アクセス許可ベクタ(パケットの内容)
ACPTN |
acptn1 |
通常操作1のアクセス許可パターン |
|
ACPTN |
acptn2 |
通常操作2のアクセス許可パターン |
|
ACPTN |
acptn3 |
管理操作のアクセス許可パターン |
|
ACPTN |
acptn4 |
参照操作のアクセス許可パターン |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_RSATR |
予約属性 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)のアクセス許可ベクタ(4つのアクセス許可パターンの組)を,各パラメータで指定した値に設定する【NGKI1090】.
静的APIにおいては,tskidはオブジェクト識別名,acptn1〜acptn4は整数定数式パラメータである【NGKI1091】.
sac_tskにおいてtskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1092】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,sac_tskをサポートする【HRPS0177】.
DEF_EPR |
タスクの実行時優先度の定義〔S〕【NGKI1093】 |
【静的API】
DEF_EPR(ID tskid, { PRI exepri })
【パラメータ】
ID |
tskid |
対象タスクの識別名 |
|
PRI |
exepri |
タスクの実行時優先度 |
【エラーコード】
E_PAR |
パラメータエラー |
|
E_ILUSE |
サービスコール不正使用 |
|
E_OBJ |
オブジェクト状態エラー |
【サポートするカーネル】
DEF_EPRは,TOPPERS/SSP3カーネルのみがサポートする静的APIである.他のカーネルは,DEF_EPRをサポートしない【NGKI1096】.
【機能】
tskidで指定したタスク(対象タスク)の実行時優先度を,exepriで指定した優先度に設定する【NGKI1097】.
tskidはオブジェクト識別名,exepriは整数定数式パラメータである【NGKI1098】.
exepriが,対象タスクの起動時優先度よりも低い場合には,E_ILUSEエラーとなる【NGKI1099】.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていない静的APIである.
del_tsk |
タスクの削除〔TD〕【NGKI1100】 |
【C言語API】
ER ercd = del_tsk(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)を削除する.具体的な振舞いは以下の通り.
対象タスクが休止状態である場合には,対象タスクの登録が解除され,そのタスクIDが未使用の状態に戻される【NGKI1108】.また,タスクの生成時にタスクのスタック領域およびシステムスタック領域がカーネルによって確保された場合は,それらのメモリ領域が解放される【NGKI1109】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,del_tskをサポートする【ASPS0108】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,del_tskをサポートする【HRPS0178】.
act_tsk |
タスクの起動〔TI〕【NGKI3529】 |
【C言語API】
ER ercd = act_tsk(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_QOVR |
キューイングオーバフロー |
【機能】
tskidで指定したタスク(対象タスク)に対して起動要求を行う.具体的な振舞いは以下の通り.
対象タスクが休止状態である場合には,対象タスクに対してタスク起動時に行うべき初期化処理が行われ,対象タスクは実行できる状態になる【NGKI1118】.
対象タスクが休止状態でなく,対象タスクがTA_NOACTQUE属性でない場合には,対象タスクの起動要求キューイング数に1が加えられる【NGKI3527】.対象タスクがTA_NOACTQUE属性である場合や,起動要求キューイング数に1を加えるとTMAX_ACTCNTを超える場合には,E_QOVRエラーとなる【NGKI3528】.
タスクコンテキストから呼び出した場合,tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1121】.
【補足説明】
マルチプロセッサ対応カーネルでは,act_tskは,対象タスクの次回起動時の割付けプロセッサを設定しない.
mact_tsk |
割付けプロセッサ指定でのタスクの起動〔TIM〕【NGKI3530】 |
【C言語API】
ER ercd = mact_tsk(ID tskid, ID prcid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
ID |
prcid |
タスクの割付け対象のプロセッサのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_QOVR |
キューイングオーバフロー |
【機能】
prcidで指定したプロセッサを割付けプロセッサとして,tskidで指定したタスク(対象タスク)に対して起動要求を行う.具体的な振舞いは以下の通り.
対象タスクが休止状態である場合には,対象タスクの割付けプロセッサがprcidで指定したプロセッサに変更された後,対象タスクに対してタスク起動時に行うべき初期化処理が行われ,対象タスクは実行できる状態になる【NGKI1132】.
対象タスクが休止状態でなく,対象タスクがTA_NOACTQUE属性でない場合には,対象タスクの起動要求キューイング数に1が加えられ,次回起動時の割付けプロセッサがprcidで指定したプロセッサに設定される【NGKI3557】.対象タスクがTA_NOACTQUE属性である場合や,起動要求キューイング数に1を加えるとTMAX_ACTCNTを超える場合には,E_QOVRエラーとなる【NGKI3558】.
タスクコンテキストから呼び出した場合,tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1135】.
対象タスクの属するクラスの割付け可能プロセッサが,prcidで指定したプロセッサを含んでいない場合には,E_PARエラーとなる【NGKI1136】.
保護機能対応カーネルでは,対象タスクがユーザタスクの場合に,[NGKI0628]の制約が課される.具体的には,対象タスクが属するユーザドメインが,アイドルドメインにまとめられておらず,prcidで指定したプロセッサでタイムウィンドウを割り当てられていない場合,E_PARエラーとなる【NGKI5109】.
prcidにTPRC_INI(=0)を指定すると,対象タスクの割付けプロセッサを,それが属するクラスの初期割付けプロセッサとする【NGKI1137】.
【補足説明】
TMAX_ACTCNTが2以上の場合でも,対象タスクが次に起動される時の割付けプロセッサは,キューイングされない.すなわち,プロセッサAに割り付けられた休止状態でないタスクを対象として,プロセッサBを割付けプロセッサとしてmact_tskを呼び出し,さらにプロセッサCを割付けプロセッサとしてmact_tskを呼び出すと,対象タスクの次回起動時の割付けプロセッサがプロセッサCに変更され,対象タスクがプロセッサBで実行されることはない.なお,TMAX_ACTCNTが1の場合には,プロセッサCを割付けプロセッサとした2回目のmact_tskがE_QOVRエラーとなるため,次回起動時の割付けプロセッサはプロセッサBのまま変更されない.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていないサービスコールである.
can_act |
タスク起動要求のキャンセル〔T〕【NGKI1138】 |
【C言語API】
ER_UINT actcnt = can_act(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER_UINT |
actcnt |
キューイングされていた起動要求の数(正の値または0)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
tskidで指定したタスク(対象タスク)に対する処理されていない起動要求をすべてキャンセルし,キャンセルした起動要求の数を返す.具体的な振舞いは以下の通り.
対象タスクの起動要求キューイング数が0に設定され,0に設定する前の起動要求キューイング数が,サービスコールの返値として返される【NGKI1144】.また,マルチプロセッサ対応カーネルにおいては,対象タスクの次回起動時の割付けプロセッサが未設定の状態に戻される【NGKI1145】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1146】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,can_actをサポートしない【SSPS0116】.
mig_tsk |
タスクの割付けプロセッサの変更〔TM〕【NGKI1147】 |
【C言語API】
ER ercd = mig_tsk(ID tskid, ID prcid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
ID |
prcid |
タスクの割付けプロセッサのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスクの割付けプロセッサを,prcidで指定したプロセッサに変更する.具体的な振舞いは以下の通り.
対象タスクが,自タスクが割り付けられたプロセッサに割り付けられている場合には,対象タスクをprcidで指定したプロセッサに割り付ける【NGKI1155】.対象タスクが実行できる状態の場合には,prcidで指定したプロセッサに割り付けられた優先度が同じタスク(サブ優先度が使われる状況では,サブ優先度も同じタスク)の中で,優先順位が最も低くなる【NGKI1156】.
対象タスクが,自タスクが割付けられたプロセッサと異なるプロセッサに割り付けられている場合には,E_OBJエラーとなる【NGKI1157】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1158】.
ディスパッチ保留状態で,対象タスクを自タスクとしてmig_tskを呼び出すと,E_CTXエラーとなる【NGKI1159】.
対象タスクの属するクラスの割付け可能プロセッサが,prcidで指定したプロセッサを含んでいない場合には,E_PARエラーとなる【NGKI1160】.
保護機能対応カーネルでは,対象タスクがユーザタスクの場合に,[NGKI0628]の制約が課される.具体的には,対象タスクが属するユーザドメインが,アイドルドメインにまとめられておらず,prcidで指定したプロセッサでタイムウィンドウを割り当てられていない場合,E_PARエラーとなる【NGKI5110】.
prcidにTPRC_INI(=0)を指定すると,対象タスクの割付けプロセッサを,それが属するクラスの初期割付けプロセッサに変更する【NGKI1161】.
【補足説明】
この仕様では,タスクをマイグレートさせることができるのは,そのタスクと同じプロセッサに割り付けられたタスクのみである.そのため,CPUロック状態やディスパッチ禁止状態を用いて,他のタスクへのディスパッチが起こらないようにすることで,自タスクが他のプロセッサへマイグレートされるのを防ぐことができる.
対象タスクが,最初からprcidで指定したプロセッサに割り付けられている場合には,割付けプロセッサの変更は起こらないが,優先度が同じタスク(サブ優先度が使われる状況では,サブ優先度も同じタスク)の中で,優先順位が最も低くなる.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていないサービスコールである.
get_tst |
タスク状態の参照〔T〕【NGKI3613】 |
【C言語API】
ER ercd = get_tst(ID tskid, STAT *p_tskstat)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
STAT * |
p_tskstat |
タスク状態を入れるメモリ領域へのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
|
STAT |
tskstat |
タスク状態 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
【機能】
tskidで指定したタスク(対象タスク)のタスク状態を参照する.具体的な振舞いは以下の通り.
対象タスクの現在のタスク状態を表す次のいずれかの値が,p_tskstatが指すメモリ領域に返される【NGKI3620】.
TTS_RUN |
0x01U |
実行状態 |
|
TTS_RDY |
0x02U |
実行可能状態 |
|
TTS_WAI |
0x04U |
待ち状態 |
|
TTS_SUS |
0x08U |
強制待ち状態 |
|
TTS_WAS |
0x0cU |
二重待ち状態 |
|
TTS_DMT |
0x10U |
休止状態 |
マルチプロセッサ対応カーネルでは,対象タスクが自タスクの場合にも,TTS_SUSが返される場合がある【NGKI5209】.この状況は,自タスクに対してget_tstを発行するのと同じタイミングで,他のプロセッサで実行されているタスクから同じタスクに対してsus_tskが発行された場合に発生する可能性がある.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI3621】.
【使用上の注意】
get_tstを呼び出し,対象タスクの現在状態を参照した直後に割込みが発生した場合,get_tstから戻ってきた時には対象タスクの状態が変化している可能性がある.また,マルチプロセッサ対応カーネルでは,対象タスクの現在状態を参照した直後に,他のプロセッサで実行されている処理により対象タスクの状態が変化する場合もある.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様に定義されていないサービスコールである.
chg_pri |
タスクのベース優先度の変更〔T〕【NGKI1183】 |
【C言語API】
ER ercd = chg_pri(ID tskid, PRI tskpri)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
PRI |
tskpri |
ベース優先度 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_ILUSE |
サービスコール不正使用 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)のベース優先度を,tskpriで指定した優先度に変更する.具体的な振舞いは以下の通り.
対象タスクが休止状態でない場合には,対象タスクのベース優先度が,tskpriで指定した優先度に変更される【NGKI1192】.それに伴って,対象タスクの現在優先度も変更される【NGKI1193】.
chg_priを発行した結果,対象タスクの現在優先度が変化する場合と,対象タスクが優先度上昇状態でない場合(正確な定義は「4.4.5 ミューテックス」の節を参照すること.ミューテックス機能を使わない場合には,この条件は常に成り立つ)には,以下の処理が行われる.
対象タスクが実行できる状態の場合には,現在優先度が同じ(サブ優先度が使われる状況では,サブ優先度も同じ)タスクの中で,対象タスクの優先順位が最も低くなる【NGKI1194】.対象タスクが待ち状態で,タスクの優先度順の待ち行列につながれている場合には,対象タスクの変更後の優先度に従って,その待ち行列中での順序が変更される【NGKI1195】.待ち行列中に現在優先度が同じタスクがある場合には,対象タスクの順序はそれらの中で最後になる【NGKI1196】.
対象タスクが優先度上昇状態であり,対象タスクの現在優先度が変化しない場合には,対象タスクの優先順位や待ち行列中での順序は変更されない【NGKI1197】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1198】.また,tskpriにTPRI_INI(=0)を指定すると,対象タスクのベース優先度が,起動時優先度に変更される【NGKI1199】.
対象タスクが優先度上限ミューテックスをロックしているかロックを待っている場合,tskpriは,それらのミューテックスの上限優先度と同じかそれより低くなければならない.そうでない場合には,E_ILUSEエラーとなる【NGKI1201】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,chg_priをサポートしない【SSPS0121】.
【μITRON4.0仕様との関係】
対象タスクが,同じ優先度のタスクの中で最低の優先順位となる(対象タスクが待ち状態で,タスクの優先度順の待ち行列につながれている場合には,同じ優先度のタスクの中での順序が最後になる)条件を変更した.
【TOPPERS新世代カーネル統合仕様との関係】
ユーザドメインが指定できる最高のタスク優先度の機能を廃止した.
get_pri |
タスク優先度の参照〔T〕【NGKI1202】 |
【C言語API】
ER ercd = get_pri(ID tskid, PRI *p_tskpri)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
PRI * |
p_tskpri |
現在優先度を入れるメモリ領域へのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
|
PRI |
tskpri |
現在優先度 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)の現在優先度を参照する.具体的な振舞いは以下の通り.
対象タスクが休止状態でない場合には,対象タスクの現在優先度が,p_tskpriが指すメモリ領域に返される【NGKI1210】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1211】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,get_priをサポートしない【SSPS0122】.
chg_spr |
タスクのサブ優先度の変更〔T〕【NGKI3665】 |
【C言語API】
ER ercd = chg_spr(ID tskid, uint_t subpri)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
uint_t |
subpri |
サブ優先度 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
tskidで指定したタスク(対象タスク)のサブ優先度を,subpriで指定した値に変更する.具体的な振舞いは以下の通り.
対象タスクのサブ優先度が,subpriで指定した値に変更される【NGKI3672】.対象タスクが実行できる状態で,対象タスクの現在優先度がサブ優先度を使用すると設定されており,対象タスクが優先度上昇状態でない場合(正確な定義は「4.4.5 ミューテックス」の節を参照すること.ミューテックス機能を使わない場合には,この条件は常に成り立つ)には,優先度とサブ優先度が同じタスクの中で,対象タスクの優先順位が最も低くなる【NGKI3673】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI3674】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,chg_sprをサポートしない【ASPS0231】.ただし,サブ優先度機能拡張パッケージでは,chg_sprをサポートする【ASPS0232】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,chg_sprをサポートする【FMPS0169】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,chg_sprをサポートしない【HRPS0224】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,chg_sprをサポートしない【HRMPS0103】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,chg_sprをサポートしない【SSPS0161】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様に定義されていないサービスコールである.
get_inf |
自タスクの拡張情報の参照〔T〕【NGKI1212】 |
【C言語API】
ER ercd = get_inf(EXINF *p_exinf)
【パラメータ】
EXINF * |
p_exinf |
拡張情報を入れるメモリ領域へのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
|
EXINF |
exinf |
拡張情報 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_MACV |
メモリアクセス違反 |
【機能】
自タスクの拡張情報を参照する.参照した拡張情報は,p_exinfが指すメモリ領域に返される【NGKI1216】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,get_infをサポートしない【SSPS0123】.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていないサービスコールである.
ref_tsk |
タスクの状態参照〔T〕【NGKI1217】 |
【C言語API】
ER ercd = ref_tsk(ID tskid, T_RTSK *pk_rtsk)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
|
T_RTSK * |
pk_rtsk |
タスクの現在状態を入れるパケットへのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
*タスクの現在状態(パケットの内容)
STAT |
tskstat |
タスク状態 |
|
PRI |
tskpri |
タスクの現在優先度 |
|
PRI |
tskbpri |
タスクのベース優先度 |
|
uint_t |
subpri |
タスクのサブ優先度(サブ優先度機能をサポートするカーネルの場合) |
|
STAT |
tskwait |
タスクの待ち要因 |
|
ID |
wobjid |
タスクの待ち対象のオブジェクトのID |
|
TMO |
lefttmo |
タスクがタイムアウトするまでの時間 |
|
uint_t |
actcnt |
タスクの起動要求キューイング数 |
|
uint_t |
wupcnt |
タスクの起床要求キューイング数 |
|
bool_t |
raster |
タスク終了要求フラグ |
|
bool_t |
dister |
タスク終了禁止状態 |
|
uint_t |
svclevel |
タスクの拡張サービスコールのネストレベル(保護機能対応カーネルの場合) |
|
ID |
prcid |
タスクの割付けプロセッサのID(マルチプロセッサ対応カーネルの場合) |
|
ID |
actprc |
タスクの次回起動時の割付けプロセッサのID(マルチプロセッサ対応カーネルの場合) |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
【機能】
tskidで指定したタスク(対象タスク)の現在状態を参照する.参照した現在状態は,pk_rtskで指定したメモリ領域に返される【NGKI1224】.
tskstatには,対象タスクの現在のタスク状態を表す次のいずれかの値が返される【NGKI1225】.
TTS_RUN |
0x01U |
実行状態 |
|
TTS_RDY |
0x02U |
実行可能状態 |
|
TTS_WAI |
0x04U |
待ち状態 |
|
TTS_SUS |
0x08U |
強制待ち状態 |
|
TTS_WAS |
0x0cU |
二重待ち状態 |
|
TTS_DMT |
0x10U |
休止状態 |
マルチプロセッサ対応カーネルでは,対象タスクが自タスクの場合にも,tskstatがTTS_SUSとなる場合がある【NGKI1226】.この状況は,自タスクに対してref_tskを発行するのと同じタイミングで,他のプロセッサで実行されているタスクから同じタスクに対してsus_tskが発行された場合に発生する可能性がある.
対象タスクが休止状態でない場合には,tskpriには対象タスクの現在優先度が,tskbpriには対象タスクのベース優先度が返される【NGKI1227】.対象タスクが休止状態である場合には,tskpriとtskbpriの値は保証されない【NGKI1228】.
サブ優先度機能をサポートするカーネルでは,subpriには対象タスクのサブ優先度が返される【NGKI3662】.
対象タスクが待ち状態である場合には,tskwaitには,対象タスクが何を待っている状態であるかを表す次のいずれかの値が返される【NGKI1229】.
TTW_SLP |
0x0001U |
起床待ち |
|
TTW_DLY |
0x0002U |
時間経過待ち |
|
TTW_SEM |
0x0004U |
セマフォの資源獲得待ち |
|
TTW_FLG |
0x0008U |
イベントフラグ待ち |
|
TTW_SDTQ |
0x0010U |
データキューへの送信待ち |
|
TTW_RDTQ |
0x0020U |
データキューからの受信待ち |
|
TTW_SPDQ |
0x0100U |
優先度データキューへの送信待ち |
|
TTW_RPDQ |
0x0200U |
優先度データキューからの受信待ち |
|
TTW_MTX |
0x0080U |
ミューテックスのロック待ち状態 |
|
TTW_SMBF |
0x0400U |
メッセージバッファへの送信待ち |
|
TTW_RMBF |
0x0800U |
メッセージバッファからの受信待ち |
|
TTW_MPF |
0x2000U |
固定長メモリブロックの獲得待ち |
対象タスクが待ち状態でない場合には,tskwaitの値は保証されない【NGKI1230】.
対象タスクが起床待ち状態および時間経過待ち状態以外の待ち状態である場合には,wobjidに,対象タスクが待っているオブジェクトのID番号が返される【NGKI1231】.対象タスクが待ち状態でない場合や,起床待ち状態または時間経過待ち状態である場合には,wobjidの値は保証されない【NGKI1232】.
対象タスクが時間経過待ち状態以外の待ち状態である場合には,lefttmoに,タスクがタイムアウトを起こすまでの相対時間が返される【NGKI1233】.タスクがタイムアウトを起こさない場合には,TMO_FEVR(=UINT32_MAX)が返される【NGKI1234】.
対象タスクが時間経過待ち状態である場合には,lefttmoに,タスクの遅延時間が経過して待ち解除されるまでの相対時間が返される【NGKI1235】.
対象タスクが待ち状態でない場合には,lefttmoの値は保証されない【NGKI1237】.
actcntには,対象タスクの起動要求キューイング数が返される【NGKI1238】.
対象タスクが休止状態でない場合には,wupcntに,タスクの起床要求キューイング数が返される【NGKI1239】.また,rasterには,タスク終了要求フラグがセットされている場合にはtrue,クリアされている場合にはfalseが返される【NGKI3467】.disterには,タスク終了禁止状態の場合にはtrue,タスク終了許可状態の場合にはfalseが返される【NGKI3468】.対象タスクが休止状態である場合には,wupcnt,raster,disterの値は保証されない【NGKI1240】.
保護機能対応カーネルで,対象タスクが休止状態でない場合には,svclevelに,対象タスクが拡張サービスコールを呼び出していない場合には0,呼び出している場合には,実行中の拡張サービスコールがネスト段数が返される【NGKI1243】.対象タスクが休止状態である場合には,svclevelの値は保証されない【NGKI1244】.
マルチプロセッサ対応カーネルでは,prcidに,対象タスクの割付けプロセッサのID番号が返される【NGKI1245】.またactprcには,対象タスクの次回起動時の割付けプロセッサのID番号が返される【NGKI1246】.次回起動時の割付けプロセッサが未設定の場合には,actprcにTPRC_NONE(=0)が返される【NGKI1247】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1248】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,tskwaitにTTW_SMBF,TTW_RMBFが返ることはない【ASPS0235】.ただし,メッセージバッファ機能拡張パッケージを用いると,tskwaitにTTW_SMBFとTTW_RMBFが返る場合がある【ASPS0208】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,tskwaitにTTW_SMBF,TTW_RMBFが返ることはない【FMPS0173】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,ref_tskをサポートしない【SSPS0124】.
【使用上の注意】
ref_tskはデバッグ時向けの機能であり,その他の目的に使用することは推奨しない.これは,ref_tskを呼び出し,対象タスクの現在状態を参照した直後に割込みが発生した場合,ref_tskから戻ってきた時には対象タスクの状態が変化している可能性があるためである.また,マルチプロセッサ対応カーネルでは,対象タスクの現在状態を参照した直後に,他のプロセッサで実行されている処理により対象タスクの状態が変化する場合もある.
【μITRON4.0仕様との関係】
対象タスクが時間経過待ち状態の時にlefttmoに返される値について規定した.参照できる情報に,タスク終了要求フラグ(raster)とタスク終了禁止状態(dister)を追加した.逆に,参照できるタスクの状態から,強制待ち要求ネスト数(suscnt)を除外した.
マルチプロセッサ対応カーネルで参照できる情報として,割付けプロセッサのID(prcid)と次回起動時の割付けプロセッサのID(actprc)を追加した.
【μITRON4.0/PX仕様との関係】
保護機能対応カーネルで参照できる情報として,拡張サービスコールのネストレベル(svclevel)を追加した.
【TOPPERS新世代カーネル統合仕様との関係】
参照できる情報に,タスク終了要求フラグ(raster)とタスク終了禁止状態(dister)を追加した.逆に,保護機能対応カーネルで参照できる情報から,タスク例外処理マスク状態(texmsk)と待ち禁止状態(waifbd)を削除した.
4.2 タスク付属同期機能
タスク付属同期機能は,タスクとタスクの間,または非タスクコンテキストの処理とタスクの間で同期を取るために,タスク単独で持っている機能である.
タスク付属同期機能に関連して,各タスクが持つ情報は次の通り【NGKI1249】.
-
起床要求キューイング数
タスクの起床要求キューイング数は,処理されていないタスクの起床要求の数であり,タスクの起動時に0に初期化される【NGKI1250】.
タスク付属同期機能に関連するカーネル構成マクロは次の通り.
TMAX_WUPCNT |
タスクの起床要求キューイング数の最大値【NGKI1251】 |
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,TMAX_WUPCNTは1に固定されている【ASPS0113】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,TMAX_WUPCNTは1に固定されている【FMPS0107】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,TMAX_WUPCNTは1に固定されている【HRPS0109】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,TMAX_WUPCNTは1に固定されている【HRMPS0104】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,タスク付属同期機能をサポートしない【SSPS0125】.
【μITRON4.0仕様との関係】
この仕様では,強制待ち要求をネストする機能をサポートしないこととした.言い換えると,強制待ち要求ネスト数の最大値を1に固定する.これに伴い,強制待ち状態から強制再開するサービスコール(frsm_tsk)とタスクの強制待ち要求ネスト数の最大値を表すカーネル構成マクロ(TMAX_SUSCNT)は廃止した.また,ref_tskで参照できる情報(T_RTSKのフィールド)から,強制待ち要求ネスト数(suscnt)を除外した.
【TOPPERS新世代カーネル統合仕様との関係】
待ち禁止状態への遷移を行うサービスコール(dis_wai)とその解除を行うサービスコール(ena_wai)を廃止した.待ち禁止状態の役割は,新たに導入したタスク終了要求フラグがセットされた状態が兼ねている.
slp_tsk |
起床待ち〔T〕【NGKI1252】 |
tslp_tsk |
起床待ち(タイムアウト付き)〔T〕【NGKI1253】 |
【C言語API】
ER ercd = slp_tsk()
ER ercd = tslp_tsk(TMO tmout)
【パラメータ】
TMO |
tmout |
タイムアウト時間(tslp_tskの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_PAR |
パラメータエラー |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(tslp_tskの場合)【NGKI1257】 |
|
E_RLWAI |
待ち状態の強制解除【NGKI1258】 |
|
E_RASTER |
タスクの終了要求【NGKI3455】 |
【機能】
自タスクを起床待ちさせる.具体的な振舞いは以下の通り.
自タスクの起床要求キューイング数が0でない場合には,起床要求キューイング数から1が減ぜられる【NGKI1259】.起床要求キューイング数が0の場合には,自タスクは起床待ち状態となる【NGKI1260】.
【補足説明】
自タスクの起床要求キューイング数が0でない場合には,自タスクは実行できる状態を維持し,自タスクの優先順位は変化しない.
wup_tsk |
タスクの起床〔TI〕【NGKI3531】 |
【C言語API】
ER ercd = wup_tsk(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
|
E_QOVR |
キューイングオーバフロー |
【機能】
tskidで指定したタスク(対象タスク)を起床する.具体的な振舞いは以下の通り.
対象タスクが起床待ち状態である場合には,対象タスクが待ち解除される【NGKI1271】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1272】.
対象タスクが起床待ち状態でなく,休止状態でもない場合には,対象タスクの起床要求キューイング数に1が加えられる【NGKI1273】.起床要求キューイング数に1を加えるとTMAX_WUPCNTを超える場合には,E_QOVRエラーとなる【NGKI1274】.
タスクコンテキストから呼び出した場合,tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1275】.
can_wup |
タスク起床要求のキャンセル〔T〕【NGKI1276】 |
【C言語API】
ER_UINT wupcnt = can_wup(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER_UINT |
wupcnt |
キューイングされていた起床要求の数(正の値または0)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)に対する処理されていない起床要求をすべてキャンセルし,キャンセルした起床要求の数を返す.具体的な振舞いは以下の通り.
対象タスクが休止状態でない場合には,対象タスクの起床要求キューイング数が0に設定され,0に設定する前の起床要求キューイング数が,サービスコールの返値として返される【NGKI1284】.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1285】.
rel_wai |
強制的な待ち解除〔TI〕【NGKI3532】 |
【C言語API】
ER ercd = rel_wai(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)を,強制的に待ち解除する.具体的な振舞いは以下の通り.
対象タスクが待ち状態である場合には,対象タスクが待ち解除される【NGKI1296】.待ち解除されたタスクには,待ち状態となったサービスコールからE_RLWAIが返る【NGKI1297】.
sus_tsk |
強制待ち状態への遷移〔T〕【NGKI1298】 |
【C言語API】
ER ercd = sus_tsk(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
|
E_RASTER |
タスクの終了要求 |
|
E_QOVR |
キューイングオーバフロー |
【機能】
tskidで指定したタスク(対象タスク)を強制待ちにする.具体的な振舞いは以下の通り.
対象タスクが実行できる状態である場合には,対象タスクは強制待ち状態となる【NGKI1307】.また,待ち状態(二重待ち状態を除く)である場合には,二重待ち状態となる【NGKI1308】.
マルチプロセッサ対応カーネルでは,対象タスクが自タスクの場合にも,E_QOVRエラーとなる場合がある【NGKI1309】.この状況は,自タスクに対してsus_tskを発行するのと同じタイミングで,他のプロセッサで実行されているタスクから同じタスクに対してsus_tskが発行された場合に発生する可能性がある.
tskidにTSK_SELF(=0)を指定すると,自タスクが対象タスクとなる【NGKI1310】.
ディスパッチ保留状態で,対象タスクを自タスクとしてsus_tskを呼び出すと,E_CTXエラーとなる【NGKI1311】.なお,sus_tskは,自タスクを広義の待ち状態に遷移させる可能性のあるサービスコールであるが,対象タスクが自タスクでない場合には,割込み優先度マスクが全解除でない状態やディスパッチ禁止状態で呼び出しても,E_CTXエラーにはならない【NGKI3604】.これは,[NGKI0175]と[NGKI0179]の原則の例外となっている.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
システム状態に対するアクセス許可ベクタにより,呼出しを禁止できるようにした.
rsm_tsk |
強制待ち状態からの再開〔T〕【NGKI1312】 |
【C言語API】
ER ercd = rsm_tsk(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)を,強制待ちから再開する.具体的な振舞いは以下の通り.
対象タスクが強制待ち状態である場合には,対象タスクは強制待ちから再開される【NGKI1320】.
dly_tsk |
自タスクの遅延〔T〕【NGKI1348】 |
【C言語API】
ER ercd = dly_tsk(RELTIM dlytim)
【パラメータ】
RELTIM |
dlytim |
遅延時間 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_PAR |
パラメータエラー |
|
E_RLWAI |
待ち状態の強制解除【NGKI1352】 |
|
E_RASTER |
タスクの終了要求【NGKI3456】 |
【機能】
dlytimで指定した時間,自タスクを遅延させる.具体的な振舞いは以下の通り.
自タスクは,dlytimで指定した時間が経過するまでの間,時間経過待ち状態となる【NGKI1353】.dly_tskを呼び出してからdlytimで指定した相対時間後に,自タスクは待ち解除され,dly_tskからE_OKが返る【NGKI1354】.
4.3 タスク終了機能
タスク終了機能には,自タスクを終了させる機能,タスクを安全に終了させるためのタスク終了要求機能,タスクを強制終了させる機能が含まれる.
タスク終了時には,次の処理が行われる.まず,終了するタスク(対象タスク)に対してタスク終了時に行うべきその他の処理が行われた後,対象タスクは休止状態になる【NGKI1178】.対象タスクの起動要求キューイング数が0でない場合には,対象タスクに対してタスク起動時に行うべき処理が行われ,対象タスクは実行できる状態になる【NGKI1179】.またこの時,起動要求キューイング数から1が減ぜられる【NGKI1180】.さらに,マルチプロセッサ対応カーネルにおいては,次回起動時の割付けプロセッサが設定されていれば,タスクの割付けプロセッサがそのプロセッサに変更され,次回起動時の割付けプロセッサは未設定の状態に戻される【NGKI1008】.
タスク終了要求機能に関連して,各タスクが持つ情報は次の通り【NGKI3684】.
-
タスク終了要求フラグ
-
タスク終了禁止フラグ
タスク終了要求フラグは,タスクに対する終了要求を記憶するためのフラグであり,タスクの起動時にクリアした状態に初期化される【NGKI3451】.
タスク終了禁止フラグは,タスクに対する終了要求を保留するためのフラグで,タスクの起動時にクリアした状態に初期化される【NGKI3454】.タスク終了禁止フラグがセットされた状態をタスク終了禁止状態,クリアされた状態をタスク終了許可状態と呼ぶ.
実行状態のタスクに対して,「タスク終了要求フラグがセットされる」「タスク終了許可状態である」「ディスパッチ許可状態である」「割込み優先度マスク全解除状態である」「CPUロック状態でない」の5つの条件が揃った場合,そのタスクは終了する.すなわち,そのタスクに対して,タスク終了時に行うべき処理が行われる【NGKI3683】.
タスク終了要求フラグがセットされたタスクは,広義の待ち状態になることがない.具体的には,広義の待ち状態のタスクのタスク終了要求フラグがセットされた場合,タスクは実行できる状態に遷移する【NGKI3452】.タスクが待ち状態であった場合には,待ち状態となったサービスコールからE_RASTERが返る【NGKI5206】.また,タスク終了要求フラグがセットされたタスクが,自タスクを待ち状態に遷移させる可能性のあるサービスコールを呼び出した場合には,E_RASTERエラーとなる【NGKI3453】.さらに,タスク終了要求フラグがセットされたタスクを強制待ち状態に遷移させるサービスコールを呼び出した場合にも,E_RASTERエラーとなる【NGKI3607】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
タスク終了要求機能を追加した.
タスク終了要求フラグがセットされた状態は,μITRON4.0/PX仕様で導入された待ち禁止状態を役割を兼ねている.ただし,この仕様でタスク終了要求フラグがセットされたタスクが自タスクを待ち状態に遷移させる可能性のあるサービスコールを呼び出した場合,無条件にエラーになる[NGKI3453]のに対して,TOPPERS新世代カーネル統合仕様で待ち禁止状態のタスクが同様のサービスコールを呼び出した場合には,待ち状態に遷移しようとした場合にのみエラーとなる[NGKI0222].例えば,資源数が1のセマフォに対して,待ち禁止状態のタスクがwai_semを発行した場合,セマフォの獲得に成功するのに対して,タスク終了要求フラグがセットされたタスクが発行した場合には,E_RASTERエラーとなる.
ext_tsk |
自タスクの終了〔T〕【NGKI1162】 |
【C言語API】
ER ercd = ext_tsk()
【パラメータ】
なし |
【リターンパラメータ】
ER |
ercd |
エラーコード |
【エラーコード】
E_SYS |
システムエラー |
|
E_CTX |
コンテキストエラー |
【機能】
自タスクを終了させる.具体的には,自タスクに対してタスク終了時に行うべき処理が行われる【NGKI3449】.
ext_tskは,CPUロック解除状態,割込み優先度マスク全解除状態,ディスパッチ許可状態で呼び出すのが原則であるが,そうでない状態で呼び出された場合には,CPUロック解除状態,割込み優先度マスク全解除状態,ディスパッチ許可状態に遷移させた後,自タスクを終了させる【NGKI1168】.
マルチプロセッサ対応カーネルでは,CPUロック解除状態に遷移させた後,自タスクを終了させる前に,割込みを受け付ける場合があり,その結果,他のタスクに切り換わる場合もある【NGKI5183】.これは,カーネル処理の不可分性の原則の例外となっている.
ext_tskが正常に処理された場合,ext_tskからはリターンしない【NGKI1169】.
【補足説明】
保護機能対応カーネルにおいては,ext_tskによりCPUロック解除状態,割込み優先度マスク全解除状態,ディスパッチ許可状態に遷移した場合,システム周期の切換えとタイムウィンドウの切換えの保留が解除され,システム周期の切換えとタイムウィンドウの切換えが起こる可能性がある.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,ext_tskをサポートしない【SSPS0118】.自タスクを終了させる場合には,タスクのメインルーチンからリターンする【SSPS0119】.
【μITRON4.0仕様との関係】
ext_tskを非タスクコンテキストから呼び出した場合に,E_CTXエラーが返ることとした.μITRON4.0仕様においては,ext_tskからはリターンしないと規定されている.
ras_ter |
タスクの終了要求〔T〕【NGKI3469】 |
【C言語API】
ER ercd = ras_ter(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_ILUSE |
サービスコール不正使用 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)に終了要求を行う.具体的な振舞いは以下の通り.
対象タスクが休止状態でなく,タスク終了許可状態である場合には,対象タスクに対してタスク終了時に行うべき処理が行われる【NGKI3477】.
対象タスクが休止状態でなく,タスク終了禁止状態である場合には,対象タスクのタスク終了要求フラグがセットされる【NGKI3478】.また,対象タスクが待ち状態である場合には,対象タスクが待ち解除される【NGKI3479】.待ち解除されたタスクには,待ち状態となったサービスコールからE_RASTERが返る【NGKI3480】.さらに,対象タスクが強制待ち状態である場合には,対象タスクは強制待ちから再開される【NGKI3606】.
マルチプロセッサ対応カーネルでは,対象タスクは,自タスクと同じプロセッサに割り付けられているタスクに限られる.対象タスクが自タスクと異なるプロセッサに割り付けられている場合には,E_OBJエラーとなる【NGKI3481】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,ras_terをサポートしない【SSPS0151】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様に定義されていないサービスコールである.
dis_ter |
タスク終了の禁止〔T〕【NGKI3482】 |
【C言語API】
ER ercd = dis_ter()
【パラメータ】
なし |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
自タスクのタスク終了禁止フラグをセットする【NGKI3486】.すなわち,自タスクをタスク終了禁止状態に遷移させる.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,dis_terをサポートしない【SSPS0152】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様に定義されていないサービスコールである.
ena_ter |
タスク終了の許可〔T〕【NGKI3487】 |
【C言語API】
ER ercd = ena_ter()
【パラメータ】
なし |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
自タスクのタスク終了禁止フラグをクリアする【NGKI3491】.すなわち,自タスクをタスク終了許可状態に遷移させる.
【補足説明】
自タスクのタスク終了要求フラグがセットされていた場合には,タスク終了許可状態へ遷移した結果,自タスクが終了する可能性がある.この場合,ena_terからはリターンしない.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,ena_terをサポートしない【SSPS0153】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様に定義されていないサービスコールである.
sns_ter |
タスク終了禁止状態の参照〔TI〕【NGKI3494】 |
【C言語API】
bool_t state = sns_ter()
【パラメータ】
なし |
【リターンパラメータ】
bool_t |
state |
タスク終了禁止状態 |
【機能】
実行状態のタスク(タスクコンテキストから呼び出した場合には自タスク)のタスク終了禁止フラグを参照する.具体的な振舞いは以下の通り.
実行状態のタスクが,タスク終了禁止状態の場合にtrue,タスク終了許可状態の場合にfalseが返る【NGKI3495】.sns_terを非タスクコンテキストから呼び出した場合で,実行状態のタスクがない場合には,trueが返る【NGKI3496】.
マルチプロセッサ対応カーネルにおいては,サービスコールを呼び出した処理単位を実行しているプロセッサにおいて実行状態のタスクのタスク終了禁止フラグを参照する【NGKI3497】.
【補足説明】
sns_terをタスクコンテキストから呼び出した場合,実行状態のタスクは自タスクに一致する.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,sns_terをサポートしない【SSPS0154】.
【μITRON4.0仕様,TOPPERS新世代カーネル統合仕様との関係】
μITRON4.0仕様およびTOPPERS新世代カーネル統合仕様に定義されていないサービスコールである.
ter_tsk |
タスクの強制終了〔T〕【NGKI1170】 |
【C言語API】
ER ercd = ter_tsk(ID tskid)
【パラメータ】
ID |
tskid |
対象タスクのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_ILUSE |
サービスコール不正使用 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
tskidで指定したタスク(対象タスク)を終了させる.具体的には,対象タスクが休止状態でない場合には,対象タスクに対してタスク終了時に行うべき処理が行われる【NGKI3450】.
マルチプロセッサ対応カーネルでは,対象タスクは,自タスクと同じプロセッサに割り付けられているタスクに限られる.対象タスクが自タスクと異なるプロセッサに割り付けられている場合には,E_OBJエラーとなる【NGKI1182】.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,ter_tskをサポートしない【SSPS0120】.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
システム状態に対するアクセス許可ベクタにより,呼出しを禁止できるようにした.
4.4 同期・通信機能
同期・通信機能は,タスクとは独立したオブジェクトにより,タスクとタスクの間,または非タスクコンテキストの処理とタスクの間で同期・通信を行うための機能である.
【TOPPERS/SSP3カーネルにおける規定】
SSP3カーネルでは,同期・通信機能をサポートしない【SSPS0127】.
【μITRON4.0仕様との関係】
メールボックス機能を廃止し,スピンロック機能を追加した.
ランデブ機能はサポートしていない.今後の検討により,ランデブ機能をサポートすることに変更する可能性もある.
【TOPPERS新世代カーネル統合仕様との関係】
メールボックス機能を廃止した.
【仕様決定の理由】
メールボックス機能を廃止したのは,保護機能対応カーネルではサポートできないためである.メールボックス機能は,ほとんどの場合に,データキュー機能または優先度データキュー機能を用いて,メッセージを置いたメモリ領域へのポインタを送受信する方法で置き換えることができる.
4.4.1 セマフォ
セマフォは,資源の数を表す0以上の整数値を取るカウンタ(資源数)を介して,排他制御やイベント通知を行うための同期・通信オブジェクトである.セマフォの資源数から1を減ずることを資源の獲得,資源数に1を加えることを資源の返却と呼ぶ.セマフォは,セマフォIDと呼ぶID番号によって識別する【NGKI1445】.
各セマフォが持つ情報は次の通り【NGKI1446】.
-
セマフォ属性
-
資源数(の現在値)
-
待ち行列(セマフォの資源獲得待ち状態のタスクのキュー)
-
初期資源数
-
最大資源数
-
アクセス許可ベクタ(保護機能対応カーネルの場合)
-
属する保護ドメイン(保護機能対応カーネルの場合)
-
属するクラス(マルチプロセッサ対応カーネルの場合)
待ち行列は,セマフォの資源が獲得できるまで待っている状態(セマフォの資源獲得待ち状態)のタスクが,資源を獲得できる順序でつながれているキューである.
セマフォの初期資源数は,セマフォを生成または再初期化した際の,資源数の初期値である.また,セマフォの最大資源数は,資源数が取りうる最大値である.資源数が最大資源数に一致している時に資源を返却しようとすると,E_QOVRエラーとなる【NGKI1447】.
セマフォ属性には,次の属性を指定することができる【NGKI1448】.
TA_TPRI |
0x01U |
待ち行列をタスクの優先度順にする |
TA_TPRIを指定しない場合,待ち行列はFIFO順になる【NGKI1449】.
セマフォ機能に関連するカーネル構成マクロは次の通り.
TMAX_MAXSEM |
セマフォの最大資源数の最大値(=UINT_MAX)【NGKI1450】 |
TNUM_SEMID |
登録できるセマフォの数(動的生成対応でないカーネルでは,静的APIによって登録されたセマフォの数に一致)【NGKI1451】 |
【μITRON4.0仕様との関係】
TNUM_SEMIDは,μITRON4.0仕様に規定されていないカーネル構成マクロである.
CRE_SEM |
セマフォの生成〔S〕【NGKI1452】 |
acre_sem |
セマフォの生成〔TD〕【NGKI1453】 |
【静的API】
CRE_SEM(ID semid, { ATR sematr, uint_t isemcnt, uint_t maxsem })
【C言語API】
ER_ID semid = acre_sem(const T_CSEM *pk_csem)
【パラメータ】
ID |
semid |
生成するセマフォの識別名(CRE_SEMの場合) |
|
T_CSEM * |
pk_csem |
セマフォの生成情報を入れたパケットへのポインタ(acre_semの場合) |
*セマフォの生成情報(パケットの内容)
ATR |
sematr |
セマフォ属性 |
|
uint_t |
isemcnt |
セマフォの初期資源数 |
|
uint_t |
maxsem |
セマフォの最大資源数 |
【リターンパラメータ】
ER_ID |
semid |
生成されたセマフォのID番号(正の値)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_RSATR |
予約属性 |
|
E_PAR |
パラメータエラー |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_NOID |
ID番号不足 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
各パラメータで指定したセマフォの生成情報に従って,セマフォを生成する【NGKI5189】.生成されたセマフォの資源数は初期資源数に,待ち行列は空の状態に初期化される【NGKI1464】.
静的APIにおいては,semidはオブジェクト識別名,sematr,isemcnt,maxsemは整数定数式パラメータである【NGKI1465】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,acre_semをサポートする【ASPS0120】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,acre_semをサポートする【HRPS0180】.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
アクセス権を制御するためのアクセスの種別を,保護ドメインに対する通常操作1に変更した.
AID_SEM |
割付け可能なセマフォIDの数の指定〔SD〕【NGKI1469】 |
【静的API】
AID_SEM(uint_t nosem)
【パラメータ】
uint_t |
nosem |
割付け可能なセマフォIDの数 |
【エラーコード】
E_RSATR |
予約属性 |
【機能】
nosemで指定した数のセマフォIDを,セマフォを生成するサービスコールによって割付け可能なセマフォIDとして確保する【NGKI1471】.
nosemは整数定数式パラメータである【NGKI1472】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,AID_SEMをサポートする【ASPS0211】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,AID_SEMをサポートする【HRPS0212】.
SAC_SEM |
セマフォのアクセス許可ベクタの設定〔SP〕【NGKI1473】 |
sac_sem |
セマフォのアクセス許可ベクタの設定〔TPD〕【NGKI1474】 |
【静的API】
SAC_SEM(ID semid, { ACPTN acptn1, ACPTN acptn2,
ACPTN acptn3, ACPTN acptn4 })
【C言語API】
ER ercd = sac_sem(ID semid, const ACVCT *p_acvct)
【パラメータ】
ID |
semid |
対象セマフォの識別名(SAC_SEMの場合)またはID番号(sac_semの場合) |
|
ACVCT * |
p_acvct |
アクセス許可ベクタを入れたパケットへのポインタ(sac_semの場合) |
*アクセス許可ベクタ(パケットの内容)
ACPTN |
acptn1 |
通常操作1のアクセス許可パターン |
|
ACPTN |
acptn2 |
通常操作2のアクセス許可パターン |
|
ACPTN |
acptn3 |
管理操作のアクセス許可パターン |
|
ACPTN |
acptn4 |
参照操作のアクセス許可パターン |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_RSATR |
予約属性 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
semidで指定したセマフォ(対象セマフォ)のアクセス許可ベクタ(4つのアクセス許可パターンの組)を,各パラメータで指定した値に設定する【NGKI1485】.
静的APIにおいては,semidはオブジェクト識別名,acptn1〜acptn4は整数定数式パラメータである【NGKI1486】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,sac_semをサポートする【HRPS0181】.
del_sem |
セマフォの削除〔TD〕【NGKI1487】 |
【C言語API】
ER ercd = del_sem(ID semid)
【パラメータ】
ID |
semid |
対象セマフォのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
semidで指定したセマフォ(対象セマフォ)を削除する.具体的な振舞いは以下の通り.
対象セマフォの登録が解除され,そのセマフォIDが未使用の状態に戻される【NGKI1494】.また,対象セマフォの待ち行列につながれたタスクは,待ち行列の先頭のタスクから順に待ち解除される【NGKI1495】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1496】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,del_semをサポートする【ASPS0123】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,del_semをサポートする【HRPS0182】.
sig_sem |
セマフォの資源の返却〔TI〕【NGKI3533】 |
【C言語API】
ER ercd = sig_sem(ID semid)
【パラメータ】
ID |
semid |
対象セマフォのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_QOVR |
キューイングオーバフロー |
【機能】
semidで指定したセマフォ(対象セマフォ)に資源を返却する.具体的な振舞いは以下の通り.
対象セマフォの待ち行列にタスクが存在する場合には,待ち行列の先頭のタスクが待ち解除される【NGKI1505】.この時,待ち解除されたタスクが資源を獲得したことになるため,対象セマフォの資源数は変化しない【NGKI1506】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1507】.
待ち行列にタスクが存在しない場合には,対象セマフォの資源数に1が加えられる【NGKI1508】.資源数に1を加えるとそのセマフォの最大資源数を越える場合には,E_QOVRエラーとなる【NGKI1509】.
wai_sem |
セマフォの資源の獲得〔T〕【NGKI1510】 |
pol_sem |
セマフォの資源の獲得(ポーリング)〔T〕【NGKI1511】 |
twai_sem |
セマフォの資源の獲得(タイムアウト付き)〔T〕【NGKI1512】 |
【C言語API】
ER ercd = wai_sem(ID semid)
ER ercd = pol_sem(ID semid)
ER ercd = twai_sem(ID semid, TMO tmout)
【パラメータ】
ID |
semid |
対象セマフォのID番号 |
|
TMO |
tmout |
タイムアウト時間(twai_semの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(wai_semを除く)【NGKI1521】 |
|
E_RLWAI |
待ち状態の強制解除(pol_semを除く)【NGKI1522】 |
|
E_RASTER |
タスクの終了要求(pol_semを除く)【NGKI3457】 |
|
E_DLT |
待ちオブジェクトの削除または再初期化(pol_semを除く)【NGKI1523】 |
【機能】
semidで指定したセマフォ(対象セマフォ)から資源を獲得する.具体的な振舞いは以下の通り.
対象セマフォの資源数が1以上の場合には,資源数から1が減ぜられる【NGKI1524】.資源数が0の場合には,自タスクはセマフォの資源獲得待ち状態となり,対象セマフォの待ち行列につながれる【NGKI1525】.
ini_sem |
セマフォの再初期化〔T〕【NGKI1526】 |
【C言語API】
ER ercd = ini_sem(ID semid)
【パラメータ】
ID |
semid |
対象セマフォのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
semidで指定したセマフォ(対象セマフォ)を再初期化する.具体的な振舞いは以下の通り.
対象セマフォの資源数は,初期資源数に初期化される【NGKI1532】.また,対象セマフォの待ち行列につながれたタスクは,待ち行列の先頭のタスクから順に待ち解除される【NGKI1533】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1534】.
【使用上の注意】
セマフォを再初期化した場合に,アプリケーションとの整合性を保つのは,アプリケーションの責任である.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていないサービスコールである.
ref_sem |
セマフォの状態参照〔T〕【NGKI1535】 |
【C言語API】
ER ercd = ref_sem(ID semid, T_RSEM *pk_rsem)
【パラメータ】
ID |
semid |
対象セマフォのID番号 |
|
T_RSEM * |
pk_rsem |
セマフォの現在状態を入れるパケットへのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
*セマフォの現在状態(パケットの内容)
ID |
wtskid |
セマフォの待ち行列の先頭のタスクのID番号 |
|
uint_t |
semcnt |
セマフォの資源数 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
【機能】
semidで指定したセマフォ(対象セマフォ)の現在状態を参照する.参照した現在状態は,pk_rsemで指定したパケットに返される【NGKI1542】.
対象セマフォの待ち行列にタスクが存在しない場合,wtskidにはTSK_NONE(=0)が返る【NGKI1543】.
【使用上の注意】
ref_semはデバッグ時向けの機能であり,その他の目的に使用することは推奨しない.これは,ref_semを呼び出し,対象セマフォの現在状態を参照した直後に割込みが発生した場合,ref_semから戻ってきた時には対象セマフォの状態が変化している可能性があるためである.また,マルチプロセッサ対応カーネルでは,対象セマフォの現在状態を参照した直後に,他のプロセッサで実行されている処理により対象セマフォの状態が変化する場合もある.
4.4.2 イベントフラグ
イベントフラグは,イベントの発生の有無を表すビットの集合(ビットパターン)を介して,イベント通知を行うための同期・通信オブジェクトである.イベントが発生している状態を1,発生していない状態を0とし,ビットパターンにより複数のイベントの発生の有無を表す【NGKI1544】.イベントフラグは,イベントフラグIDと呼ぶID番号によって識別する【NGKI1545】.
1つまたは複数のビットを1にする(セットする)ことを,イベントフラグをセットするといい,0にする(クリアする)ことを,イベントフラグをクリアするという.イベントフラグによりイベントを通知する側のタスクは,イベントフラグをセットまたはクリアすることで,イベントの発生を通知する.
イベントフラグによりイベントの通知を受ける側のタスクは,待ちビットパターンと待ちモードにより,どのビットがセットされるのを待つかを指定する.待ちモードにTWF_ORW(=0x01U)を指定した場合,待ちビットパターンに含まれるいずれかのビットがセットされるのを待つ【NGKI1546】.待ちモードにTWF_ANDW(=0x02U)を指定した場合,待ちビットパターンに含まれるすべてのビットがセットされるのを待つ【NGKI1547】.この条件を,イベントフラグの待ち解除の条件と呼ぶ.
各イベントフラグが持つ情報は次の通り【NGKI1548】.
-
イベントフラグ属性
-
ビットパターン(の現在値)
-
待ち行列(イベントフラグ待ち状態のタスクのキュー)
-
初期ビットパターン
-
アクセス許可ベクタ(保護機能対応カーネルの場合)
-
属する保護ドメイン(保護機能対応カーネルの場合)
-
属するクラス(マルチプロセッサ対応カーネルの場合)
待ち行列は,イベントフラグが指定した待ち解除の条件を満たすまで待っている状態(イベントフラグ待ち状態)のタスクがつながれているキューである.待ち行列につながれたタスクの待ち解除は,待ち解除の条件を満たした中で,待ち行列の前方につながれたものから順に行われる(〔NGKI0216〕に該当)【NGKI1549】.
イベントフラグの初期ビットパターンは,イベントフラグを生成または再初期化した際の,ビットパターンの初期値である.
イベントフラグ属性には,次の属性を指定することができる【NGKI1550】.
TA_TPRI |
0x01U |
待ち行列をタスクの優先度順にする |
|
TA_WMUL |
0x02U |
複数のタスクが待つのを許す |
|
TA_CLR |
0x04U |
タスクの待ち解除時にイベントフラグをクリアする |
TA_TPRIを指定しない場合,待ち行列はFIFO順になる【NGKI1551】.TA_WMULを指定しない場合,1つのイベントフラグに複数のタスクが待つことを禁止する【NGKI1552】.
TA_CLRを指定した場合,タスクの待ち解除時に,イベントフラグのビットパターンを0にクリアする【NGKI1553】.TA_CLRを指定しない場合,タスクの待ち解除時にイベントフラグをクリアしない【NGKI1554】.
イベントフラグ機能に用いるデータ型は次の通り.
FLGPTN |
イベントフラグのビットパターン(符号無し整数,uint_tに定義)【NGKI1555】 |
イベントフラグ機能に関連するカーネル構成マクロは次の通り.
TBIT_FLGPTN |
イベントフラグのビット数(FLGPTNの有効ビット数)【NGKI1556】 |
TNUM_FLGID |
登録できるイベントフラグの数(動的生成対応でないカーネルでは,静的APIによって登録されたイベントフラグの数に一致)【NGKI1557】 |
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,イベントフラグのビット数(TBIT_FLGPTN)は16以上である【ASPS0124】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,イベントフラグのビット数(TBIT_FLGPTN)は16以上である【FMPS0115】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,イベントフラグのビット数(TBIT_FLGPTN)は16以上である【HRPS0115】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,イベントフラグのビット数(TBIT_FLGPTN)は16以上である【HRMPS0105】.
【μITRON4.0仕様との関係】
TNUM_FLGIDは,μITRON4.0仕様に規定されていないカーネル構成マクロである.
CRE_FLG |
イベントフラグの生成〔S〕【NGKI1558】 |
acre_flg |
イベントフラグの生成〔TD〕【NGKI1559】 |
【静的API】
CRE_FLG(ID flgid, { ATR flgatr, FLGPTN iflgptn })
【C言語API】
ER_ID flgid = acre_flg(const T_CFLG *pk_cflg)
【パラメータ】
ID |
flgid |
生成するイベントフラグの識別名(CRE_FLGの場合) |
|
T_CFLG * |
pk_cflg |
イベントフラグの生成情報を入れたパケットへのポインタ(acre_flgの場合) |
*イベントフラグの生成情報(パケットの内容)
ATR |
flgatr |
イベントフラグ属性 |
|
FLGPTN |
iflgptn |
イベントフラグの初期ビットパターン |
【リターンパラメータ】
ER_ID |
flgid |
生成されたイベントフラグのID番号(正の値)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_RSATR |
予約属性 |
|
E_PAR |
パラメータエラー |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_NOID |
ID番号不足 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
各パラメータで指定したイベントフラグの生成情報に従って,イベントフラグを生成する【NGKI5190】.生成されたイベントフラグのビットパターンは初期ビットパターンに,待ち行列は空の状態に初期化される【NGKI1570】.
静的APIにおいては,flgidはオブジェクト識別名,flgatrとiflgptnは整数定数式パラメータである【NGKI1571】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,acre_flgをサポートする【ASPS0126】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,acre_flgをサポートする【HRPS0183】.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
アクセス権を制御するためのアクセスの種別を,保護ドメインに対する通常操作1に変更した.
AID_FLG |
割付け可能なイベントフラグIDの数の指定〔SD〕【NGKI1572】 |
【静的API】
AID_FLG(uint_t noflg)
【パラメータ】
uint_t |
noflg |
割付け可能なイベントフラグIDの数 |
【エラーコード】
E_RSATR |
予約属性 |
【機能】
noflgで指定した数のイベントフラグIDを,イベントフラグを生成するサービスコールによって割付け可能なイベントフラグIDとして確保する【NGKI1574】.
noflgは整数定数式パラメータである【NGKI1575】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,AID_FLGをサポートする【ASPS0212】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,AID_FLGをサポートする【HRPS0213】.
SAC_FLG |
イベントフラグのアクセス許可ベクタの設定〔SP〕【NGKI1576】 |
sac_flg |
イベントフラグのアクセス許可ベクタの設定〔TPD〕【NGKI1577】 |
【静的API】
SAC_FLG(ID flgid, { ACPTN acptn1, ACPTN acptn2,
ACPTN acptn3, ACPTN acptn4 })
【C言語API】
ER ercd = sac_flg(ID flgid, const ACVCT *p_acvct)
【パラメータ】
ID |
flgid |
対象イベントフラグの識別名(SAC_FLGの場合)またはID番号(sac_flgの場合) |
|
ACVCT * |
p_acvct |
アクセス許可ベクタを入れたパケットへのポインタ(sac_flgの場合) |
*アクセス許可ベクタ(パケットの内容)
ACPTN |
acptn1 |
通常操作1のアクセス許可パターン |
|
ACPTN |
acptn2 |
通常操作2のアクセス許可パターン |
|
ACPTN |
acptn3 |
管理操作のアクセス許可パターン |
|
ACPTN |
acptn4 |
参照操作のアクセス許可パターン |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_RSATR |
予約属性 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)のアクセス許可ベクタ(4つのアクセス許可パターンの組)を,各パラメータで指定した値に設定する【NGKI1588】.
静的APIにおいては,flgidはオブジェクト識別名,acptn1〜acptn4は整数定数式パラメータである【NGKI1589】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,sac_flgをサポートする【HRPS0184】.
del_flg |
イベントフラグの削除〔TD〕【NGKI1590】 |
【C言語API】
ER ercd = del_flg(ID flgid)
【パラメータ】
ID |
flgid |
対象イベントフラグのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)を削除する.具体的な振舞いは以下の通り.
対象イベントフラグの登録が解除され,そのイベントフラグIDが未使用の状態に戻される【NGKI1597】.また,対象イベントフラグの待ち行列につながれたタスクは,待ち行列の先頭のタスクから順に待ち解除される【NGKI1598】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1599】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,del_flgをサポートする【ASPS0129】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,del_flgをサポートする【HRPS0185】.
set_flg |
イベントフラグのセット〔TI〕【NGKI3534】 |
【C言語API】
ER ercd = set_flg(ID flgid, FLGPTN setptn)
【パラメータ】
ID |
flgid |
対象イベントフラグのID番号 |
|
FLGPTN |
setptn |
セットするビットパターン |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)のsetptnで指定したビットをセットする.具体的な振舞いは以下の通り.
対象イベントフラグのビットパターンは,それまでの値とsetptnで指定した値のビット毎論理和(C言語の"|")に更新される【NGKI1608】.対象イベントフラグの待ち行列にタスクが存在する場合には,待ち解除の条件を満たしたタスクが,待ち行列の前方につながれたものから順に待ち解除される【NGKI1609】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1610】.
【補足説明】
対象イベントフラグがTA_CLR属性である場合には,待ち解除の条件を満たしたタスクを1つ待ち解除した時点で,対象イベントフラグのビットパターンが0にクリアされるため,他のタスクが待ち解除されることはない.
clr_flg |
イベントフラグのクリア〔T〕【NGKI1611】 |
【C言語API】
ER ercd = clr_flg(ID flgid, FLGPTN clrptn)
【パラメータ】
ID |
flgid |
対象イベントフラグのID番号 |
|
FLGPTN |
clrptn |
クリアするビットパターン(クリアしないビットを1,クリアするビットを0とする) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)のclrptnで指定したビットをクリアする.対象イベントフラグのビットパターンは,それまでの値とclrptnで指定した値のビット毎論理積(C言語の"&")に更新される【NGKI1617】.
wai_flg |
イベントフラグ待ち〔T〕【NGKI1618】 |
pol_flg |
イベントフラグ待ち(ポーリング)〔T〕【NGKI1619】 |
twai_flg |
イベントフラグ待ち(タイムアウト付き)〔T〕【NGKI1620】 |
【C言語API】
ER ercd = wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
ER ercd = pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
ER ercd = twai_flg(ID flgid, FLGPTN waiptn,
MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
【パラメータ】
ID |
flgid |
対象イベントフラグのID番号 |
|
FLGPTN |
waiptn |
待ちビットパターン |
|
MODE |
wfmode |
待ちモード |
|
FLGPTN * |
p_flgptn |
待ち解除時のビットパターンを入れるメモリ領域へのポインタ |
|
TMO |
tmout |
タイムアウト時間(twai_flgの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
|
FLGPTN |
flgptn |
待ち解除時のビットパターン |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_ILUSE |
サービスコール不正使用 |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(wai_flgを除く)【NGKI1633】 |
|
E_RLWAI |
待ち状態の強制解除(pol_flgを除く)【NGKI1634】 |
|
E_RASTER |
タスクの終了要求(pol_flgを除く)【NGKI3458】 |
|
E_DLT |
待ちオブジェクトの削除または再初期化(pol_flgを除く)【NGKI1635】 |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)が,waiptnとwfmodeで指定した待ち解除の条件を満たすのを待つ.具体的な振舞いは以下の通り.
対象イベントフラグが,waiptnとwfmodeで指定した待ち解除の条件を満たしている場合には,対象イベントフラグのビットパターンの現在値がp_flgptnが指すメモリ領域に返される【NGKI1636】.対象イベントフラグがTA_CLR属性である場合には,対象イベントフラグのビットパターンが0にクリアされる【NGKI1637】.
待ち解除の条件を満たしていない場合には,自タスクはイベントフラグ待ち状態となり,対象イベントフラグの待ち行列につながれる【NGKI1638】.
ini_flg |
イベントフラグの再初期化〔T〕【NGKI1639】 |
【C言語API】
ER ercd = ini_flg(ID flgid)
【パラメータ】
ID |
flgid |
対象イベントフラグのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)を再初期化する.具体的な振舞いは以下の通り.
対象イベントフラグのビットパターンは,初期ビットパターンに初期化される【NGKI1645】.また,対象イベントフラグの待ち行列につながれたタスクは,待ち行列の先頭のタスクから順に待ち解除される【NGKI1646】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1647】.
【使用上の注意】
イベントフラグを再初期化した場合に,アプリケーションとの整合性を保つのは,アプリケーションの責任である.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていないサービスコールである.
ref_flg |
イベントフラグの状態参照〔T〕【NGKI1648】 |
【C言語API】
ER ercd = ref_flg(ID flgid, T_RFLG *pk_rflg)
【パラメータ】
ID |
flgid |
対象イベントフラグのID番号 |
|
T_RFLG * |
pk_rflg |
イベントフラグの現在状態を入れるパケットへのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
*イベントフラグの現在状態(パケットの内容)
ID |
wtskid |
イベントフラグの待ち行列の先頭のタスクのID番号 |
|
uint_t |
flgptn |
イベントフラグのビットパターン |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
【機能】
flgidで指定したイベントフラグ(対象イベントフラグ)の現在状態を参照する.参照した現在状態は,pk_rflgで指定したパケットに返される【NGKI1655】.
対象イベントフラグの待ち行列にタスクが存在しない場合,wtskidにはTSK_NONE(=0)が返る【NGKI1656】.
【使用上の注意】
ref_flgはデバッグ時向けの機能であり,その他の目的に使用することは推奨しない.これは,ref_flgを呼び出し,対象イベントフラグの現在状態を参照した直後に割込みが発生した場合,ref_flgから戻ってきた時には対象イベントフラグの状態が変化している可能性があるためである.また,マルチプロセッサ対応カーネルでは,対象イベントフラグの現在状態を参照した直後に,他のプロセッサで実行されている処理により対象イベントフラグの状態が変化する場合もある.
4.4.3 データキュー
データキューは,1ワードのデータをメッセージとして,FIFO順で送受信するための同期・通信オブジェクトである.より大きいサイズのメッセージを送受信したい場合には,メッセージを置いたメモリ領域へのポインタを1ワードのデータとして送受信する方法がある.データキューは,データキューIDと呼ぶID番号によって識別する【NGKI1657】.
各データキューが持つ情報は次の通り【NGKI1658】.
-
データキュー属性
-
データキュー管理領域
-
送信待ち行列(データキューへの送信待ち状態のタスクのキュー)
-
受信待ち行列(データキューからの受信待ち状態のタスクのキュー)
-
アクセス許可ベクタ(保護機能対応カーネルの場合)
-
属する保護ドメイン(保護機能対応カーネルの場合)
-
属するクラス(マルチプロセッサ対応カーネルの場合)
データキュー管理領域は,データキューに送信されたデータを,送信された順に格納しておくためのメモリ領域である.データキュー生成時に,データキュー管理領域に格納できるデータ数を0とすることで,データキュー管理領域のサイズを0とすることができる【NGKI1659】.
保護機能対応カーネルにおいて,データキュー管理領域は,カーネルの管理領域として扱われる【NGKI1660】.
送信待ち行列は,データキューに対してデータが送信できるまで待っている状態(データキューへの送信待ち状態)のタスクが,データを送信できる順序でつながれているキューである.また,受信待ち行列は,データキューからデータが受信できるまで待っている状態(データキューからの受信待ち状態)のタスクが,データを受信できる順序でつながれているキューである.
データキュー属性には,次の属性を指定することができる【NGKI1661】.
TA_TPRI |
0x01U |
送信待ち行列をタスクの優先度順にする |
TA_TPRIを指定しない場合,送信待ち行列はFIFO順になる【NGKI1662】.受信待ち行列は,FIFO順に固定されている【NGKI1663】.
データキュー機能に関連するカーネル構成マクロは次の通り.
TNUM_DTQID |
登録できるデータキューの数(動的生成対応でないカーネルでは,静的APIによって登録されたデータキューの数に一致)【NGKI1664】 |
【μITRON4.0仕様との関係】
TNUM_DTQIDは,μITRON4.0仕様に規定されていないカーネル構成マクロである.
CRE_DTQ |
データキューの生成〔S〕【NGKI1665】 |
acre_dtq |
データキューの生成〔TD〕【NGKI1666】 |
【静的API】
CRE_DTQ(ID dtqid, { ATR dtqatr, uint_t dtqcnt, void *dtqmb })
※ dtqmbの記述は省略することができる【NGKI3901】.
【C言語API】
ER_ID dtqid = acre_dtq(const T_CDTQ *pk_cdtq)
【パラメータ】
ID |
dtqid |
生成するデータキューの識別名(CRE_DTQの場合) |
|
T_CDTQ * |
pk_cdtq |
データキューの生成情報を入れたパケットへのポインタ(acre_dtqの場合) |
*データキューの生成情報(パケットの内容)
ATR |
dtqatr |
データキュー属性 |
|
uint_t |
dtqcnt |
データキュー管理領域に格納できるデータ数 |
|
void * |
dtqmb |
データキュー管理領域の先頭番地 |
【リターンパラメータ】
ER_ID |
dtqid |
生成されたデータキューのID番号(正の値)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_RSATR |
予約属性 |
|
E_NOSPT |
未サポート機能 |
|
E_PAR |
パラメータエラー |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_NOID |
ID番号不足 |
|
E_NOMEM |
メモリ不足 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
各パラメータで指定したデータキューの生成情報に従って,データキューを生成する【NGKI5191】.dtqcntとdtqmbからデータキュー管理領域が設定され,格納されているデータがない状態に初期化される【NGKI1678】.また,送信待ち行列と受信待ち行列は,空の状態に初期化される【NGKI1679】.
静的APIにおいては,dtqidはオブジェクト識別名,dtqatrとdtqcntは整数定数式パラメータ,dtqmbは一般定数式パラメータである【NGKI1680】.コンフィギュレータは,静的APIのメモリ不足(E_NOMEM)エラーを検出することができない【NGKI1681】.
dtqmbにNULLを指定するか,静的APIにおいてdtqmbの記述を省略した場合,dtqcntで指定した数のデータを格納できるデータキュー管理領域が,コンフィギュレータまたはカーネルにより確保される【NGKI1682】.
dtqmbにNULL以外を指定した場合,dtqmbを先頭番地とするデータキュー管理領域は,アプリケーションで確保しておく必要がある【NGKI1683】.データキュー管理領域をアプリケーションで確保するために,次のマクロを用意している【NGKI1684】.
TSZ_DTQMB(dtqcnt) |
dtqcntで指定した数のデータを格納できるデータキュー管理領域のサイズ(バイト数) |
|
TCNT_DTQMB(dtqcnt) |
dtqcntで指定した数のデータを格納できるデータキュー管理領域を確保するために必要なMB_T型の配列の要素数 |
これらを用いて,dtqcntで指定した数のデータを格納できるデータキュー管理領域を確保する方法は次の通り【NGKI1685】.
MB_T <データキュー管理領域の変数名>[TCNT_DTQMB(dtqcnt)];
この時,dtqmbには<データキュー管理領域の変数名>を指定する【NGKI1686】.
この方法に従わず,dtqmbにターゲット定義の制約に合致しない先頭番地を指定した時には,E_PARエラーとなる【NGKI1687】.また,保護機能対応カーネルにおいて,dtqmbで指定したデータキュー管理領域がカーネル専用のメモリオブジェクトに含まれない場合,E_OBJエラーとなる【NGKI1688】.
なお,dtqmbにNULL以外を指定できないカーネルでは,TSZ_DTQMBとTCNT_DTQMBは用意していない【NGKI5179】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,dtqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【ASPS0132】.
ASP3カーネルの動的生成機能拡張パッケージでは,acre_dtqをサポートする【ASPS0133】.acre_dtqに対しては,dtqmbにNULL以外を指定できないという制限はない【ASPS0134】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,dtqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【FMPS0121】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,dtqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【HRPS0121】.
HRP3カーネルの動的生成機能拡張パッケージでは,acre_dtqをサポートする【HRPS0186】.acre_dtqに対しては,dtqmbにNULL以外を指定できないという制限はない【HRPS0187】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,dtqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【HRMPS0106】.
【μITRON4.0仕様との関係】
μITRON4.0/PX仕様にあわせて,データキューの生成情報の最後のパラメータを,dtq(データキュー領域の先頭番地)から,dtqmb(データキュー管理領域の先頭番地)に改名した.また,TSZ_DTQをTSZ_DTQMBに改名した.
TCNT_DTQMBを新設し,データキュー管理領域をアプリケーションで確保する方法を規定した.
【μITRON4.0/PX仕様,TOPPERS新世代カーネル統合仕様との関係】
アクセス権を制御するためのアクセスの種別を,保護ドメインに対する通常操作1に変更した.
AID_DTQ |
割付け可能なデータキューIDの数の指定〔SD〕【NGKI1689】 |
【静的API】
AID_DTQ(uint_t nodtq)
【パラメータ】
uint_t |
nodtq |
割付け可能なデータキューIDの数 |
【エラーコード】
E_RSATR |
予約属性 |
【機能】
nodtqで指定した数のデータキューIDを,データキューを生成するサービスコールによって割付け可能なデータキューIDとして確保する【NGKI1691】.
nodtqは整数定数式パラメータである【NGKI1692】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,AID_DTQをサポートする【ASPS0213】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,AID_DTQをサポートする【HRPS0214】.
SAC_DTQ |
データキューのアクセス許可ベクタの設定〔SP〕【NGKI1693】 |
sac_dtq |
データキューのアクセス許可ベクタの設定〔TPD〕【NGKI1694】 |
【静的API】
SAC_DTQ(ID dtqid, { ACPTN acptn1, ACPTN acptn2,
ACPTN acptn3, ACPTN acptn4 })
【C言語API】
ER ercd = sac_dtq(ID dtqid, const ACVCT *p_acvct)
【パラメータ】
ID |
dtqid |
対象データキューの識別名(SAC_DTQの場合)またはID番号(sac_dtqの場合) |
|
ACVCT * |
p_acvct |
アクセス許可ベクタを入れたパケットへのポインタ(sac_dtqの場合) |
*アクセス許可ベクタ(パケットの内容)
ACPTN |
acptn1 |
通常操作1のアクセス許可パターン |
|
ACPTN |
acptn2 |
通常操作2のアクセス許可パターン |
|
ACPTN |
acptn3 |
管理操作のアクセス許可パターン |
|
ACPTN |
acptn4 |
参照操作のアクセス許可パターン |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_RSATR |
予約属性 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
dtqidで指定したデータキュー(対象データキュー)のアクセス許可ベクタ(4つのアクセス許可パターンの組)を,各パラメータで指定した値に設定する【NGKI1705】.
静的APIにおいては,dtqidはオブジェクト識別名,acptn1〜acptn4は整数定数式パラメータである【NGKI1706】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,sac_dtqをサポートする【HRPS0188】.
del_dtq |
データキューの削除〔TD〕【NGKI1707】 |
【C言語API】
ER ercd = del_dtq(ID dtqid)
【パラメータ】
ID |
dtqid |
対象データキューのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
dtqidで指定したデータキュー(対象データキュー)を削除する.具体的な振舞いは以下の通り.
対象データキューの登録が解除され,そのデータキューIDが未使用の状態に戻される【NGKI1714】.また,対象データキューの送信待ち行列と受信待ち行列につながれたタスクは,それぞれの待ち行列の先頭のタスクから順に待ち解除される【NGKI1715】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1716】.
データキューの生成時に,データキュー管理領域がカーネルによって確保された場合は,そのメモリ領域が解放される【NGKI1717】.
【補足説明】
送信待ち行列と受信待ち行列の両方にタスクがつながれていることはないため,別の待ち行列で待っていたタスクの間の待ち解除の順序は,規定する必要がない.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,del_dtqをサポートする【ASPS0137】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,del_dtqをサポートする【HRPS0189】.
snd_dtq |
データキューへの送信〔T〕【NGKI1718】 |
psnd_dtq |
データキューへの送信(ポーリング)〔TI〕【NGKI3535】 |
tsnd_dtq |
データキューへの送信(タイムアウト付き)〔T〕【NGKI1721】 |
【C言語API】
ER ercd = snd_dtq(ID dtqid, intptr_t data)
ER ercd = psnd_dtq(ID dtqid, intptr_t data)
ER ercd = tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
【パラメータ】
ID |
dtqid |
対象データキューのID番号 |
|
intptr_t |
data |
送信データ |
|
TMO |
tmout |
タイムアウト時間(tsnd_dtqの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(snd_dtqを除く)【NGKI1731】 |
|
E_RLWAI |
待ち状態の強制解除(psnd_dtqを除く)【NGKI1732】 |
|
E_RASTER |
タスクの終了要求(psnd_dtqを除く)【NGKI3459】 |
|
E_DLT |
待ちオブジェクトの削除または再初期化(psnd_dtqを除く)【NGKI1733】 |
【機能】
dtqidで指定したデータキュー(対象データキュー)に,dataで指定したデータを送信する.具体的な振舞いは以下の通り.
対象データキューの受信待ち行列にタスクが存在する場合には,受信待ち行列の先頭のタスクが,dataで指定したデータを受信し,待ち解除される【NGKI1734】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1735】.
対象データキューの受信待ち行列にタスクが存在せず,データキュー管理領域にデータを格納するスペースがある場合には,dataで指定したデータが,FIFO順でデータキュー管理領域に格納される【NGKI1736】.
対象データキューの受信待ち行列にタスクが存在せず,データキュー管理領域にデータを格納するスペースがない場合には,自タスクはデータキューへの送信待ち状態となり,対象データキューの送信待ち行列につながれる【NGKI1737】.
fsnd_dtq |
データキューへの強制送信〔TI〕【NGKI3536】 |
【C言語API】
ER ercd = fsnd_dtq(ID dtqid, intptr_t data)
【パラメータ】
ID |
dtqid |
対象データキューのID番号 |
|
intptr_t |
data |
送信データ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_ILUSE |
サービスコール不正使用 |
【機能】
dtqidで指定したデータキュー(対象データキュー)に,dataで指定したデータを強制送信する.具体的な振舞いは以下の通り.
対象データキューの受信待ち行列にタスクが存在する場合には,受信待ち行列の先頭のタスクが,dataで指定したデータを受信し,待ち解除される【NGKI1747】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1748】.
対象データキューの受信待ち行列にタスクが存在せず,データキュー管理領域にデータを格納するスペースがある場合には,dataで指定したデータが,FIFO順でデータキュー管理領域に格納される【NGKI1749】.
対象データキューの受信待ち行列にタスクが存在せず,データキュー管理領域にデータを格納するスペースがない場合には,データキュー管理領域の先頭に格納されたデータを削除し,空いたスペースを用いて,dataで指定したデータが,FIFO順でデータキュー管理領域に格納される【NGKI1750】.
rcv_dtq |
データキューからの受信〔T〕【NGKI1751】 |
prcv_dtq |
データキューからの受信(ポーリング)〔T〕【NGKI1752】 |
trcv_dtq |
データキューからの受信(タイムアウト付き)〔T〕【NGKI1753】 |
【C言語API】
ER ercd = rcv_dtq(ID dtqid, intptr_t *p_data)
ER ercd = prcv_dtq(ID dtqid, intptr_t *p_data)
ER ercd = trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout)
【パラメータ】
ID |
dtqid |
対象データキューのID番号 |
|
intptr_t * |
p_data |
受信データを入れるメモリ領域へのポインタ |
|
TMO |
tmout |
タイムアウト時間(trcv_dtqの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
|
intptr_t |
data |
受信データ |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(rcv_dtqを除く)【NGKI1763】 |
|
E_RLWAI |
待ち状態の強制解除(prcv_dtqを除く)【NGKI1764】 |
|
E_RASTER |
タスクの終了要求(prcv_dtqを除く)【NGKI3460】 |
|
E_DLT |
待ちオブジェクトの削除または再初期化(prcv_dtqを除く)【NGKI1765】 |
【機能】
dtqidで指定したデータキュー(対象データキュー)からデータを受信する.データの受信に成功した場合,受信したデータはp_dataが指すメモリ領域に返される【NGKI3421】.具体的な振舞いは以下の通り.
対象データキューのデータキュー管理領域にデータが格納されている場合には,データキュー管理領域の先頭に格納されたデータを受信する【NGKI1766】.また,送信待ち行列にタスクが存在する場合には,送信待ち行列の先頭のタスクの送信データが,FIFO順でデータキュー管理領域に格納され,そのタスクは待ち解除される【NGKI1767】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1768】.
対象データキューのデータキュー管理領域にデータが格納されておらず,送信待ち行列にタスクが存在する場合には,送信待ち行列の先頭のタスクの送信データを受信する【NGKI1769】.送信待ち行列の先頭のタスクは,待ち解除される【NGKI3422】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1770】.
対象データキューのデータキュー管理領域にデータが格納されておらず,送信待ち行列にタスクが存在しない場合には,自タスクはデータキューからの受信待ち状態となり,対象データキューの受信待ち行列につながれる【NGKI1771】.
ini_dtq |
データキューの再初期化〔T〕【NGKI1772】 |
【C言語API】
ER ercd = ini_dtq(ID dtqid)
【パラメータ】
ID |
dtqid |
対象データキューのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
dtqidで指定したデータキュー(対象データキュー)を再初期化する.具体的な振舞いは以下の通り.
対象データキューのデータキュー管理領域は,格納されているデータがない状態に初期化される【NGKI1778】.また,対象データキューの送信待ち行列と受信待ち行列につながれたタスクは,それぞれの待ち行列の先頭のタスクから順に待ち解除される【NGKI1779】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1780】.
【補足説明】
送信待ち行列と受信待ち行列の両方にタスクがつながれていることはないため,別の待ち行列で待っていたタスクの間の待ち解除の順序は,規定する必要がない.
【使用上の注意】
データキューを再初期化した場合に,アプリケーションとの整合性を保つのは,アプリケーションの責任である.
【μITRON4.0仕様との関係】
μITRON4.0仕様に定義されていないサービスコールである.
ref_dtq |
データキューの状態参照〔T〕【NGKI1781】 |
【C言語API】
ER ercd = ref_dtq(ID dtqid, T_RDTQ *pk_rdtq)
【パラメータ】
ID |
dtqid |
対象データキューのID番号 |
|
T_RDTQ * |
pk_rdtq |
データキューの現在状態を入れるパケットへのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
*データキューの現在状態(パケットの内容)
ID |
stskid |
データキューの送信待ち行列の先頭のタスクのID番号 |
|
ID |
rtskid |
データキューの受信待ち行列の先頭のタスクのID番号 |
|
uint_t |
sdtqcnt |
データキュー管理領域に格納されているデータの数 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
【機能】
dtqidで指定したデータキュー(対象データキュー)の現在状態を参照する.参照した現在状態は,pk_rdtqで指定したパケットに返される【NGKI1788】.
対象データキューの送信待ち行列にタスクが存在しない場合,stskidにはTSK_NONE(=0)が返る【NGKI1789】.また,受信待ち行列にタスクが存在しない場合,rtskidにはTSK_NONE(=0)が返る【NGKI1790】.
【使用上の注意】
ref_dtqはデバッグ時向けの機能であり,その他の目的に使用することは推奨しない.これは,ref_dtqを呼び出し,対象データキューの現在状態を参照した直後に割込みが発生した場合,ref_dtqから戻ってきた時には対象データキューの状態が変化している可能性があるためである.また,マルチプロセッサ対応カーネルでは,対象データキューの現在状態を参照した直後に,他のプロセッサで実行されている処理により対象データキューの状態が変化する場合もある.
4.4.4 優先度データキュー
優先度データキューは,1ワードのデータをメッセージとして,データの優先度順で送受信するための同期・通信オブジェクトである.より大きいサイズのメッセージを送受信したい場合には,メッセージを置いたメモリ領域へのポインタを1ワードのデータとして送受信する方法がある.優先度データキューは,優先度データキューIDと呼ぶID番号によって識別する【NGKI1791】.
各優先度データキューが持つ情報は次の通り【NGKI1792】.
-
優先度データキュー属性
-
優先度データキュー管理領域
-
送信待ち行列(優先度データキューへの送信待ち状態のタスクのキュー)
-
受信待ち行列(優先度データキューからの受信待ち状態のタスクのキュー)
-
送信できるデータ優先度の最大値
-
アクセス許可ベクタ(保護機能対応カーネルの場合)
-
属する保護ドメイン(保護機能対応カーネルの場合)
-
属するクラス(マルチプロセッサ対応カーネルの場合)
優先度データキュー管理領域は,優先度データキューに送信されたデータを,データの優先度順に格納しておくためのメモリ領域である.優先度データキュー生成時に,優先度データキュー管理領域に格納できるデータ数を0とすることで,優先度データキュー管理領域のサイズを0とすることができる【NGKI1793】.
保護機能対応カーネルにおいて,優先度データキュー管理領域は,カーネルの管理領域として扱われる【NGKI1794】.
送信待ち行列は,優先度データキューに対してデータが送信できるまで待っている状態(優先度データキューへの送信待ち状態)のタスクが,データを送信できる順序でつながれているキューである.また,受信待ち行列は,優先度データキューからデータが受信できるまで待っている状態(優先度データキューからの受信待ち状態)のタスクが,データを受信できる順序でつながれているキューである.
優先度データキュー属性には,次の属性を指定することができる【NGKI1795】.
TA_TPRI |
0x01U |
送信待ち行列をタスクの優先度順にする |
TA_TPRIを指定しない場合,送信待ち行列はFIFO順になる【NGKI1796】.受信待ち行列は,FIFO順に固定されている【NGKI1797】.
優先度データキュー機能に関連するカーネル構成マクロは次の通り.
TMIN_DPRI |
データ優先度の最小値(=1)【NGKI1798】 |
|
TMAX_DPRI |
データ優先度の最大値 |
TNUM_PDQID |
登録できる優先度データキューの数(動的生成対応でないカーネルでは,静的APIによって登録された優先度データキューの数に一致)【NGKI1799】 |
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,データ優先度の最大値(TMAX_DPRI)は16に固定されている【ASPS0138】.ただし,タスク優先度拡張パッケージでは,TMAX_DPRIを256に拡張する【ASPS0139】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,データ優先度の最大値(TMAX_DPRI)は16に固定されている【FMPS0124】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,データ優先度の最大値(TMAX_DPRI)は16に固定されている【HRPS0124】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,データ優先度の最大値(TMAX_DPRI)は16に固定されている【HRMPS0107】.
【使用上の注意】
データの優先度が使われるのは,データが優先度データキュー管理領域に格納される場合のみであり,データを送信するタスクが送信待ち行列につながれている間には使われない.そのため,送信待ち行列につながれているタスクが,優先度データキュー管理領域に格納されているデータよりも高い優先度のデータを送信しようとしている場合でも,最初に送信されるのは,優先度データキュー管理領域に格納されているデータである.また,TA_TPRI属性の優先度データキューにおいても,送信待ち行列はタスクの優先度順となり,タスクが送信しようとしているデータの優先度順となるわけではない.
【μITRON4.0仕様との関係】
μITRON4.0仕様に規定されていない機能である.
CRE_PDQ |
優先度データキューの生成〔S〕【NGKI1800】 |
acre_pdq |
優先度データキューの生成〔TD〕【NGKI1801】 |
【静的API】
CRE_PDQ(ID pdqid, { ATR pdqatr, uint_t pdqcnt, PRI maxdpri, void *pdqmb })
※ pdqmbの記述は省略することができる【NGKI3902】.
【C言語API】
ER_ID pdqid = acre_pdq(const T_CPDQ *pk_cpdq)
【パラメータ】
ID |
pdqid |
生成する優先度データキューの識別名(CRE_PDQの場合) |
|
T_CPDQ * |
pk_cpdq |
優先度データキューの生成情報を入れたパケットへのポインタ(acre_pdqの場合) |
*優先度データキューの生成情報(パケットの内容)
ATR |
pdqatr |
優先度データキュー属性 |
|
uint_t |
pdqcnt |
優先度データキュー管理領域に格納できるデータ数 |
|
PRI |
maxdpri |
優先度データキューに送信できるデータ優先度の最大値 |
|
void * |
pdqmb |
優先度データキュー管理領域の先頭番地 |
【リターンパラメータ】
ER_ID |
pdqid |
生成された優先度データキューのID番号(正の値)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_RSATR |
予約属性 |
|
E_NOSPT |
未サポート機能 |
|
E_PAR |
パラメータエラー |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_NOID |
ID番号不足 |
|
E_NOMEM |
メモリ不足 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
各パラメータで指定した優先度データキューの生成情報に従って,優先度データキューを生成する【NGKI5192】.pdqcntとpdqmbから優先度データキュー管理領域が設定され,格納されているデータがない状態に初期化される【NGKI1813】.また,送信待ち行列と受信待ち行列は,空の状態に初期化される【NGKI1814】.
静的APIにおいては,pdqidはオブジェクト識別名,pdqatr,pdqcnt,maxdpriは整数定数式パラメータ,pdqmbは一般定数式パラメータである【NGKI1815】.コンフィギュレータは,静的APIのメモリ不足(E_NOMEM)エラーを検出することができない【NGKI1816】.
pdqmbにNULLを指定するか,静的APIにおいてpdqmbの記述を省略した場合,pdqcntで指定した数のデータを格納できる優先度データキュー管理領域が,コンフィギュレータまたはカーネルにより確保される【NGKI1817】.
pdqmbにNULL以外を指定した場合,pdqmbを先頭番地とする優先度データキュー管理領域は,アプリケーションで確保しておく必要がある【NGKI1820】.優先度データキュー管理領域をアプリケーションで確保するために,次のマクロを用意している【NGKI1821】.
TSZ_PDQMB(pdqcnt) |
pdqcntで指定した数のデータを格納できる優先度データキュー管理領域のサイズ(バイト数) |
|
TCNT_PDQMB(pdqcnt) |
pdqcntで指定した数のデータを格納できる優先度データキュー管理領域を確保するために必要なMB_T型の配列の要素数 |
これらを用いて,pdqcntで指定した数のデータを格納できる優先度データキュー管理領域を確保する方法は次の通り【NGKI1822】.
MB_T <優先度データキュー管理領域の変数名>[TCNT_PDQMB(pdqcnt)];
この時,pdqmbには<優先度データキュー管理領域の変数名>を指定する【NGKI1823】.
この方法に従わず,pdqmbにターゲット定義の制約に合致しない先頭番地を指定した時には,E_PARエラーとなる【NGKI1824】.また,保護機能対応カーネルにおいて,pdqmbで指定した優先度データキュー管理領域がカーネル専用のメモリオブジェクトに含まれない場合,E_OBJエラーとなる【NGKI1825】.
なお,pdqmbにNULL以外を指定できないカーネルでは,TSZ_PDQMBとTCNT_PDQMBは用意していない【NGKI5180】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,pdqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【ASPS0142】.
ASP3カーネルの動的生成機能拡張パッケージでは,acre_pdqをサポートする【ASPS0143】.acre_pdqに対しては,pdqmbにNULL以外を指定できないという制限はない【ASPS0144】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,pdqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【FMPS0127】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,pdqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【HRPS0127】.
HRP3カーネルの動的生成機能拡張パッケージでは,acre_pdqをサポートする【HRPS0190】.acre_pdqに対しては,pdqmbにNULL以外を指定できないという制限はない【HRPS0191】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,pdqmbにはNULLのみを指定することができる.NULL以外を指定した場合には,E_NOSPTエラーとなる【HRMPS0108】.
【TOPPERS新世代カーネル統合仕様との関係】
アクセス権を制御するためのアクセスの種別を,保護ドメインに対する通常操作1に変更した.
AID_PDQ |
割付け可能な優先度データキューIDの数の指定〔SD〕【NGKI1826】 |
【静的API】
AID_PDQ(uint_t nopdq)
【パラメータ】
uint_t |
nopdq |
割付け可能な優先度データキューIDの数 |
【エラーコード】
E_RSATR |
予約属性 |
【機能】
nopdqで指定した数の優先度データキューIDを,優先度データキューを生成するサービスコールによって割付け可能な優先度データキューIDとして確保する【NGKI1828】.
nopdqは整数定数式パラメータである【NGKI1829】.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,AID_PDQをサポートする【ASPS0214】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,AID_PDQをサポートする【HRPS0215】.
SAC_PDQ |
優先度データキューのアクセス許可ベクタの設定〔SP〕【NGKI1830】 |
sac_pdq |
優先度データキューのアクセス許可ベクタの設定〔TPD〕【NGKI1831】 |
【静的API】
SAC_PDQ(ID pdqid, { ACPTN acptn1, ACPTN acptn2,
ACPTN acptn3, ACPTN acptn4 })
【C言語API】
ER ercd = sac_pdq(ID pdqid, const ACVCT *p_acvct)
【パラメータ】
ID |
pdqid |
対象優先度データキューの識別名(SAC_PDQの場合)またはID番号(sac_pdqの場合) |
|
ACVCT * |
p_acvct |
アクセス許可ベクタを入れたパケットへのポインタ(sac_pdqの場合) |
*アクセス許可ベクタ(パケットの内容)
ACPTN |
acptn1 |
通常操作1のアクセス許可パターン |
|
ACPTN |
acptn2 |
通常操作2のアクセス許可パターン |
|
ACPTN |
acptn3 |
管理操作のアクセス許可パターン |
|
ACPTN |
acptn4 |
参照操作のアクセス許可パターン |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_RSATR |
予約属性 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
pdqidで指定した優先度データキュー(対象優先度データキュー)のアクセス許可ベクタ(4つのアクセス許可パターンの組)を,各パラメータで指定した値に設定する【NGKI1842】.
静的APIにおいては,pdqidはオブジェクト識別名,acptn1〜acptn4は整数定数式パラメータである【NGKI1843】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,sac_pdqをサポートする【HRPS0192】.
del_pdq |
優先度データキューの削除〔TD〕【NGKI1844】 |
【C言語API】
ER ercd = del_pdq(ID pdqid)
【パラメータ】
ID |
pdqid |
対象優先度データキューのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_OBJ |
オブジェクト状態エラー |
【機能】
pdqidで指定した優先度データキュー(対象優先度データキュー)を削除する.具体的な振舞いは以下の通り.
対象優先度データキューの登録が解除され,その優先度データキューIDが未使用の状態に戻される【NGKI1851】.また,対象優先度データキューの送信待ち行列と受信待ち行列につながれたタスクは,それぞれの待ち行列の先頭のタスクから順に待ち解除される【NGKI1852】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1853】.
優先度データキューの生成時に,優先度データキュー管理領域がカーネルによって確保された場合は,そのメモリ領域が解放される【NGKI1854】.
【補足説明】
送信待ち行列と受信待ち行列の両方にタスクがつながれていることはないため,別の待ち行列で待っていたタスクの間の待ち解除の順序は,規定する必要がない.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルの動的生成機能拡張パッケージでは,del_pdqをサポートする【ASPS0147】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルの動的生成機能拡張パッケージでは,del_pdqをサポートする【HRPS0193】.
snd_pdq |
優先度データキューへの送信〔T〕【NGKI1855】 |
psnd_pdq |
優先度データキューへの送信(ポーリング)〔TI〕【NGKI3537】 |
tsnd_pdq |
優先度データキューへの送信(タイムアウト付き)〔T〕【NGKI1858】 |
【C言語API】
ER ercd = snd_pdq(ID pdqid, intptr_t data, PRI datapri)
ER ercd = psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
ER ercd = tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
【パラメータ】
ID |
pdqid |
対象優先度データキューのID番号 |
|
intptr_t |
data |
送信データ |
|
PRI |
datapri |
送信データの優先度 |
|
TMO |
tmout |
タイムアウト時間(tsnd_pdqの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(snd_pdqを除く)【NGKI1868】 |
|
E_RLWAI |
待ち状態の強制解除(psnd_pdqを除く)【NGKI1869】 |
|
E_RASTER |
タスクの終了要求(psnd_pdqを除く)【NGKI3461】 |
|
E_DLT |
待ちオブジェクトの削除または再初期化(psnd_pdqを除く)【NGKI1870】 |
【機能】
pdqidで指定した優先度データキュー(対象優先度データキュー)に,dataで指定したデータを,datapriで指定した優先度で送信する.具体的な振舞いは以下の通り.
対象優先度データキューの受信待ち行列にタスクが存在する場合には,受信待ち行列の先頭のタスクが,dataで指定したデータを受信し,待ち解除される【NGKI1871】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1872】.
対象優先度データキューの受信待ち行列にタスクが存在せず,優先度データキュー管理領域にデータを格納するスペースがある場合には,dataで指定したデータが,datapriで指定したデータの優先度順で優先度データキュー管理領域に格納される【NGKI1873】.
対象優先度データキューの受信待ち行列にタスクが存在せず,優先度データキュー管理領域にデータを格納するスペースがない場合には,自タスクは優先度データキューへの送信待ち状態となり,対象優先度データキューの送信待ち行列につながれる【NGKI1874】.
datapriは,TMIN_DPRI以上で,対象データキューに送信できるデータ優先度の最大値以下でなければならない.そうでない場合には,E_PARエラーとなる【NGKI1876】.
rcv_pdq |
優先度データキューからの受信〔T〕【NGKI1877】 |
prcv_pdq |
優先度データキューからの受信(ポーリング)〔T〕【NGKI1878】 |
trcv_pdq |
優先度データキューからの受信(タイムアウト付き)〔T〕【NGKI1879】 |
【C言語API】
ER ercd = rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
ER ercd = prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
ER ercd = trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
【パラメータ】
ID |
pdqid |
対象優先度データキューのID番号 |
|
intptr_t * |
p_data |
受信データを入れるメモリ領域へのポインタ |
|
PRI * |
p_datapri |
受信データの優先度を入れるメモリ領域へのポインタ |
|
TMO |
tmout |
タイムアウト時間(trcv_pdqの場合) |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
|
intptr_t |
data |
受信データ |
|
PRI |
datapri |
受信データの優先度 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_NOSPT |
未サポート機能 |
|
E_ID |
不正ID番号 |
|
E_PAR |
パラメータエラー |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
|
E_TMOUT |
ポーリング失敗またはタイムアウト(rcv_pdqを除く)【NGKI1890】 |
|
E_RLWAI |
待ち状態の強制解除(prcv_pdqを除く)【NGKI1891】 |
|
E_RASTER |
タスクの終了要求(prcv_pdqを除く)【NGKI3462】 |
|
E_DLT |
待ちオブジェクトの削除または再初期化(prcv_pdqを除く)【NGKI1892】 |
【機能】
pdqidで指定した優先度データキュー(対象優先度データキュー)からデータを受信する.データの受信に成功した場合,受信したデータはp_dataが指すメモリ領域に,その優先度はp_datapriが指すメモリ領域に返される【NGKI1894】.具体的な振舞いは以下の通り.
対象優先度データキューの優先度データキュー管理領域にデータが格納されている場合には,優先度データキュー管理領域の先頭に格納されたデータを受信する【NGKI1893】.また,送信待ち行列にタスクが存在する場合には,送信待ち行列の先頭のタスクの送信データが,データの優先度順で優先度データキュー管理領域に格納され,そのタスクは待ち解除される【NGKI1895】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1896】.
対象優先度データキューの優先度データキュー管理領域にデータが格納されておらず,送信待ち行列にタスクが存在する場合には,送信待ち行列の先頭のタスクの送信データを受信する【NGKI1897】.送信待ち行列の先頭のタスクは,待ち解除される【NGKI1899】.待ち解除されたタスクには,待ち状態となったサービスコールからE_OKが返る【NGKI1900】.
対象優先度データキューの優先度データキュー管理領域にデータが格納されておらず,送信待ち行列にタスクが存在しない場合には,自タスクは優先度データキューからの受信待ち状態となり,対象優先度データキューの受信待ち行列につながれる【NGKI1901】.
ini_pdq |
優先度データキューの再初期化〔T〕【NGKI1902】 |
【C言語API】
ER ercd = ini_pdq(ID pdqid)
【パラメータ】
ID |
pdqid |
対象優先度データキューのID番号 |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
【機能】
pdqidで指定した優先度データキュー(対象優先度データキュー)を再初期化する.具体的な振舞いは以下の通り.
対象優先度データキューの優先度データキュー管理領域は,格納されているデータがない状態に初期化される【NGKI1908】.また,対象優先度データキューの送信待ち行列と受信待ち行列につながれたタスクは,それぞれの待ち行列の先頭のタスクから順に待ち解除される【NGKI1909】.待ち解除されたタスクには,待ち状態となったサービスコールからE_DLTエラーが返る【NGKI1910】.
【補足説明】
送信待ち行列と受信待ち行列の両方にタスクがつながれていることはないため,別の待ち行列で待っていたタスクの間の待ち解除の順序は,規定する必要がない.
【使用上の注意】
優先度データキューを再初期化した場合に,アプリケーションとの整合性を保つのは,アプリケーションの責任である.
ref_pdq |
優先度データキューの状態参照〔T〕【NGKI1911】 |
【C言語API】
ER ercd = ref_pdq(ID pdqid, T_RPDQ *pk_rpdq)
【パラメータ】
ID |
pdqid |
対象優先度データキューのID番号 |
|
T_RPDQ * |
pk_rpdq |
優先度データキューの現在状態を入れるパケットへのポインタ |
【リターンパラメータ】
ER |
ercd |
正常終了(E_OK)またはエラーコード |
*優先度データキューの現在状態(パケットの内容)
ID |
stskid |
優先度データキューの送信待ち行列の先頭のタスクのID番号 |
|
ID |
rtskid |
優先度データキューの受信待ち行列の先頭のタスクのID番号 |
|
uint_t |
spdqcnt |
優先度データキュー管理領域に格納されているデータの数 |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_ID |
不正ID番号 |
|
E_NOEXS |
オブジェクト未登録 |
|
E_OACV |
オブジェクトアクセス違反 |
|
E_MACV |
メモリアクセス違反 |
【機能】
pdqidで指定した優先度データキュー(対象優先度データキュー)の現在状態を参照する.参照した現在状態は,pk_rpdqで指定したパケットに返される【NGKI1918】.
対象優先度データキューの送信待ち行列にタスクが存在しない場合,stskidにはTSK_NONE(=0)が返る【NGKI1919】.また,受信待ち行列にタスクが存在しない場合,rtskidにはTSK_NONE(=0)が返る【NGKI1920】.
【使用上の注意】
ref_pdqはデバッグ時向けの機能であり,その他の目的に使用することは推奨しない.これは,ref_pdqを呼び出し,対象優先度データキューの現在状態を参照した直後に割込みが発生した場合,ref_pdqから戻ってきた時には対象優先度データキューの状態が変化している可能性があるためである.また,マルチプロセッサ対応カーネルでは,対象優先度データキューの現在状態を参照した直後に,他のプロセッサで実行されている処理により対象優先度データキューの状態が変化する場合もある.
4.4.5 ミューテックス
ミューテックスは,タスク間の排他制御を行うための同期・通信オブジェクトである.タスクは,排他制御区間に入る時にミューテックスをロックし,排他制御区間を出る時にロック解除する.ミューテックスは,ミューテックスIDと呼ぶID番号によって識別する【NGKI2007】.
ミューテックスは,排他制御に伴う優先度逆転の時間を抑えるために,優先度上限プロトコル(priority ceiling protocol)と優先度継承プロトコル(priority inheritance protocol)をサポートする.ミューテックス属性により優先度上限/優先度継承ミューテックスであると指定することで,そのミューテックスの操作時に,優先度上限/優先度継承プロトコルに従った現在優先度の制御が行われる.
各ミューテックスが持つ情報は次の通り【NGKI2008】.
-
ミューテックス属性
-
ロック状態(ロックされている状態とロック解除されている状態)
-
ミューテックスをロックしているタスク
-
待ち行列(ミューテックスのロック待ち状態のタスクのキュー)
-
上限優先度(優先度上限ミューテックスの場合)
-
アクセス許可ベクタ(保護機能対応カーネルの場合)
-
属する保護ドメイン(保護機能対応カーネルの場合)
-
属するクラス(マルチプロセッサ対応カーネルの場合)
待ち行列は,ミューテックスをロックできるまで待っている状態(ミューテックスのロック待ち状態)のタスクが,ミューテックスをロックできる順序でつながれているキューである.
上限優先度は,優先度上限ミューテックスに対してのみ有効で,ミューテックスの生成時に,そのミューテックスをロックする可能性のあるタスクのベース優先度の中で最も高い優先度(または,それより高い優先度)に設定する【NGKI2009】.
ミューテックス属性には,次の属性を指定することができる【NGKI2010】.
TA_TPRI |
0x01U |
待ち行列をタスクの優先度順にする |
|
TA_INHERIT |
0x02U |
優先度継承ミューテックスとする.待ち行列をタスクの優先度順にする |
|
TA_CEILING |
0x03U |
優先度上限ミューテックスとする.待ち行列をタスクの優先度順にする |
TA_TPRI,TA_INHERIT,TA_CEILINGのいずれも指定しない場合,待ち行列はFIFO順になる【NGKI2011】.
ミューテックス機能に関連して,各タスクが持つ情報は次の通り【NGKI2012】.
-
ロックしているミューテックスのリスト
ロックしているミューテックスのリストは,タスクの起動時に空に初期化される【NGKI2013】.
タスクの現在優先度は,常に,以下の優先度の中で最も高い優先度に設定される【NGKI2014】.
-
そのタスクのベース優先度
-
そのタスクがロックしている優先度上限ミューテックスの優先度上限
-
そのタスクがロックしている優先度継承ミューテックスに対してロック待ち状態となっているタスクの現在優先度
タスクが優先度上昇状態であるとは,タスクが以下のいずれかを満たしている状態をいう.
-
そのタスクが優先度上限ミューテックスをロックしている.
-
そのタスクがロックしている優先度継承ミューテックスに対してロック待ち状態となっているタスクの中で,そのタスクのベース優先度と同じかそれより高い現在優先度を持つものがある.
サブ優先度機能をサポートするカーネルでは,タスクが優先度上昇状態である間は,サブ優先度は一時的に最高値(=0)になったものとみなしてスケジューリングされる【NGKI5219】.
ミューテックス機能によりタスクの現在優先度が変化する場合と,サブ優先度が使われる状況(サブ優先度機能をサポートするカーネルで,タスクの現在優先度がサブ優先度を使用すると設定されている場合)で優先度上昇状態であるか否かが変化する場合には,以下の処理が行われる.
現在優先度等を変化させるサービスコールの前後とも,当該タスクが実行できる状態である場合には,優先度が同じタスク(サブ優先度が使われる状況では,サブ優先度も同じタスク)の中で優先順位が最も高くなる【NGKI2015】.そのサービスコールにより,当該タスクが実行できる状態に遷移する場合には,優先度が同じタスク(サブ優先度が使われる状況では,サブ優先度も同じタスク)の中で優先順位が最も低くなる【NGKI2016】.
そのサービスコールの後で,当該タスクが待ち状態で,タスクの優先度順の待ち行列につながれている場合には,当該タスクの変更後の現在優先度に従って,その待ち行列中での順序が変更される【NGKI2017】.待ち行列中に同じ現在優先度のタスクがある場合には,当該タスクの順序はそれらの中で最後になる【NGKI2018】.
ミューテックス機能に関連して,タスクの終了時に行うべき処理として,タスクがロックしているミューテックスのロック解除がある.タスクの終了時にロックしているミューテックスが残っている場合,それらのミューテックスは,ロックしたのと逆の順序でロック解除される【NGKI2019】.ロック解除の具体的な処理内容については,unl_mtxの機能の項を参照すること.
ミューテックス機能に関連するカーネル構成マクロは次の通り.
TNUM_MTXID |
登録できるミューテックスの数(動的生成対応でないカーネルでは,静的APIによって登録されたミューテックスの数に一致)【NGKI2020】 |
【使用上の注意】
優先度上限プロトコルには,(a) 優先度の低いタスクの排他制御区間に最大1回しかブロックされない,(b) タスクの実行が開始された以降は優先度の低いタスクにブロックされないという利点があるが,これは,タスク間の同期に優先度上限ミューテックスのみを用い,他の方法でタスクのスケジューリングに関与しない場合に得られる利点である.
これらの利点を得るためには,タスクの優先順位の回転やディスパッチの禁止を行ってはならないことに加えて,優先度上限ミューテックスをロックしたタスクを待ち状態にしてはならない.特に,優先度上限ミューテックスに対して,タスクがロック待ち状態になる状況に注意が必要である(優先度上限プロトコルでは,タスクがミューテックスのロック待ち状態になることはない).
例えば,着目するタスクAと,タスクAよりベース優先度の低いタスクBとタスクC,タスクAよりも高い上限優先度を持った優先度上限ミューテックスがある場合を考える.タスクAがミューテックスをロックし,タスクBとタスクCがミューテックスを待っている状況で,タスクAがミューテックスをロック解除すると,タスクBがミューテックスをロックして優先度が上がり,タスクBに切り換わる.さらにタスクBがミューテックスをロック解除すると,タスクCがミューテックスをロックして優先度が上がり,タスクCに切り換わる.タスクAが実行されるのは,タスクCがミューテックスをロック解除した後である.この例では,タスクAが実行開始後に,タスクBとタスクCの排他制御区間にブロックされることになる.
優先度上限ミューテックスに対してタスクがロック待ち状態になる状況を回避するためには,優先度上限ミューテックスをロックする場合に,待ち状態にならないploc_mtxを用いるのが安全である.
マルチプロセッサにおいては,タスク間の同期に優先度上限ミューテックスのみを用い,他の方法でタスクのスケジューリングに関与しない場合でも,優先度上限ミューテックスに対してタスクがロック待ち状態になる場合がある.
【補足説明】
優先度継承ミューテックスのロックを待っているタスクの現在優先度が,ミューテックスの操作により変更された場合,そのミューテックスをロックしているタスクの現在優先度の変更が必要になる場合がある.これを推移的な優先度継承と呼ぶ.さらにそのタスクが,別の優先度継承ミューテックスのロックを待っていた場合には,そのミューテックスをロックしているタスクに対して推移的な優先度継承が起こる場合がある.
この仕様で優先度上限プロトコルと呼んでいる方式は,オリジナルのpriority ceiling protocolとは異なるものである.この仕様の方式は,AUTOSAR OS仕様でもpriority ceiling protocolと呼ばれているが,学術論文や他のOSでは,immediate ceiling priority protocol,priority protection protocol,priority ceiling emulation,highest locker protocolなどと呼ばれている.
【TOPPERS/ASP3カーネルにおける規定】
ASP3カーネルでは,優先度継承ミューテックスはサポートしない【ASPS0237】.ただし,優先度継承拡張パッケージを用いると,優先度継承ミューテックスの機能を追加することができる【ASPS0238】.
【TOPPERS/FMP3カーネルにおける規定】
FMP3カーネルでは,優先度継承ミューテックスはサポートしない【FMPS0174】.
【TOPPERS/HRP3カーネルにおける規定】
HRP3カーネルでは,優先度継承ミューテックスはサポートしない【HRPS0245】.
【TOPPERS/HRMP3カーネルにおける規定】
HRMP3カーネルでは,優先度継承ミューテックスはサポートしない【HRMPS0121】.
【μITRON4.0仕様との関係】
μITRON4.0仕様の厳密な優先度制御規則を採用し,簡略化した優先度制御規則はサポートしていない.
ミューテックス機能によりタスクの現在優先度が変化する場合の振舞いは,μITRON4.0仕様では実装依存となっているが,この仕様では規定している.
ミューテックスのロック解除は,ロックしたのと逆順で行わなければならないものとした.
TNUM_MTXIDは,μITRON4.0仕様に規定されていないカーネル構成マクロである.
【TOPPERS新世代カーネル統合仕様との関係】
ミューテックス(優先度継承ミューテックスは除く)は標準機能の位置付けとした.そのため,ASP3カーネルとFMP3カーネルにおいても,ミューテックスをサポートしている.
μITRON4.0仕様でサポートしており,TOPPERS新世代カーネル統合仕様でサポートしていなかった優先度継承プロトコルをサポートしている.
ミューテックスのロック解除は,ロックしたのと逆順で行わなければならないものとした.
CRE_MTX |
ミューテックスの生成〔S〕【NGKI2021】 |
acre_mtx |
ミューテックスの生成〔TD〕【NGKI2022】 |
【静的API】
CRE_MTX(ID mtxid, { ATR mtxatr, PRI ceilpri })
※ 優先度上限ミューテックス以外の場合には,ceilpriの記述を省略することができる【NGKI2035】.
【C言語API】
ER_ID mtxid = acre_mtx(const T_CMTX *pk_cmtx)
【パラメータ】
ID |
mtxid |
生成するミューテックスの識別名(CRE_MTXの場合) |
|
T_CMTX * |
pk_cmtx |
ミューテックスの生成情報を入れたパケットへのポインタ(acre_mtxの場合) |
*ミューテックスの生成情報(パケットの内容)
ATR |
mtxatr |
ミューテックス属性 |
|
PRI |
ceilpri |
ミューテックスの上限優先度 |
【リターンパラメータ】
ER_ID |
mtxid |
生成されたミューテックスのID番号(正の値)またはエラーコード |
【エラーコード】
E_CTX |
コンテキストエラー |
|
E_RSATR |
予約属性 |