	
	TOPPERS/FMPカーネル
		ターゲット依存部 ポーティングガイド

		対応バージョン: Release 1.4.0
		対応ASPカーネルバージョン : Release 1.9.1
		最終更新: 2015年1月27日

このドキュメントは，TOPPERS/FMPカーネルを，未サポートのターゲットシス
テムにポーティングするために必要となるターゲット依存部の実装方法を説明
するものである．

TOPPERS/FMPカーネルは，シングルプロセッサ向けのRTOSであるTOPPERS/ASPカ
ーネルをベースとしているため，多くのポーティング項目はTOPPERS/ASPカー
ネルと同一である．そのため，TOPPERS/FMPカーネルをポーティングする前に，
TOPPERS/ASPカーネルをポーティングすることを推奨する．このドキュメント
では，TOPPERS/ASPカーネルからのポーティングに関して説明する．

----------------------------------------------------------------------
 TOPPERS/FMP Kernel
     Toyohashi Open Platform for Embedded Real-Time Systems/
     Flexible MultiProcessor Kernel

 Copyright (C) 2005-2015 by Embedded and Real-Time Systems Laboratory
             Graduate School of Information Science, Nagoya Univ., JAPAN
 
 上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
 ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
 変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
 (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
     権表示，この利用条件および下記の無保証規定が，そのままの形でソー
     スコード中に含まれていること．
 (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
     用できる形で再配布する場合には，再配布に伴うドキュメント（利用
     者マニュアルなど）に，上記の著作権表示，この利用条件および下記
     の無保証規定を掲載すること．
 (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
     用できない形で再配布する場合には，次のいずれかの条件を満たすこ
     と．
   (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
       作権表示，この利用条件および下記の無保証規定を掲載すること．
   (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
       報告すること．
 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
     害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
     また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
     由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
     免責すること．
 
 本ソフトウェアは，無保証で提供されているものである．上記著作権者お
 よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
 に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
 アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
 の責任を負わない．
 
 @(#) $Id: porting.txt 1214 2017-04-25 07:02:15Z ertl-honda $
----------------------------------------------------------------------

○目次
◎０．動作アーキテクチャ
１．共通事項
	1.1 ターゲット依存部の構成
	1.2 名前の衝突の防止
	1.3 多重インクルードの防止
	1.4 アセンブリ言語とのヘッダファイルの共用 
	1.5 インクルード記述の方法
	1.6 クリティカルセクションの出入処理の実現に関する制約
２．システム構築環境のターゲット依存部
	2.1 ターゲット略称とターゲット依存部のディレクトリ
	2.2 Makefileのターゲット依存部
	2.3 開発環境名とコマンド名の設定
	2.4 コンパイルオプションとオブジェクトファイルの設定
	2.5 オフセットファイルの生成方法
		2.5.1 コンフィギュレータを用いる方法 
		2.5.2 makeoffset.cとgenoffsetを用いる方法 
	2.6 リンク方法の設定
	2.7 依存関係の定義
	2.8 その他の設定
３．TOPPERS共通定義のターゲット依存部
	3.1 ターゲット識別マクロ
	3.2 整数型の最大値・最小値・ビット数
	3.3 サイズの指定された整数型，その最大値・最小値，整数定数を作るマクロ
	3.4 サイズの指定された浮動小数点型，その最大値・最小値のマクロ
	3.5 コンパイラの拡張機能のためのマクロ定義
	3.6 標準的な定義の上書き
	3.7 アサーションのための定義
	◎3.8 テスト用ラベル追加マクロ
４．システムインタフェースレイヤ（SIL）のターゲット依存部
	○4.1 全割込みロック状態の管理
	4.2 微少時間待ち
	4.3 プロセッサのエンディアン
	4.4 メモリ空間アクセス関数
	4.5 I/O空間アクセス関数
	◎4.6 スピンロック機能
	◎4.7 プロセッサIDの取得
５．カーネルAPIのターゲット依存部
	5.1 ターゲット定義でサポートする機能
	5.2 割込み優先度の範囲
	5.3 タイムティックの定義
	5.4 メモリ領域確保のための型定義
	5.5 ビットパターンのビット数
	5.6 メモリ領域確保のためのマクロ
	○5.7 オーバランハンドラ機能拡張のための定義（オプション）
	◎5.8 プロセッサ数の定義
	◎5.9 クラスIDの定義
６．カーネル実装のターゲット依存部
	6.1 カーネル実装のターゲット依存部の共通事項
		○6.1.1 カーネル実装のターゲット依存部の構成要素
		6.1.2 ターゲット依存部の関数の命名規則
	6.2 トレースログ機能への対応
	6.3 システム状態の管理
		6.3.1 全割込みロック状態の管理
		○6.3.2 コンテキストの管理
		○6.3.3 CPUロック状態の管理
		◎6.3.4 コンテキストとCPUロック状態のチェック
	6.4 割込みに関連するシステム状態の管理
		○6.4.1 割込み優先度マスクの管理
		○6.4.2 割込み要求禁止フラグの管理
		6.4.3 割込み要求のクリア
		6.4.4 割込み要求のプローブ
		6.4.5 割込みハンドラの先頭処理と末尾処理
	6.5 タスクディスパッチャ
		6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック
		○6.5.2 ディスパッチャ本体
		○6.5.3 タスクコンテキストからのディスパッチ
		○6.5.4 ディスパッチャの動作開始
		6.5.5 現在のコンテキストを捨ててディスパッチ
		○6.5.6 タスクの起動処理
	○6.6 割込みハンドラ
		○6.6.1 割込みハンドラの出入口処理
		6.6.2 割込みハンドラ毎の出入口処理の生成
		○6.6.3 割込みハンドラの設定
		○6.6.4 割込み要求ラインの属性の設定
		6.6.5 割込み管理機能の初期化処理の変更
		6.6.6 デフォルトの割込みハンドラ
		6.6.7 カーネル管理外の割込み
		6.6.8 割込みサービスルーチンの生成
		◎6.6.9 割込み番号・割込みハンドラ番号のマルチプロセッサ拡張
	6.7 CPU例外ハンドラとCPU例外発生時のシステム状態の参照
		○6.7.1 CPU例外ハンドラの出入口処理
		6.7.2 CPU例外ハンドラの出入口処理の生成
		6.7.3 CPU例外ハンドラの設定
		6.7.4 CPU例外管理機能の初期化処理の変更
		6.7.5 デフォルトのCPU例外ハンドラ
		6.7.6 CPU例外発生時のシステム状態の参照
		◎6.7.7 CPU例外ハンドラ番号のマルチプロセッサ拡張
	○6.8 カーネルの起動・終了とスタック領域など
	6.9 カーネル内部のチューニング
		6.9.1 ビットマップサーチ
		6.9.2 ビットフィールド
	6.10 カーネル実装に関するその他の定義
		6.10.1 オブジェクト属性の拡張
		6.10.2 エラーチェック方法の指定
		○6.10.3 非タスクコンテキスト用のスタック領域
		6.10.4 空ラベルの定義
	6.11 トレースログ機能に関する設定
		○6.11.1 取得できるトレースログの種類とマクロ
		6.11.2 トレースログ記録のサンプルコード
	6.12 カーネル実装のターゲット依存部のためのリネーム記述
	6.13 タイマドライバ
		6.13.1 タイマドライバのファイル構成
		6.13.2 タイマの初期化・終了処理・割込み処理
		◎6.13.3 性能評価用システム時刻の参照のための機能
	○6.14 オーバランタイマドライバ（オプション）
		○6.14.1 オーバランタイマドライバのファイル構成
		○6.14.2 オーバランタイマの操作と割込み処理
	○6.15 動的メモリ管理
		6.15.1 TLSFを用いたメモリ管理モジュールの例
	◎6.16 プロセッサ識別
		◎6.16.1 プロセッサINDEX
		◎6.16.2 マスタプロセッサ
	◎6.17 ロック
		◎6.17.1 ロック方式
		◎6.17.2 ロック変数の型定義
	◎6.18 システム時刻の管理方式
	◎6.19 プロセッサ間割込みドライバ
		◎6.19.1 プロセッサ間割込みドライバのファイル構成
		◎6.19.2 プロセッサ間割込みの初期化・終了処理・割込み処理
		◎6.19.3 プロセッサ間割込みの発行とクリア
		◎6.19.4 プロセッサ割込みハンドラの登録
		◎6.19.5 プロセッサ割込みハンドラ呼び出しの省略
	◎6.20 プロセッサコントロールブロック
	◎6.21 スピンロック
		◎6.21.1 スピンロック方式
		◎6.21.2 スピンロック方式の指定
		◎6.21.3 スピンロック関連の型
		◎6.21.4 スピンロックの初期化・取得・解放機能
	◎6.22 タスクマイグレーション
		◎6.22.1 自タスクのマイグレーションサポート
		◎6.22.2 タスク終了時のマイグレーションサポート
７．コンフィギュレータ設定ファイルのターゲット依存部
	7.1 設定ファイルとターゲット依存部の位置付け
	7.2 パス2のテンプレートファイルのターゲット依存部
		7.2.1 ターゲット非依存部をインクルードする前に定義すべき変数
		○7.2.2 ターゲット非依存部で定義される変数
		◎7.2.3 クラス内容の定義
		◎7.2.4 クラス内容の定義（連想配列）
		◎7.2.5 クラス内容の定義（関数）
		◎7.2.6 プロセッサ毎のデータ構造の配置場所
	7.3 パス3のテンプレートファイルのターゲット依存部
	○7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル
８．システムサービス等のターゲット依存部
	8.0 システムサービスのターゲット依存部
	○8.1 システムログ機能のターゲット依存定義
		◎8.1.1 システムログ出力の共有
	○8.2 ログタスクのターゲット依存定義
	8.3 シリアルインタフェースドライバのターゲット依存部
		○8.3.1 変数，データ型，管理関数
		8.3.2 デバイスサービスルーチン
		8.3.3 コールバックルーチン
	8.4 カーネル起動メッセージの出力のターゲット依存定義
	○8.5 サンプルプログラムとテストプログラムのターゲット依存定義
		◎8.5.1 実行時間分布集計モジュール用マクロ
９．その他
	○9.1 ドキュメント
	9.2 パッケージ記述ファイル
１０．リファレンス
	○10.1 ターゲット依存部のファイル一覧

○がついている項目はASPカーネルから変更があった箇所を，◎はFMPカーネル
で新規に追加された箇所を示す．


０．動作アーキテクチャ

FMPカーネルを動作させるシステムは，次のアーキテクチャ（プロセッサ/バス
/メモリ）を満たさなければならない．

(0-1) アドレス

各プロセッサで，プログラムや固定データに対して，同一アドレスでアクセス
可能であること．それぞれのプロセッサがアクセスする物理的なメモリが異な
っていてもよい．

(0-2) 共有メモリ

全プロセッサから，同一のアドレスでアクセス可能なRAMがあること．（カー
ネルのコントロールブロックはこの領域に配置する．）

(0-3) プロセッサ間割込み機能

任意のプロセッサに割込み（プロセッサ間割込み）を発生可能であること

(0-4) プロセッサ間排他制御機能

プロセッサ間での排他制御のための機構を持つこと．
  例 : test & set 命令， Mutex回路

(0-4) ロックの個数

プロセッサ間の排他制御機構を用いてロックを最低2個作成可能であること．2
個のみの場合はジャイアントロック方式のみサポート可能．1個+プロセッサ毎
に2個作成可能であるとプロセッサロック方式をサポート可能．ロックの作成
個数に上限がないと細粒度ロック方式もサポート可能．

(0-5) プロセッサID

各プロセッサがユニークなIDを持ち，それをソフトウェアで読み込むことによ
り，自プロセッサを判別可能であること．


１．共通事項

1.1 ターゲット依存部の構成

ASPカーネルから変更なし．

1.2 名前の衝突の防止

ASPカーネルから変更なし．

1.3 多重インクルードの防止

ASPカーネルから変更なし．

1.4 アセンブリ言語とのヘッダファイルの共用 

ASPカーネルから変更なし．

1.5 インクルード記述の方法

ASPカーネルから変更なし．

1.6 クリティカルセクションの出入処理の実現に関する制約

ASPカーネルから変更なし．


２．システム構築環境のターゲット依存部

2.1 ターゲット略称とターゲット依存部のディレクトリ

ASPカーネルから変更なし．

2.2 Makefileのターゲット依存部

ASPカーネルから変更なし．

2.3 開発環境名とコマンド名の設定

ASPカーネルから変更なし．

2.4 コンパイルオプションとオブジェクトファイルの設定

ASPカーネルから変更なし．

2.5 オフセットファイルの生成方法

ASPカーネルから変更なし．

2.5.1 makeoffset.cの記述方法

ASPカーネルから変更なし．

2.6 リンク方法の設定

ASPカーネルから変更なし．

2.7 依存関係の定義

ASPカーネルから変更なし．

2.8 その他の設定

ASPカーネルから変更なし．


３．TOPPERS共通定義のターゲット依存部

3.1 ターゲット識別マクロ

ASPカーネルから変更なし．

3.2 整数型の最大値・最小値・ビット数

ASPカーネルから変更なし．

3.3 サイズの指定された整数型，その最大値・最小値，整数定数を作るマクロ

ASPカーネルから変更なし．

3.4 サイズの指定された浮動小数点型，その最大値・最小値のマクロ

ASPカーネルから変更なし．

3.5 コンパイラの拡張機能のためのマクロ定義

ASPカーネルから変更なし．

3.6 標準的な定義の上書き

ASPカーネルから変更なし．

3.7 アサーションのための定義

ASPカーネルから変更なし．

3.8 テスト用ラベル追加マクロ

タイミングに依存したテスト用にグローバルなラベルを宣言するマクロを必要
に応じて定義する．現状このテストはARM用のシミュレータであるSkyEyeを使
用する必要があるため，その他のターゲットでは定義する必要がある．

定義を有効とした場合，最適化レベルを上げてコンパイルすると，コンパイル
エラーとなる場合があるので注意すること．

(3-8-1) TEST_G_LABEL

４．システムインタフェースレイヤ（SIL）のターゲット依存部

4.1 全割込みロック状態の管理

全割込みロック状態の管理はプロセッサ毎に行う．

(4-1-1) SIL_PRE_LOC

全割込みロックフラグの状態を保存するための変数を定義するマクロ．プロセ
ッサ毎に独立した変数を用意する．

(4-1-2) SIL_LOC_INT()

呼び出したプロセッサにおいて，現在の全割込みロックフラグの状態を
SIL_PRE_LOCで定義した変数に保存し，全割込みロック状態に遷移させるマク
ロ．

(4-1-3) SIL_UNL_INT()

呼び出したプロセッサにおいて，SIL_LOC_INT()によって変数に保存した状態
に戻すマクロ．

4.2 微少時間待ち

ASPカーネルから変更なし．

4.3 プロセッサのエンディアン

ASPカーネルから変更なし．

4.4 メモリ空間アクセス関数

ASPカーネルから変更なし．

4.5 I/O空間アクセス関数

ASPカーネルから変更なし．

4.6 スピンロック機能

SILのターゲット依存部では，スピンロックを用いたプロセッサ間の排他制御
機能の実現のため，スピンロックを取得する機能とスピンロックを返却する機
能を提供する．

SILの機能は，カーネルを使用しない場合にも使用できる必要がある．そのた
め，スピンロックの取得と解放は，カーネルを用いず，プロセッサのリソース
を直接操作することによって実現する．

スピンロックはカーネルが使用するものとは別に，システムインタフェースレ
イヤ用に確保する．使用するスピンロックは，カーネル起動時にターゲット依
存部で初期化すること．

(4-6-1) SIL_LOC_SPN

システムインタフェースレイヤ用のスピンロックを取得するマクロ．このマク
ロを実現する際には，「1.6クリティカルセクションの出入処理の実現に関す
る制約」の節に記述されている制約に従わなければならない．SIL_LOC_SPNは，
SIL_LOC_INTの機能を包含する．すなわち，SIL_LOC_SPNに成功すると全割込み
ロック状態になる．また，SIL_LOC_INT と同様に，用いる関数またはブロック
の先頭の変数宣言部に SIL_PRE_LOC を記述しなければならない．

(4-6-2) SIL_UNL_SPN

システムインタフェースレイヤ用のスピンロックを返却するマクロ．このマク
ロを実現する際には，「1.6クリティカルセクションの出入処理の実現に関す
る制約」の節に記述されている制約に従わなければならない．

(4-6-3) TOPPERS_sil_force_unl_spn

システムインタフェースレイヤ用のスピンロックを取得している場合に解放す
る関数．割込みロック状態は変更しない．この関数は，カーネル内部からのみ
呼び出す．

4.7 プロセッサIDの取得

(4-7-1) sil_get_pid(ID *p_prcid)

呼び出したプロセッサのプロセッサIDを取得する．

５．カーネルAPIのターゲット依存部

5.1 ターゲット定義でサポートする機能

5.2 割込み優先度の範囲

5.3 タイムティックの定義

5.4 メモリ領域確保のための型定義

5.5 ビットパターンのビット数

5.6 メモリ領域確保のためのマクロ

5.7 オーバランハンドラ機能拡張のための定義（オプション）

FMPカーネルでは，オーバランハンドラをサポートしない．

5.8 プロセッサ数の定義

(5-8-1)TNUM_PRCID   プロセッサ数

システムのプロセッサ数を定義する．なお，サポートするプロセッサ数の最大
数は，uint_t のビット幅の数となる(32bitなら32個)．

5.9 クラスIDの定義

クラスのIDを定義する．クラスIDの具体的な値はターゲット依存で定義する．

サンプルプログラムを動作させるためには，プロセッサ毎に次のマクロ名のク
ラスを定義する必要がある．

(5-9-1) TCL_1

プロセッサ1が初期割付けプロセッサのクラス．
割付け可能プロセッサはシステム上の全てのプロセッサ．

(5-9-2) TCL_2

プロセッサ2が初期割付けプロセッサのクラス．
割付け可能プロセッサはシステム上の全てのプロセッサ．

(5-9-3) TCL_3

プロセッサ3が初期割付けプロセッサのクラス．
割付け可能プロセッサはシステム上の全てのプロセッサ．

(5-9-4) TCL_4

プロセッサ4が初期割付けプロセッサのクラス．
割付け可能プロセッサはシステム上の全てのプロセッサ．

(5-9-5) TCL_1_ONLY

プロセッサ1が初期割付けプロセッサのクラス．
割付け可能プロセッサはプロセッサ1のみ．

(5-9-6) TCL_2_ONLY

プロセッサ2が初期割付けプロセッサのクラス．
割付け可能プロセッサはプロセッサ2のみ．

(5-9-7) TCL_3_ONLY

プロセッサ3が初期割付けプロセッサのクラス．
割付け可能プロセッサはプロセッサ3のみ．

(5-9-8) TCL_4_ONLY

プロセッサ4が初期割付けプロセッサのクラス．
割付け可能プロセッサはプロセッサ4のみ．

(5-9-9) TCL_SYSTIM_PRC 

クローバルタイマ方式の場合のタイムイベントハンドラを登録するクラス．初
期割付けプロセッサと割付け可能プロセッサは，システム時刻管理プロセッサ
を指定すること．

６．カーネル実装のターゲット依存部

6.1 カーネル実装のターゲット依存部の共通事項

6.1.1 カーネル実装のターゲット依存部の構成要素

(f) プロセッサ間割込みドライバ

プロセッサ間で割込みを発生させるためのプロセッサ間割込みドライバのヘッ
ダファイル，実装ファイル，システムコンフィギュレーションファイルを，そ
れぞれ，target_ipi.h，target_ipi.c，target_ipi.cfgに含める．プロセッサ・
チップ・開発環境依存部を切り分けることも可能である．

6.1.2 ターゲット依存部の関数の命名規則

ASPカーネルから変更なし．

6.2 トレースログ機能への対応

ASPカーネルから変更なし．

6.3 システム状態の管理

ASPカーネルから変更なし．

6.3.1 全割込みロック状態の管理

ASPカーネルから変更なし．

6.3.2 コンテキストの管理

(6-3-2-1) bool_t sense_context(void)

タスクコンテキストから，CPUロック解除状態で呼び出される可能性があるた
め，ディスパッチとマイグレーションを考慮して，ディスパッチとマイグレー
ションがなされた場合でも正しく動作するよう，必要なら割込みを禁止して実
行すること．

6.3.3 CPUロック状態の管理

(6-3-3-1) void t_lock_cpu(void)
(6-3-3-3) void x_lock_cpu(void)

タスクコンテキストから，CPUロック解除状態で呼び出されるため，ディスパ
ッチとマイグレーションを考慮して，ディスパッチとマイグレーションがなさ
れた場合でも正しく動作するよう，必要なら割込みを禁止して実行すること．

(6-3-3-7) bool_t t_sense_lock(void)
(6-3-3-9) bool_t x_sense_lock(void)

タスクコンテキストから，CPUロック解除状態で呼び出される可能性があるた
め，ディスパッチとマイグレーションを考慮して，ディスパッチとマイグレー
ションがなされた場合でも正しく動作するよう，必要なら割込みを禁止して実
行すること．

6.3.4 コンテキストとCPUロック状態のチェック

前述のように，コンテキストの判定（sense_context()）と，CPUロック状態の
判定（[tix]_sense_lock()）は，マイグレーションを考慮して必要なら，割込
みを禁止して実行する必要がある．これらの判定関数は，共通部から同時に呼
び出されることが多いため，実行オーバヘッドを考慮して，コンテキスト判定
とCPUロック状態の判定の両方をチェックするターゲット依存の関数を用意す
る．この関数では，マイグレーションを考慮して，必要なら，割込みを禁止し
て判定する．リターン時には割込みを元の状態とする

なお，これら関数が全割込みロック状態で呼び出される状況は考える必要がな
いことから，全割込みロック状態とCPUロック状態を区別できる必要はない．
NMI以外にカーネルの管理外の割込みを設けない場合には，全割込みロック状
態とCPUロック状態が全く同一の状態でもかまわない．

(6-3-4-4) bool_t sense_tskctx_unl(void)

タスクコンテキスト かつ CPUロック解除状態なら true を それ以外なら 
false を返す関数．

タスクコンテキストから，CPUロック解除状態で呼び出される可能性があるた
め，ディスパッチとマイグレーションを考慮して，ディスパッチとマイグレー
ションがなされた場合でも正しく動作するよう，必要なら割込みを禁止して実
行すること．

(6-3-4-5) bool_t sense_intctx_unl(void)

非タスクコンテキスト かつ CPUロック解除状態なら true を それ以外なら 
false を返す関数．

タスクコンテキストから，CPUロック解除状態で呼び出される可能性があるた
め，ディスパッチとマイグレーションを考慮して，ディスパッチとマイグレー
ションがなされた場合でも正しく動作するよう，必要なら割込みを禁止して実
行すること．

6.4 割込みに関連するシステム状態の管理

6.4.1 割込み優先度マスクの管理

(6-4-1-1) bool_t VALID_INTPRI_CHGIPM(PRI intpri)（オプション）

タスクコンテキストから，CPUロック解除状態で呼び出される可能性があるた
め，ディスパッチとマイグレーションを考慮して，ディスパッチとマイグレー
ションがなされた場合でも正しく動作するよう，必要なら割込みを禁止して実
行すること．

6.4.2 割込み要求禁止フラグの管理

(6-4-2-1) bool_t VALID_INTNO_DISINT(ID prcid, INTNO intno)

intnoが，dis_int／ena_intに対する割込み番号として有効な値である場合に
true，そうでない場合にfalseを返すマクロ．prcidのプロセッサから割込み要
求禁止フラグがセット／クリアできないintnoに対しては，このマクロがfalse
を返すようにする．

6.4.3 割込み要求のクリア

ASPカーネルから変更なし．

6.4.4 割込み要求のプローブ

ASPカーネルから変更なし．

6.4.5 割込みハンドラの先頭処理と末尾処理

ASPカーネルから変更なし．

6.5 タスクディスパッチャ

6.5.1 タスクコンテキストブロックのデータ型

ASPカーネルから変更なし．

6.5.2 ディスパッチャ本体

ディスパッチャ本体で扱うp_runtsk/p_schedtsk/reqflgは，自プロセッサの
pcbが保持しているものとする．CPUロック状態はディスパッチャ本体を実行し
ているプロセッサを対象とする．

----------------------------------------
void
dispatcher(void)
{
#ifdef LOG_DSP_ENTER
	log_dsp_enter(my_pcb.p_runtsk);
#endif /* LOG_DSP_ENTER */
  dispatcher_0:
	while ((my_pcb.p_runtsk = my_pcb.p_schedtsk) == NULL) {
		割込みを許可したらCPUロック解除状態になるよう準備する
		非タスクコンテキストに切り換える … (*1)
		do {
			割込みをすべて許可し，割込み発生を待つ … (*2)
			割込み許可前の状態に戻す（＝カーネル管理の割込みを禁止する）
		} while (!my_pcb.reqflg);
		my_pcb.reqflg = false;
		タスクコンテキストに戻す … (*1)
		自プロセッサをCPUロック状態に戻す ... (*3)
	}
	自タスク（my_pcb.p_runtsk）のTCBからスタックポインタを復帰する
#ifdef LOG_DSP_LEAVE
	log_dsp_leave(my_pcb.p_runtsk);
#endif /* LOG_DSP_LEAVE */
	自タスクのTCBから実行再開番地を復帰し，そこへ分岐する … (*a)
}
----------------------------------------

6.5.3 タスクコンテキストからのディスパッチ

ディスパッチ（dispatch）で扱うp_runtskやp_schedtskは，自プロセッサの
pcb(my_pcb)が保持しているものとする．

----------------------------------------
void
dispatch(void)
{
	スクラッチレジスタ(*)を除くすべてのレジスタをスタックに保存する
	スタックポインタを自タスク（my_pcb.p_runtsk）のTCBに保存する
	dispatch_rを，実行再開番地として自タスクのTCBに保存する … (*a)
	dispatcherに分岐する

  dispatch_r:
	スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
	calltex(); … (*b)
}
----------------------------------------

ここでスクラッチレジスタ(*)とは，関数呼出しにより保存されないレジスタの
ことである．必要な場合には，関数を呼び出す側で保存しなければならないた
め，caller saved registerと呼ばれる場合もある

(*b)でcalltexを呼ぶ代わりに，calltexの処理内容（p_runtsk->enatexがtrue
で，p_runtsk->texptnが0でなく，ipmflgがtrueの場合に，call_texrtnを呼ぶ）
をここにインライン展開した方が効率がよい．ターゲット非依存部のcalltexを
使わない場合には，OMIT_CALLTEXをマクロ定義することで，ターゲット非依存
部からcalltexを取り除くことができる．

6.5.4 ディスパッチャの動作開始

(6-5-4-1) void start_dispatch(void)

ディスパッチャの動作開始（start_dispatch）で扱うCPUロック状態・割込み
優先度マスクは，start_dispatchを実行しているプロセッサのものを対象とす
る．

----------------------------------------
void
start_dispatch(void)
{
	タスクコンテキストに切り換える
	自プロセッサをCPUロック状態・割込み優先度マスク全解除状態にする
	dispatcher_0に分岐する
}
----------------------------------------

6.5.5 現在のコンテキストを捨ててディスパッチ

(6-5-5-1) void exit_and_dispatch(void)

ASPカーネルから変更なし．

6.5.6 タスクの起動処理

(6-5-6-1) void activate_context(TCB *p_tcb)

activate_contextとstart_rの処理内容は次の通り．

----------------------------------------
void
activate_context(TCB *p_tcb)
{
	指定されたタスク（p_tcb）のTCB中のスタックポインタを初期化する
	start_rを，実行再開番地として自タスクのTCBに保存する … (*a)
	return;

  start_r:
	CPUロック解除状態にする
	自タスク（p_runtsk）の起動番地を，拡張情報をパラメータとして呼び出す
	ext_tskに分岐する ... (*c)
}
----------------------------------------

(*c)でext_tskを呼ぶ代わりに，自タスクの起動番地を呼び出す時の返り番地を
ext_tskの番地としておく方法がある．

(*a)において，実行再開番地をスタックに保存／復帰する方法をとる場合には，
この時点でスタックを使ってはならないため，この処理を例外扱いしなければ
ならない．

6.6 割込みハンドラ

マルチプロセッサのハードウェア割込みのタイプは大きく二つに分けることが
できる．1つ目は，単一の割込みコントローラを全てのプロセッサで共有して
おり，割込みを任意のプロセッサで受け付けることが出来るタイプで，SMP割
込み型と呼ぶ．もう一方は，プロセッサ毎に割込みコントローラを持ち，割込
みは特定のプロセッサに固定されているタイプで，AMP割込み型と呼ぶ．

割込み番号と割込みハンドラ番号を引数とする関数については，上位ビットフ
ィールドに（32bitの場合は上位16bit）に割込みを受け付けるプロセッサのプ
ロセッサIDがが指定された値が渡されるため，必要に応じてマスクしてから扱
うこと．

割込み管理のための管理ブロックは，ターゲット依存部のコンフィギュレータ
テンプレートファイル（target.tf）内で生成する．SMP割込みの場合は，シス
テムで単一の管理ブロックを生成するのが一般的であり，AMP割込みの場合は，
プロセッサ毎に管理ブロックを生成するのが一般的である．

6.6.1 割込みハンドラの出入口処理

割込みの出入口処理で扱うreqflg/dspflg/p_runtsk/p_schedtskは，自プロセ
ッサのpcb(my_pcb)が保持しているものとする．

----------------------------------------
void
<割込みの出入口処理>(void)
{
	少なくともカーネル管理の割込みを禁止した状態にする … (*f)
	スクラッチレジスタをスタックに保存する
#ifdef プロセッサロック or 細粒度ロック
	if (自プロセッサのPCBのp_firstlock != NULL) {
		p_firstlockのロックを解放する．
		p_firstlockをNULLに設定．
		if (自プロセッサのPCBのp_secondlock != NULL) {
			p_secondlockのロックを解放する．
			p_secondlockをNULLに設定．
		}
   
#endif /* プロセッサロック or 細粒度ロック */
	if (タスクコンテキストで割込み発生) {
		スタックを非タスクコンテキスト用のスタックに切り換え，
								非タスクコンテキストに切り換える
	}

	割込み優先度マスクを，受け付けた割込み要求の割込優先度に設定し，
				CPUロック解除状態にする（受け付けた割込みよりも
				優先度の高い割込みを受け付けるようにする）… (*i)

#ifdef LOG_INH_ENTER
	log_inh_enter(割込みハンドラ番号);
#endif /* LOG_INH_ENTER */
	割込みハンドラを呼び出す
#ifdef LOG_INH_LEAVE
	log_inh_leave(割込みハンドラ番号);
#endif /* LOG_INH_LEAVE */

  ret_int:
	force_unlock_spinを呼び出し，スピンロックを取得していれば解放する
	if (タスクコンテキストで割込み発生) {
		カーネル管理の割込み（または，すべての割込み）をマスクする
		スタックをタスク用のスタックに戻し，タスクコンテキストに切り換える
																… (*g)
		if (自プロセッサのPCBのreqflg == true) {
			自プロセッサのPCBのreqflg = false;
			自プロセッサをCPUロック状態にする
			自プロセッサの割込み優先度マスクを，割込み処理前の値に設定する … (*h)
			if (自プロセッサのPCBのdspflg 
					&& 自プロセッサのPCBのp_runtsk != 自プロセッサのPCBのp_schedtsk) {
				スクラッチレジスタを除くすべてのレジスタをスタックに保存する
				スタックポインタを自タスク（自プロセッサのPCBp_runtsk）のTCBに保存する
				ret_int_rを，実行再開番地として自タスクのTCBに保存する … (*a)
				dispatcherに分岐する

			  ret_int_r:
				スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
			}
			calltex(); … (*b)
		}
	}
	割込み処理からのリターン後に，割込み優先度マスクが
									割込み処理前の値に戻るように準備する
	割込み処理からのリターンでCPUロック状態が解除されるよう準備する
	スクラッチレジスタをスタックから復帰する
	割込み処理からのリターン
}
----------------------------------------

6.6.2 割込みハンドラ毎の出入口処理の生成

ASPカーネルから変更なし．

6.6.3 割込みハンドラの設定

(6-6-3-2) void x_define_inh(INHNO inhno, FP int_entry, uint_t affinity_mask)

標準の割込み管理機能の初期化処理では，初期割付けプロセッサにおいて，こ
の関数を実行する．affinity_mask には，割付け可能なプロセッサをビットパ
ターンで渡される．複数のプロセッサで動的に割込みを受け付けるプロセッサ
を変更可能な場合は，affinity_mask で指定されたプロセッサのみで割込みを
受け付けるようにする．

6.6.4 割込み要求ラインの属性の設定

(6-6-4-1) bool_t VALID_INTNO_CFGINT(ID prcid, INTNO intno)（オプション）

intnoが，割込み番号として有効な値である場合にtrue，そうでない場合に
falseを返すマクロ．prcidのプロセッサから割込み要求ラインの属性を設定で
きないintnoに対しては，このマクロがfalseを返すようにする．

(6-6-4-2) void x_config_int(INTNO intno, ATR intatr, PRI intpri, uint_t affinity_mask)

標準の割込み管理機能の初期化処理では，初期割付けプロセッサにおいて，こ
の関数を実行する．affinity_mask には，割付け可能なプロセッサをビットパ
ターンで渡される．複数のプロセッサで動的に割込みを受け付けるプロセッサ
を変更可能な場合は，affinity_mask で指定されたプロセッサのみで割込みを
受け付けるようにする．

6.6.5 割込み管理機能の初期化処理の変更

ASPカーネルから変更なし．

6.6.6 デフォルトの割込みハンドラ

ASPカーネルから変更なし．

6.6.7 カーネル管理外の割込み

ASPカーネルから変更なし．

6.6.8 割込みサービスルーチンの生成

ASPカーネルから変更なし．

6.6.9 割込み番号・割込みハンドラ番号のマルチプロセッサ拡張

割込み番号に関しては，複数のプロセッサに接続された割込み要求ラインに対
しては，割込み番号の上位ビットを0とし，1つのプロセッサのみに接続された
割込み要求ラインに対しては，割込み番号の上位ビット(32bitの場合は上位
16bit)に接続されたプロセッサのID番号を含める．例えば，プロセッサID 2 
のプロセッサのみに接続された識別番号が 3 の割込み要求ラインの32bitCPU
での割込み番号は，0x00020003 となる．

割込みハンドラ番号に関しては，上位ビット(32bitの場合は上位16bit)に，そ
の割込みハンドラを実行するプロセッサのID番号を含める．例えば，プロセッ
サID 2 プロセッサで実行する識別番号が 4 の割込みハンドラの32bitCPUでの
割込みハンドラ番号は，0x00020004 となる．

6.7 CPU例外ハンドラとCPU例外発生時のシステム状態の参照

6.7.1 CPU例外ハンドラの出入口処理

CPU例外の出入口処理で扱うreqflg/dspflg/p_runtsk/p_schedtskは，自プロセ
ッサのPCBが保持しているものとする．また，各状態はCPU例外の出入口処理を
実行しているプロセッサのものを対象とする．

----------------------------------------
void
<CPU例外の出入口処理>(void)
{
	スクラッチレジスタをスタックに保存する
	if (カーネル管理外のCPU例外) {
		if (タスクコンテキストでCPU例外発生) {
			スタックを非タスクコンテキスト用のスタックに切り換え，
									非タスクコンテキストに切り換える … (*j)
		}
		システム状態（コンテキストは除く）を，CPU例外発生時の状態にする
		CPU例外ハンドラを，CPU例外の情報を記憶している領域の先頭番地を
									パラメータ（p_excinf）として呼び出す
		if (タスクコンテキストでCPU例外発生) {
			スタックをタスク用のスタックに戻し，
									タスクコンテキストに切り換える … (*j)
		}
		CPU例外処理からのリターン後に，CPU例外発生時のシステム状態に
													戻るように準備する
	}
	else {
		if (タスクコンテキストでCPU例外発生) {
			（少なくとも）カーネル管理の割込みを禁止した状態にする
			スタックを非タスクコンテキスト用のスタックに切り換え，
									非タスクコンテキストに切り換える
		}
		CPU例外発生時にスピンロックを取得していたか（自プロセッサのPCBのlocspnid）保存する
		割込み優先度マスクを，CPU例外発生時の値に設定し，
				CPUロック解除状態にする（CPU例外発生時の割込み優先度マスク
				よりも優先度の高い割込みを受け付けるようにする）
#ifdef LOG_EXC_ENTER
		log_exc_enter(CPU例外ハンドラ番号);
#endif /* LOG_EXC_ENTER */
		CPU例外ハンドラを，CPU例外の情報を記憶している領域の先頭番地を
										パラメータ（p_excinf）として呼び出す
#ifdef LOG_EXC_LEAVE
		log_exc_leave(CPU例外ハンドラ番号);
#endif /* LOG_EXC_LEAVE */

	  ret_exc:
		if (CPU例外発生時にスピンロック未取得) {
			force_unlock_spinを呼び出し，スピンロックを取得していれば解放する
		}
		if (タスクコンテキストでCPU例外発生) {
			自プロセッサでカーネル管理の割込み（または，すべての割込み）をマスクする
			スタックをタスク用のスタックに戻し，タスクコンテキストに切り換える
																	… (*g)
			if (自プロセッサのPCBのreqflg) {
				自プロセッサのPCBのreqflg = false;
				自プロセッサをCPUロック状態にする
				if (自プロセッサのPCBのdspflg 
					&& 自プロセッサのPCBのp_runtsk != 自プロセッサのPCBのp_schedtsk) {
					スクラッチレジスタを除くすべてのレジスタをスタックに保存する
					スタックポインタを自タスク（自プロセッサのPCBのp_runtsk）のTCBに保存する
					ret_exc_rを，実行再開番地として自タスクのTCBに保存する … (*a)
					dispatcherに分岐する

				  ret_exc_r:
					スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
				}
				calltex(); … (*b)
			}
		CPU例外処理からのリターンで，自プロセッサのCPUロック状態／ロック解除状態が
									CPU例外発生時の状態に戻るように準備する
	}
	スクラッチレジスタをスタックから復帰する
	CPU例外処理からのリターン
}
----------------------------------------

6.7.2 CPU例外ハンドラの出入口処理の生成

ASPカーネルから変更なし．

6.7.3 CPU例外ハンドラの設定

ASPカーネルから変更なし．

6.7.4 CPU例外管理機能の初期化処理の変更

ASPカーネルから変更なし．

6.7.5 デフォルトのCPU例外ハンドラ

ASPカーネルから変更なし．

6.7.6 CPU例外発生時のシステム状態の参照

ASPカーネルから変更なし．

6.7.7 CPU例外ハンドラ番号のマルチプロセッサ拡張

異なるプロセッサで発生するCPU例外は，異なるCPU例外であると扱うため，同
じ種類のCPU例外であっても，異なるプロセッサのCPU例外には異なるCPU例外
ハンドラ番号を付与し，プロセッサ毎にCPU例外ハンドラを登録する．

CPU例外ハンドラ番号の上位ビットフィールド（32bitの場合は上位16bit）を
プロセッサ指定としてプロセッサIDを表し，下位ビットフィールド（32bitの
場合は下位16bit）をプロセッサ内CPU例外を識別するために用いる．例えば，
プロセッサID 2 CPU例外の識別番号が 4 で32bitのCPU例外ハンドラ番号は 
0x00020004 となる．

6.8 カーネルの起動・終了とスタック領域など

(6-8-1) スタートアップモジュール

スタートアップモジュールでは，プロセッサのモード設定やスタックポインタ
の設定といった，各コアのプライベートな設定は各コアで行う．一方，共有メ
モリのbssセクションのクリアと，dataセクションの初期化といった，共有リ
ソースの初期化処理は可能な限りマスタプロセッサで行う．共通リソースの初
期化処理としての初期化用のC言語関数（target_mprc_initialize）を呼び出
すこと．

マスタプロセッサ以外は，マスタプロセッサによる共有リソースの初期化処理
の終了を待ち合わせる．マスタプロセッサによる共有リソースの初期化処理の
終了後，各プロセッサでsta_kerを呼び出す．

カーネルの起動シーケンスを次に示す．

             マスタプロセッサ                        その他のプロセッサ
                             (a)自ハードウェアの初期化       
                             (b)hardware_init_hook()の呼び出し 
                             (c)bss/data初期化              
               (d)software_init_hook()の呼び出し
               (e)target_mprc_initialize()の呼び出し
(f)バリア同期1 ---------------------------------------------------------
                             (g)sta_ker()の呼び出し
(h)バリア同期2 ---------------------------------------------------------
                    グローバル初期化ルーチン（マスタプロセッサのみ）
(i)バリア同期3 ---------------------------------------------------------
                    ローカル初期化ルーチン（各プロセッサ）
(j)バリア同期4 ---------------------------------------------------------
                    (k)カーネルの動作を開始

(a)自ハードウェアの初期化

システムのリセット後すぐに各プロセッサで行う必要のある初期化処理を行う．

(b)hardware_init_hookの呼び出し

システムのリセット後すぐに行う必要のあるターゲットシステム依存の初期化
処理を行う．SMPタイプのハードウェアでは，マスタプロセッサのみ実行する
のが一般的である．プライベートリソースが存在する場合はそれぞのプロセッ
サで初期化する．

(c)bss/data初期化    

C言語を動作させるための，メモリの初期化を行う．マスタプロセッサのみ行
うのが一般的である．プライベートメモリは，それぞれのプロセッサで初期化
する．

(d)software_init_hook()の呼び出し

開発環境（特にライブラリ）に依存して必要な初期化処理を行う．一般的には，
マスタプロセッサのみで行う．

(e)target_mprc_initialize()の呼び出し

マスタプロセッサで事前に初期化する必要があるハードウェアを初期化する．
target_initialize()の前に必要なハードウェアの初期化を想定している．

(f)バリア同期1

sta_ker()を呼び出す前にスタートアップモジュール内でバリア同期を行う．

(g)sta_ker呼び出し

sta_kerを呼び出し，ターゲット依存の初期化やオブジェクトの初期化を行う．

(h)バリア同期2

グローバル初期化ルーチン呼び出し前の同期．この後，マスタプロセッサでグ
ローバル初期化ルーチンを呼び出す．

(i)バリア同期3

グローバル初期化ルーチンの終了後，各プロセッサでローカル初期化ルーチン
を呼び出す前の同期．

(j)バリア同期4

全てのプロセッサでのローカル初期化ルーチンの実行を待ち合わせるための同
期．

(m)カーネルの動作を開始

ディスパッチャを呼び出してカーネルの動作を開始する．

(6-8-2) void target_initialize(void)

ASPカーネルから変更なし．

(6-8-3) void call_exit_kernel(void)

ASPカーネルから変更なし．

(6-8-4) void target_exit(void)

ASPカーネルから変更なし．

(6-8-5) void target_mprc_initialize(void)

sta_ker呼び出し前にマスタプロセッサで事前に初期化する必要があるハード
ウェアを初期化するための関数．

(6-8-6) OMIT_BARRIER_SYNC

カーネルの動作スタート/終了時用のバリア同期の関数を共通部で定義された
物ではなく，依存部で用意した関数を用いる場合に定義する．

(6-8-7) void barrier_sync(uint_t phase);

カーネルの動作スタート/終了時用のバリア同期の関数．OMIT_BARRIER_SYNCを
定義して，ターゲット依存部でバリア同期の関数を定義する場合にこの仕様で
定義する．引数のphaseは同期のフェーズが指定される．

(6-8-8) カーネルの終了

カーネルの終了シーケンスを次に示す．ext_ker()を呼び出されたプロセッサ
から他のプロセッサに対して終了処理を要求してシステム全体をシャットダウ
ンさせる．

         あるプロセッサでのext_ker()呼び出し
          カーネル動作状態から非動作状態へ
            (a)他のプロセッサへの通知
                                  他のプロセッサでのext_ker()呼び出し
                                   カーネル動作状態から非動作状態へ
                      (b)exit_kernel()呼び出し
(c)バリア同期1 ---------------------------------------------------------
                  ローカル終了処理ルーチン（各プロセッサ）
(d)バリア同期2 ---------------------------------------------------------
                グローバル終了処理ルーチン（マスタプロセッサのみ）
(e)バリア同期3 ---------------------------------------------------------
                     (f)target_exit()の呼び出し

(a)他のプロセッサへの通知

標準では，共通部で用意されているディスパッチ要求用のプロセッサ間割込み
を流用した関数を用いる．ターゲット依存部で定義したい場合は，後述のマク
ロを定義すればよい．

(b)exit_kernel()呼び出し

非タスクコンテキストに切り替えてexit_kernel()を呼び出しす．

(c)バリア同期1

全てのプロセッサでの終了処理の開始を同期させるため，exit_kernel()の入
り口で同期する．

(d)バリア同期2

各プロセッサでのローカル終了処理ルーチンの実行の終了を待ち合わせる．

(e)バリア同期3

マスタプロセッサによるグローバル終了処理ルーチンの実行の終了を待ち合わ
せる．

(f)target_exit()の呼び出し

target_exit()を順に呼び出して，終了処理を終わらせる．


(6-8-9) 終了処理関連の関数

ターゲット依存部では，カーネル終了処理要求関数（必要ならば）用意する．
バリア同期関数に関しては，起動処理と同じ関数を用いるため，終了処理用に
用意する必要はない．

(6-8-9-1) OMIT_KER_REQ_ON_IPI

他のプロセッサに対するカーネル終了処理要求をディスパッチ要求用のプロセ
ッサ間割込みハンドラで兼用させない場合に定義する．

(6-8-9-2) void ext_ker_request(void)

他のプロセッサに対するカーネル終了処理要求をディスパッチ要求用のプロセ
ッサ間割込みハンドラで兼用させない場合に，ターゲット依存部で用意する．
カーネル終了処理関数（ext_ker()）で呼び出される．

6.9 カーネル内部のチューニング

6.9.1 ビットマップサーチ

ASPカーネルから変更なし．

6.9.2 ビットフィールド

ASPカーネルから変更なし．

6.10 カーネル実装に関するその他の定義

6.10.1 ターゲット依存のオブジェクト属性

6.10.2 エラーチェック方法の指定

6.10.3 非タスクコンテキスト用のスタック領域

(6-10-3-1) DEFAULT_PRC<プロセッサID>_ISTKSZ

DEF_ICSにより非タスクコンテキスト用のスタック領域が指定されない場合の，
デフォルトのスタック領域のサイズ（バイト数）．プロセッサ毎に定義する．

(6-10-3-2) DEFAULT_PRC<プロセッサID>_ISTK（オプション）

DEF_ICSにより非タスクコンテキスト用のスタック領域が指定されない場合の，
デフォルトのスタック領域の先頭番地．このマクロが定義されない場合には，
サイズがDEFAULT_ISTKSZのスタック領域が，配列により確保される．プロセッ
サ毎に定義する．

6.10.4 空ラベルの定義

ASPカーネルから変更なし．

6.11 トレースログ機能に関する設定

6.11.1 取得できるトレースログの種類とマクロ

(f) タスクマイグレーション

次のマクロを定義することで，タスクがマイグレーションした時のトレースロ
グを取得することができる．

	LOG_TSKMIG(p_tcb, src_id, dest_id)	タスクマイグレーション

6.11.2 トレースログ記録のサンプルコード

ASPカーネルから変更なし．

6.12 カーネル実装のターゲット依存部のためのリネーム記述

ASPカーネルから変更なし．

6.13 タイマドライバ

6.13.1 タイマドライバのファイル構成

ASPカーネルから変更なし．

6.13.2 タイマの初期化・終了処理・割込み処理

ASPカーネルから変更なし．

6.13.2 タイマの初期化・終了処理・割込み処理

ASPカーネルから変更なし．

6.13.3 性能評価用システム時刻の参照のための機能

FMPカーネルでは，後述するローカルタイマ方式の場合は，カーネル共通部で
のget_utmをサポートするが，グローバルタイマ方式ではサポートしない．そ
のため，グローバルタイマ方式で，get_utmをサポートしたい場合は，ターゲ
ット依存で用意すること．

6.14 オーバランタイマドライバ（オプション）

FMPカーネルではオーバランタイマをサポートしない．

6.15 動的メモリ管理

FMPカーネルでは動的生成機能拡張パッケージをサポートしない．

6.16 プロセッサ識別

6.16.1 プロセッサINDEX

プロセッサINDEXは，0から連続した番号を個々のプロセッサに割り付けたもの
であり，カーネル内部で使用する．どのプロセッサにどのINDEXを割り付ける
かは，ターゲット依存で決める．

ターゲット依存部は，実行中のプロセッサのプロセッサINDEXを判別する機能
を提供する．

(6-15-1-1) uint_t x_prc_index(void)

処理単位が実行されているプロセッサのINDEXを返す関数．ハードウェアの持
つプロセッサ識別(HW-ID)のためのIDからプロセッサINDEXを求めて返す．
HW-IDが0から連続した値でない場合には，この関数内で適切に変換する．

target_pcb.hまたはそこからインクルードされるファイル（プロセッサ・チッ
プ・開発環境依存部で用意されるヘッダファイルなど）に含める．

6.16.2 マスタプロセッサ

システム中の特定の1個のプロセッサを示す．マスタプロセッサは，オブジェ
クト初期化等を行う．どのプロセッサをマスタプロセッサとするかは，ターゲ
ット依存で決定する．ターゲット依存部では，実行中のプロセッサがマスタプ
ロセッサかを判別する機能を提供する．

(6-15-2-1) bool_t x_sense_mprc(void)

処理単位が実行されているプロセッサがマスタプロセッサならtrue，マスタプ
ロセッサでなければfalseを返す関数．

(6-15-2-2) TOPPERS_MASTER_PRCID

マスタプロセッサのIDをカーネル共通構成マクロとして定義する．

6.17 ロック

6.17.1 ロック方式

ターゲット依存部では，ロック単位の違いによる3種類のロック方式のうちの
一つの方式を選択する．ロックの個数に上限がある場合は，細粒度ロックを選
択することはできない

(6-16-1-1) TTYPE_KLOCK 

ロック方式を指定するマクロ．指定可能な方式は以下のロック方式のうちのい
ずれかである．

target_pcb.hまたはそこからインクルードされるファイル（プロセッサ・チッ
プ・開発環境依存部で用意されるヘッダファイルなど）に含める．

(6-16-1-2) G_KLOCK   ジャイアントロック方式

ジャイアントロック方式を有効にするマクロ．ジャイアントロックは，システ
ムで1つのロックを使用する方式．すべてのシステムコールが排他的に実行さ
れる．

(6-16-1-3) P_KLOCK  プロセッサロック方式

プロセッサロック方式を有効にするマクロ．プロセッサ毎にタスクロックとオ
ブジェクトロックを用いる方式．プロセッサ数 x 2 個のロックが必要．異な
るプロセッサに割り付けられている実行単位へのシステムコールは同時に実行
可能．また，異なるオブジェクトロックプロセッサに割り付けられているオブ
ジェクトへのシス テムコールは同時に実行可能．

(6-16-1-4) F_KLOCK   細粒度ロック方式

細粒度ロック方式を有効にするマクロ．プロセッサ毎にタスクロック，オブジ
ェクト毎にオブジェクトロックを用いる方式．プロセッサ数 + 実行単位とな
らないオブジェクトの数のロックが必要となる．異なるプロセッサに割り付け
られている実行単位へのシステムコールは同時に実行可能．また，異なるオブ
ジェクトへ対するシステムコールは同時に実行可能である．

6.17.2 ロック変数の型定義

ターゲット依存部は，ロック形式毎にロック変数の型を定義する．なお，使用
しないロック形式については定義する必要はない．

target_pcb.hまたはそこからインクルードされるファイル（プロセッサ・チッ
プ・開発環境依存部で用意されるヘッダファイルなど）に含める．

(6-16-2-1) LOCK 

ロック変数の型．target_pcb.hまたはそこからインクルードされるファイル
（プロセッサ・チップ・開発環境依存部で用意されるヘッダファイルなど）に
含める．

ジャイアントロック方式時は，ロック変数はグローバル変数として mp.c 内で
宣言される．

プロセッサロック方式の場合は，タスクロック変数とオブジェクトロック変数
はタスクロック，オブジェクトロック共にPCB内で宣言される．

細粒度ロック方式の場合は，タスクロック変数は，タスクロックはPCB内で宣
言され，オブジェクトロックは，実行単位以外のオブジェクトの管理ブロック
で宣言される．実行単位以外のオブジェクトの各初期化ブロックに，そのオブ
ジェクトのオブジェクトロックプロセッサのオブジェクトロックへのポインタ
を格納する変数が宣言される．

6.17.3 ロック操作関数

ターゲット依存部は，ロック形式毎にロックを操作する機能を提供する．これ
らは，使用しないロック形式の機能は定義する必要はない．各ロック形式と定
義する関数の対応表を以下に示す．

                                     G_KLOCK  P_KLOCK  F_KLOCK
x_initialize_giant_lock()              ○
x_initialize_tsk_lock()                         ○       ○
x_initialize_obj_lock()                         ○       ○
t_acquire_lock()                       ○       ○       ○
i_acquire_lock()                       ○       ○       ○
t_acquire_nested_lock()                         ○       ○
i_acquire_nested_lock()                         ○       ○
x_release_lock()                       ○       ○       ○
x_acquire_lock_without_preemption()    ○       ○       ○

(6-16-3-1) void x_initialize_giant_lock(LOCK *p_giant_lock)

ジャイアントロック方式の初期化関数．カーネル起動時にマスタプロセッサか
ら呼び出される．

(6-16-3-2) void x_initialize_tsk_lock(LOCK *p_tsk_lock)

プロセッサロック/細粒度ロック方式でのタスクロックの初期化関数．カーネ
ル起動時に自プロセッサのタスクロックを対象に呼び出される．

(6-16-3-3) void x_initialize_obj_lock(LOCK *p_obj_lock)

プロセッサロック/細粒度ロック方式でのオブジェクトロックの初期化関数．
カーネル起動時に呼び出される．プロセッサロックの場合は，自プロセッサの
オブジェクトロックを対象に呼び出される．細粒度ロックの場合は，オブジェ
クト毎のオブジェクトロックを対象に呼び出させる．

(6-16-3-4) void t_acquire_lock(LOCK *p_lock);
(6-16-3-5) void i_acquire_lock(LOCK *p_lock);

1段目のロック取得関数．CPUロック状態で呼び出される．p_lockに対してロッ
クをの取得を試み，ロックが取得ができればリターン．ロックが取得ができな
ければ，一旦割込みを許可した後禁止して，ロックの取得を試みる．

(6-16-3-6) bool_t t_acquire_nested_lock(LOCK *p_lock);
(6-16-3-7) bool_t i_acquire_nested_lock(LOCK *p_lock);

2段目のロック取得関数．CPUロック状態で呼び出される．p_lockに対してロッ
クをの取得を試み，ロックが取得ができればfalseをリターン．ロックが取得
ができなければ，一旦割込みを許可した後禁止して，自プロセッサのPCBの
p_firstlockをチェックする．p_firstlockがNULLならtrueを返す．
p_firstlockがNULLでないなら，ロックの取得を試みる．

(6-16-3-8) void x_release_lock(LOCK *p_lock)

ロック解放関数．CPUロック状態で呼び出される．p_lockのロックを解放する．

(6-16-3-9) void x_acquire_lock_without_preemption(LOCK *p_lock)

割込みを許可しないロック取得関数．CPUロック状態で呼び出される．p_lock
の取得を試み，取得できればリターンする．

6.18 システム時刻の管理方式

システム時刻の管理方式としては，プロセッサ毎に個別にタイマを持つローカ
ルタイマ方式と，システムで一つのタイマを用いるグローバルタイマ方式の2
種類をサポートする．グローバルタイマ方式では，ロック方式はジャイアント
ロックのみをサポートする．

(6-17-1) TOPPERS_SYSTIM_GLOBAL 

グローバルタイマ方式を有効にするマクロ．

(6-17-2) TOPPERS_SYSTIM_LOCAL

ローカルタイマ方式を有効にするマクロ．

(6-17-3) TOPPERS_SYSTIM_PRCID

グローバルタイマ方式の場合のシステム時刻管理プロセッサのIDを指定．

6.19 プロセッサ間割込みドライバ

6.19.1 プロセッサ間割込みドライバのファイル構成

プロセッサ間割込みドライバを組み込むための静的APIを記述したシステムコ
ンフィギュレーションファイルを，target_ipi.cfgに用意する．このファイル
には，プロセッサ間割込みドライバを初期化するための初期化ルーチンの追加，
プロセッサ間割込みを停止させるための終了処理ルーチンの追加（必要ならば），
プロセッサ間割込みのための割込みハンドラの定義（または，割込みサービス
ルーチンの追加），プロセッサ間割込みのための割込み要求ラインの属性の設
定の静的APIなどを含むことになる．

プロセッサ間割込みドライバを呼び出すために必要な定義を含むヘッダファイ
ルを，target_ipi.hに用意する．また，必要であれば，プロセッサ間割込みド
ライバの実装ファイルをtarget_ipi.cに用意する．

6.19.2 プロセッサ間割込みの初期化・終了処理・割込み処理

(6-18-2-1) void target_ipi_initialize(intptr_t exinf)

プロセッサ間割込み初期化し，プロセッサ間割込み発行可能とする関数．この
関数は，target_ipi.cfg 中に記述する静的APIにより，初期化ルーチンとして
カーネルに登録することを想定している．必要としない場合は，用意する必要
はない．

(6-18-2-2) void target_ipi_terminate(intptr_t exinf)

プロセッサ間割込みを停止させ，プロセッサ間割込みを発生しないようにする
関数．この関数は，target_ipi.cfg 中に記述する静的APIにより，終了処理ル
ーチンとしてカーネルに登録することを想定している．必要としない場合は，
用意する必要はない．

6.19.3 プロセッサ間割込みの発行とクリア

(6-18-3-1) void target_ipi_raise(uint_t prcid)

プロセッサ間割込みを発行する関数．引数には割込み発生先のプロセッサのID
が指定される．

(6-18-3-2) void target_ipi_clear(void)

プロセッサ間割込みをクリアする関数．プロセッサ間割込みを受け付けたプロ
セッサで起動されるプロセッサ間割込みハンドラで呼び出される．

6.19.4 プロセッサ割込みハンドラの登録

共通部では，プロセッサ間割込みで呼び出される割込みハンドラ 
ipi_handler() が用意されている．

この関数は，target_ipi.cfg中に記述する静的APIにより，割込みハンドラま
たは割込みサービスルーチンとしてカーネルに登録することを想定している．
なお，割込み要求禁止フラグを許可するように登録すること．

6.19.5 プロセッサ割込みハンドラ呼び出しの省略

ターゲット依存の最適化として，プロセッサ間割込み受け付け時に，上記の割
込みハンドラを呼び出さず，自プロセッサのreqflgをtrueをとして，割込みの
出口処理(ret_int)を呼び出すことが可能である．

6.20 プロセッサコントロールブロック

ターゲット依存でプロセッサ毎に必要な変数は，ターゲット依存のプロセッサ
コントロールブロック（TPCB）としてまとめ，PCB内でプロセッサ毎に生成さ
れる．TPCBの定義は，target_pcb.hまたはそこからインクルードされるファイ
ル（プロセッサ・チップ・開発環境依存部で用意されるヘッダファイルなど）
に含める．

target_pcb.hまたはそこからインクルードされるファイルには，以下の内容を
含める必要がある．

  ・前方参照用のPCBのtypedef宣言
    typedef struct processor_control_block PCB
  ・TPCBの定義
  ・(6-14-1-1) uint_t x_prc_index(void) の定義
  ・6.17.1 ロック方式 の指定
  ・6.17.2 ロック変数の型定義

(6-19-1) OMIT_TARGET_PCB

ターゲット依存のプロセッサコントロールブロックが必要でない場合に定義す
る．

(6-19-2) OMIT_GET_MY_P_PCB

共通部で定義されている自プロセッサのプロセッサコントロールブロックへの
ポインタを取得するための関数（PCB* get_my_p_pcb(void)）を使用しない場
合に定義する．定義した場合は，ターゲット依存部で，get_my_p_pcb() を定
義する必要がある．

(6-19-3) OMIT_GET_MY_P_TPCB

共通部で定義されている自プロセッサのプロセッサ依存のターゲットコントロ
ールブロックへのポインタを取得するための関数（TPCB* get_my_p_tpcb(void)）
を使用しない場合に定義する．定義した場合は，ターゲット依存部で，
get_my_p_tpcb() を定義する必要がある．

6.21 スピンロック

6.21.1 スピンロック方式

カーネルオブジェクトのスピンロックの実現方式としては，スピンロックオブ
ジェクトとハードウェアのスピンロックを1対1に対応させたネイティブ方式と，
オブジェクトロックにより，擬似的にスピンロックを実現するエミュレーショ
ン方式の2種類をサポートする．

6.21.2 スピンロック方式の指定

(6-19-2-1) TTYPE_SPN

スピンロックの実現方式を指定するのマクロ．下記のいずれかに定義する．

(6-19-2-2) NATIVE_SPN   ネイティブ方式の指定
(6-19-2-3) EMULATE_SPN  エミュレーション方式の指定

(6-19-2-4) TMAX_NATIVE_SPN  ロックの最大数

ネイティブ方式の場合に，サポートするロックの最大数を定義するマクロ．

6.21.3 スピンロック関連の型

(6-19-3-1)   SPNLOCK   ロック変数の型

ネイティブ方式の場合の，ハードウェアスピンロックで用いるロック変数の型．

6.21.4 スピンロックの初期化・取得・解放機能

ネイティブ方式の場合は，ターゲット依存部でスピンロックの，取得，解放の
機能を提供する必要がある．
     
(6-19-4-1) void x_initialize_spin(ID spnid, SPNLOCK *p_spn_lock)

スピンロックの初期化関数．初期化時に呼び出される．

(6-19-4-2) void t_lock_spin(SPNLOCK *p_spn_lock)
(6-19-4-3) void i_lock_spin(SPNLOCK *p_spn_lock)

スピンロックの取得関数．CPUロック状態で呼び出される．ハードウェアスピ
ンロックが取得を試み，取得できればリターンする．取得できない場合は，一
旦割込みを許可した後，再び割込みを禁止した後にハードウェアスピンロック
が取得を試みる．スピンロック取得状態で呼び出されることはなく，呼び出さ
れた場合の動作は保証する必要がない．

(6-19-4-4) bool_t x_try_lock_spin(SPNLOCK *p_spn_lock)

スピンロックの取得の試行関数．CPUロック状態で呼び出される．ハードウェ
アスピンロックが取得できればfalseを返す．取得できない場合は，trueを返
す．スピンロック取得状態で呼び出されることはなく，呼び出された場合の動
作は保証する必要がない．
       
(6-19-4-5)  void x_unlock_spin(SPNLOCK *spn_lock)

スピンロックの解放関数．CPUロック解除状態，スピンロックを返却した状態
で呼び出されることはなく，呼び出された場合の動作は保証する必要がない．

6.22 タスクマイグレーション

ターゲット依存部は，タスクマイグレーションをサポートするため，自タスク
のマイグレーションサポート関数，タスク終了時のマイグレーションサポート
関数を定義する．

6.22.1 自タスクのマイグレーションサポート

自タスクのマイグレーションサポート（dispatch_and_migrate）は，タスクコ
ンテキストから自タスクのマイグレーション時に呼び出される．CPUロックか
つ，移動元と移動先のロックを取得した状態で，マイグレーション先のプロセ
ッサIDを引数に呼び出される．

dispatch_and_migrateの処理内容は次の通り
．
----------------------------------------
void
dispatch_and_migrate(ID prcid)
{
	スクラッチレジスタを除くすべてのレジスタをスタックに保存する
	スタックポインタを自タスク（自プロセッサのPCBのp_runtsk）のTCBに保存する
	dispatch_rを，実行再開番地として自タスクのTCBに保存する 
	スタックを非タスクコンテテキスト用のスタックに切り替える
	migrate_self(prcid)
}

6.22.2 タスク終了時のマイグレーションサポート

タスク終了時のマイグレーションサポート関数（exit_and_migrate）．タスク
コンテキストで，ext_tsk() を呼び出した結果，キューイングされているマイ
グレーション処理を実行する際に呼び出される．CPUロックかつ，移動元と移
動先のロックを取得した状態で，マイグレーション先のプロセッサIDを引数に
呼び出される．

exit_and_migrateの処理内容は次の通り．

----------------------------------------
void
exit_and_migrate(ID prcid)
{
	スタックを非タスクコンテテキスト用のスタックに切り替える
	exit_and_migrate_self(prcid)
}


７．コンフィギュレータ設定ファイル

7.1 設定ファイルとターゲット依存部の位置付け

ASPカーネルから変更なし．

7.2 パス2のテンプレートファイルのターゲット依存部

7.2.1 ターゲット非依存部をインクルードする前に定義すべき変数

(7-2-2) INHNO_ATTISR_VALID		INTNO_ATTISR_VALIDに対応する割込ハンドラ番号

グローバルな割込み要求ラインに対する割込みハンドラ番号には，上位ビット
が0の割込みハンドラ番号を設定する．  

(7-2-21)TARGET_CHECK_ATT_ISR（オプション）

ターゲット依存でATT_ISRのクラス割付けのチェックを行う場合に定義する関
数．TARGET_CHECK_ATT_ISR には，ATT_ISRのオーダ番号がパラメータとして渡
される．

「intnoで指定した割込み要求ラインが接続されたプロセッサの集合」が任意
の集合の場合に，呼び出される．「単一プロセッサ」or「全プロセッサ」の場
合は、非依存部で対応するため，呼び出さない．


7.2.2 ターゲット非依存部で定義される変数

7.2.3 クラス関連の定義

ターゲット依存部のパス2のテンプレートファイルでは，ターゲット非依存部
をインクルードする前に以下の事項を定義する必要がある．

(7-2-3-1) NUM_CLASS

クラスの数を指定する．

7.2.4 クラス内容の定義（連想配列）

ターゲット依存部のパス2のテンプレートファイルでは，ターゲット非依存部
をインクルードする前にクラス毎に以下の事項を連想配列として定義する必要
がある．連想配列の添え字には，クラスのIDを指定する．

  1.処理単位の初期割付けプロセッサ
  2.処理単位の割付け可能プロセッサ
  3.オブジェクトロックプロセッサの指定（プロセッサロックの場合）

(7-2-4-1) CLASS_AFFINITY_INI

初期割付けプロセッサのプロセッサIDを指定する．

(7-2-4-2) CLASS_AFFINITY_MASK

マイグレーション可能なプロセッサをマスクで指定する．LSBから順に，プロ
セッサID番号"1","2","3"...に対応する．マイグレーション可能な場合は，該
当するビットを1に指定する．

(7-2-4-3) CLASS_OBJ_LOCK

プロセッサロック方式の場合，各オブジェクトのオブジェクトロックとして使
用するプロセッサのプロセッサIDを指定する．

7.2.5 クラス内容の定義（関数）

以下に示すオブジェクト管理ブロック等の配置を制御するため，ターゲット依
存部のパス2のテンプレートファイルにおいて， カーネルの構成・初期化ファ
イル（kernel_cfg.c に)おいて変数を宣言する関数を用意する．なお，これら
の関数を宣言しない場合は，特に配置指定を行わない変数の宣言が生成される．
引数は対象のオブジェクトのID番号である．これらの変数の多くは，ローカル
メモリないし，グローバルメモリに配置可能である．タスクスタックはプライ
ベートメモリに配置可能である．

  1.カーネルオブジェクトのコントロールブロックの配置場所
  2.カーネルオブジェクトのコントロールブロック以外のメモリ領域（タスク
    スタック，データキューやメモリプール等バッファ領域の配置場所

(7-2-5-1)  GENERATE_TCB(tskid)   タスク管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	TCB _kernel_tcb_$tskid$;$NL$

(7-2-5-2)  GENERATE_SEMCB(semid) セマフォ管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	SEMCB _kernel_semcb_$semid$;$NL$

(7-2-5-3)  GENERATE_FLGCB(flgid) イベントフラグ管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	FLGCB _kernel_flgcb_$flgid$;$NL$

(7-2-5-4)  GENERATE_DTQCB(dtqid) データキュー管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	DTQCB _kernel_dtqcb_$dtqid$;$NL$

(7-2-5-5)  GENERATE_PDQCB(pdqid) 優先度データキュー管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	PDQCB _kernel_pdqcb_$pdqid$;$NL$

(7-2-5-6)  GENERATE_MBXCB(mbxid) メールボックス管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	MBXCB _kernel_mbxcb_$mbxid$;$NL$

(7-2-5-7)  GENERATE_MPFCB(mpfid) 固定長メモリブロック管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	MPFCB _kernel_mpfcb_$mpfid$;$NL$

(7-2-5-8)  GENERATE_CYCCB(cycid) 周期ハンドラ管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	CYCCB _kernel_cyccb_$cycid$;$NL$

(7-2-5-9)  GENERATE_ALMCB(almid) アラームハンドラ管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	ALMCB _kernel_almcb_$almid$;$NL$

(7-2-5-10) GENERATE_SPNCB(spnid) スピンロック管理ブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	SPNCB _kernel_spncb_$spnid$;$NL$

(7-2-5-11) GENERATE_TSKSTK(tskid) タスクスタックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static STK_T _kernel_stack_$tskid$[COUNT_STK_T($TSK.STKSZ[tskid]$)];$NL$

(7-2-5-12) GENERATE_DTQMB(dtqid)  データキュー領域の宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static intptr_t _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$

(7-2-5-13) GENERATE_PDQMB(pdqid)  優先度データキュー領域の宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$

(7-2-5-14) GENERATE_MPF_T(mpfid)  固定長メモリブールバッファの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$

(7-2-5-15) GENERATE_MPFMB(mpfid)  固定長メモリプール管理領域の宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$

7.2.6 プロセッサ毎のデータ構造の配置場所

ターゲット依存部のパス2のテンプレートファイルでは，ターゲット非依存部
をインクルードする前に，カーネルの構成・初期化ファイル（kernel_cfg.c 
に)おいて宣言されるカーネル内でプロセッサ毎に必要となる以下のデータ構
造に対して，配置先の指定のための関数を定義する．なお，これらの関数を宣
言しない場合は，特に配置指定を行わない変数の宣言が生成される．

 1.PCB
   ・他プロセッサからアクセス可能な領域に配置すること．
 2.非タスクコンテキスト用のスタック
    ・自プロセッサからのみアクセスできる領域に配置可能．
 3.タイムイベント関連データ   
   3.1タイムイベントコントロールブロック
    ・他プロセッサからアクセス可能な領域に配置すること．
   3.2タイムイベントヒープ
    ・他プロセッサからアクセス可能な領域に配置すること．

(7-2-6-1) GENERATE_PCB(prcid) プロセッサコントロールブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	PCB _kernel_prc$prcid$_pcb;$NL$

(7-2-6-2) GENERATE_ISTACK(prcid) 非タスクコンテキスト用スタックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static STK_T	_kernel_prc$prcid$_istack[COUNT_STK_T(DEFAULT_PRC$prcid$_ISTKSZ)];$NL$

(7-2-6-3) GENERATE_ISTACK_ICS(prcid, icsid) ICS使用時の非タスクコンテキスト用スタックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	static STK_T	_kernel_prc$prcid$_istack[COUNT_STK_T($ICS.ISTKSZ[icsid]$)];$NL$

(7-2-6-4) GENERATE_TMEVTN_HEAP(prcid) タイムイベントヒープの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	TMEVTN	_kernel_prc$prcid$_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$

(7-2-6-5) GENERATE_TMEVTN_HEAP_SYSTIM_GLOBAL() グローバルタイマ方式時のタイムイベントヒープの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	TMEVTN	_kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$

(7-2-6-6) GENERATE_GENERATE_TEVTCB(prcid) タイムイベントコントロールブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	TEVTCB	_kernel_prc$prcid$_tevtcb;$NL$

(7-2-6-7) GENERATE_GENERATE_TEVTCB_SYSTIM_GLOBAL(prcid) グローバルタイマ方式時のタイムイベントコントロールブロックの宣言関数

未宣言の場合は，次のフォーマットで変数宣言が生成される．

	TEVTCB	_kernel_tevtcb;$NL$

7.3 パス3のテンプレートファイルのターゲット依存部

ASPカーネルから変更なし．

7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル

FMPカーネルでは，target_cfg1_out.h（または，そこからインクルードされる
ファイル）に，典型的には，以下のような定義を含める必要がある．

----------------------------------------
void sta_ker(void)
{
}

void hardware_init_hook(void)
{
}

void software_init_hook(void)
{
}

void _kernel_target_mprc_initialize(void)
{
}

STK_T *const _kernel_istk_table[TNUM_PRCID];

const SIZE _kernel_istksz_table[TNUM_PRCID];

STK_T *const	_kernel_istkpt_table[TNUM_PRCID];
----------------------------------------

８．システムサービス等のターゲット依存部

8.0 システムサービスのターゲット依存部
  
ASPカーネルから変更なし．

8.1 システムログ機能のターゲット依存定義
   
(8-1-3) SEC_SYSLOG        G_SYSLOG時のシステムログ機能用変数の配置マクロ（オプション）
(8-1-4) SEC_PRC1_SYSLOG   プロセッサ1用のシステムログ機能用変数の配置マクロ（オプション）
(8-1-5) SEC_PRC2_SYSLOG   プロセッサ2用のシステムログ機能用変数の配置マクロ（オプション）
(8-1-6) SEC_PRC3_SYSLOG   プロセッサ3用のシステムログ機能用変数の配置マクロ（オプション）
(8-1-7) SEC_PRC4_SYSLOG   プロセッサ4用のシステムログ機能用変数の配置マクロ（オプション）

システムログ機能が使用する変数の配置場所指定（セクション指定）の指定方
法を定義する．配置場所を制御しない場合は定義する必要はない．GNU環境の
場合は，次のように定義すればよい．

#define SEC_LOGTASK(type, variable) \
			type variable __attribute__((section("<セクション名>"),nocommon))

(8-1-8)  LOGTASK_PORTID_PRC1  プロセッサ1用のシステムログ用のシリアルポート番号 （ディフォルト値 1）
(8-1-9)  LOGTASK_PORTID_PRC2  プロセッサ2用のシステムログ用のシリアルポート番号 （ディフォルト値 2）
(8-1-10) LOGTASK_PORTID_PRC3  プロセッサ3用のシステムログ用のシリアルポート番号 （ディフォルト値 3）
(8-1-11) LOGTASK_PORTID_PRC4  プロセッサ4用のシステムログ用のシリアルポート番号 （ディフォルト値 4）

ログタスクがシステムログを出力するシリアルポート番号を定義する．定義し
ない場合は，ディフォルト値が使用される．

8.1.1 システムログ出力の共有

FMPカーネルでは，各プロセッサ毎にシリアルポートを持ち，あるプロセッサ
でシステムログ出力をした場合は，そのプロセッサの持つシリアルポートに出
力する構成を標準としている．しかしながら，ターゲットによってはシリアル
ポートの数がプロセッサより少ない場合がある．このような場合に，1つのシ
リアルポートを複数のプロセッサで共有することが可能である．

(8-1-1-1) G_SYSLOG

システムログを複数のプロセッサで共有するためのマクロ．ログタスクは1個
だけとなり，プロセッサ1でのみ動作する．定義は，ユーザープログラムの
Makefileにより行われる．

(8-1-1-2) LOGTASK_PORTID_G_SYSLOG  システムログ出力の共有時のシステムログ用の
                                   シリアルポート番号 （ディフォルト値 1）

システムログ出力の共有時にログタスクがシステムログを出力するシリアルポ
ート番号を定義する．定義しない場合は，ディフォルト値が使用される．

8.2 ログタスクのターゲット依存定義

(8-2-6)  SEC_LOGTASK        G_SYSLOG時のログタスク用変数の配置マクロ（オプション）
(8-2-7)  SEC_PRC1_LOGTASK   プロセッサ1用のログタスク用変数の配置マクロ（オプション）
(8-2-8)  SEC_PRC2_LOGTASK   プロセッサ2用のログタスク用変数の配置マクロ（オプション）
(8-2-9)  SEC_PRC3_LOGTASK   プロセッサ3用のログタスク用変数の配置マクロ（オプション）
(8-2-10) SEC_PRC4_LOGTASK   プロセッサ4用のログタスク用変数の配置マクロ（オプション）

ログタスクが使用する変数の配置場所指定（セクション指定）の指定方法を定
義する．配置場所を制御しない場合は定義する必要はない．

8.3 シリアルインタフェースドライバのターゲット依存部

ASPカーネルから変更なし．

8.3.1 変数，データ型，管理関数

(8-3-1-5) SEC_SERIAL1   プロセッサ1用シリアルドライバ用変数の配置マクロ（オプション）
(8-3-1-6) SEC_SERIAL2   プロセッサ2用シリアルドライバ用変数の配置マクロ（オプション）
(8-3-1-7) SEC_SERIAL3   プロセッサ3用シリアルドライバ用変数の配置マクロ（オプション）
(8-3-1-8) SEC_SERIAL4   プロセッサ4用シリアルドライバ用変数の配置マクロ（オプション）

シリアルインタフェースドライバが使用する変数の配置場所指定（セクション
指定）の指定方法を定義する．配置場所を制御しない場合は定義する必要はな
い．

8.3.2 デバイスサービスルーチン

ASPカーネルから変更なし．

8.3.3 コールバックルーチン

ASPカーネルから変更なし．

8.3.2 デバイスサービスルーチン

ASPカーネルから変更なし．

8.4 カーネル起動メッセージの出力のターゲット依存定義

ASPカーネルから変更なし．

8.5 サンプルプログラムとテストプログラムのターゲット依存定義

(8-5-2) CPUEXC1（オプション）

プロセッサ1用のCPU例外のCPU例外ハンドラ番号を定義するマクロ．このマク
ロを定義しない場合，CPU例外ハンドラを使う部分がサンプルプログラムから
除外される．CPU例外ハンドラのテストをするテストプログラムはコンパイル
できない．

(8-5-9) CPUEXC2-4（オプション）

プロセッサ2からプロセッサ4用のCPU例外ハンドラ番号を定義するマクロ．

8.5.1 実行時間分布集計モジュール用マクロ

実行時間分布集計モジュールは，初期状態では get_utm() を用いてμsec精度
の計測を行う．ローカルタイマ方式の場合は，get_utm()はプロセッサ毎に異
なるタイマを用いて時間計測を行う．そのため，プロセッサを跨ぐ時間を正し
く計測できない．プロセッサを跨ぐ処理の時間を計測したい場合は，プロセッ
サ間で共有可能なハードウエアタイマを用意して，以下のマクロを定義する．

(8-5-8) HISTTIM

実行時間分布集計モジュールで時間計測結果を格納する変数の型を指定する．

(8-5-9) HIST_GET_TIM   

時刻取得ルーチンを指定するマクロ．HIST_GET_TIM は，計測の開始と終了の
タイミングで呼び出され，HISTTIM 型の変数のポインタが引数として渡される．

(8-5-10) HIST_CONV_TIM  

時刻変換ルーチンを指定するマクロ．実行時間分布集計モジュールは，取得し
た値の差分を格納した HISTTIM 型の変数のポインタを引数に HIST_CONV_TIM 
を呼び出すため，HIST_GET_TIM で返す値に変換が必要な場合は，
HIST_CONV_TIM で行う．

(8-5-11) CPU<CPU ID>_PERF_PRE_HOOK

計測前のフックルーチン．対応するプロセッサで呼び出される．計測に悪影響
を与える割込みの禁止等の処理を呼び出すように設定する．

(8-5-12) CPU<CPU ID>_PERF_POST_HOOK

計測後のフックルーチン．対応するプロセッサで呼び出す必要がある．計測前
のフックルーチンで停止した割込みの許可等の処理を呼び出すように設定する．


９．その他

9.1 ドキュメント

(1) 対応しているターゲットシステムの種類・構成，バージョン番号
	・サポートしているプロセッサ数
   
(3-4) 性能評価用システム時刻の参照に関する規定
	・実行時間分布集計モジュール用のタイマに関する情報

(3-6) オーバランハンドラ機能拡張のサポートに関する規定

FMPカーネルでは，オーバランハンドラはサポートしない．

(3-8) タイマアーキテクチャ
  ・グローバルタイマ方式 と ローカルタイマ方式 のサポート有無や選択方
    法．

(3-9) OS内部のロックアーキテクチャ
  ・ジャイアントロック方式 と プロセッサロック方式 と 細粒度ロック方式 
    のサポート有無や選択方法．

(3-10) スピンロックアーキテクチャ
  ・ネイティブ方式 と エミュレーション方式 のサポート有無や選択方法．
    ネイティブ方式 の場合の最大数．

(3-11) メモリアーキテクチャ
  ・データの配置場所の制御方法．

9.2 パッケージ記述ファイル

ASPカーネルから変更なし．

１０．リファレンス

10.1 ターゲット依存部のファイル一覧

標準的なターゲット依存部のファイル構成は次の通りである．

target_ipi.cfg	プロセッサ間割込みハンドラドライバのシステムコンフィギ
				ュレーションファイル（6.19節）．
target_ipi.h	プロセッサ間割込みハンドラドライバのヘッダファイル（6.19節）．
				カーネルのみからインクルードされる．
target_ipi.c	プロセッサ間割込みハンドラドライバの実装ファイル
				（6.19節，オプション）．
target_pcb.h	依存部のプロセッサコントロールブロックのヘッダファイル
				（6.20節）．

以上
