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

		対応バージョン: Release 3.2.0
		対応ASP3カーネルバージョン : Release 3.5.0
		最終更新: 2021年01月07日

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

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



○目次

◎０．動作アーキテクチャ
１．共通事項
	1.1 ターゲット依存部の構成
		1.1.1 ターゲット略称とターゲット依存部ディレクトリ
		1.1.2 開発環境依存部ディレクトリ
		1.1.3 プロセッサコア依存部ディレクトリ
		1.1.4 チップ依存部ディレクトリ
	1.2 名前の衝突の防止
	1.3 ヘッダファイルの記述ルール
		1.3.1 ヘッダファイルの自己完結
		1.3.2 多重インクルードへの対応
		1.3.3 アセンブリ言語とのヘッダファイルの共用
	1.4 インクルード記述の方法
	1.5 クリティカルセクションの出入処理の実現に関する制約
２．システム構築環境のターゲット依存部
	2.1 システム略称・開発環境略称等の設定
	2.2 依存部ディレクトリの設定
	2.3 コマンド名の設定
	2.4 コンパイルオプションとオブジェクトファイルの設定
	2.5 オフセットファイルの生成方法
	2.6 リンク方法の設定
	2.7 依存関係の定義（オプション）
	2.8 その他の設定
３．TOPPERS共通定義のターゲット依存部
	3.1 ターゲット識別マクロ
	3.2 整数型の最大値・最小値・ビット数
	3.3 サイズの指定された整数型，その最大値・最小値，整数定数を作るマクロ
	3.4 サイズの指定された浮動小数点型，その最大値・最小値のマクロ
	3.5 コンパイラの拡張機能のためのマクロ定義
	3.6 標準的な定義の上書き
	3.7 アサーションのための定義
４．システムインタフェースレイヤ（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.2 トレースログ機能への対応
	6.3 システム状態の管理
		○6.3.1 全割込みロック状態の管理
		○6.3.2 コンテキストの管理
		6.3.3 CPUロック状態の管理
		◎6.3.4 チェック関数   
	6.4 割込みに関連するシステム状態の管理
		6.4.1 割込み優先度マスクの管理
		○6.4.2 割込み要求禁止フラグの管理
		○6.4.3 割込み要求のクリア
		○6.4.4 割込み要求のプローブ
	6.5 タスクディスパッチャ
		6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック
		○6.5.2 ディスパッチャ本体
		○6.5.3 自発的なディスパッチ
		○6.5.4 ディスパッチャの動作開始
		6.5.5 現在のコンテキストを捨ててディスパッチ
		6.5.6 タスクの起動準備
		◎6.5.7 ディスパッチの要求
	○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.13.4 タイムティックを用いたタイマドライバの実装
	○6.14 オーバランタイマドライバ（オプション）
		6.14.1 オーバランタイマドライバのファイル構成
		6.14.2 オーバランタイマの操作と割込み処理
	○6.15 動的メモリ管理（オプション）
		6.15.1 TLSFを用いたメモリプール管理機能の例
	○6.16 カーネル実装のコンフィギュレーションファイル
	◎6.17 プロセッサ識別
		◎6.17.1 プロセッサINDEX
		◎6.17.2 マスタプロセッサ
		◎6.17.3 タイムマスタプロセッサ
		◎6.17.4 タイムイベント処理プロセッサ
	◎6.18 ロック
		◎6.18.1 ロック変数の型定義
		◎6.18.2 ロック操作関数
	◎6.19 プロセッサ間割込みドライバ
		◎6.19.1 プロセッサ間割込みドライバのファイル構成
		◎6.19.2 プロセッサ間割込みの初期化・終了処理・割込み処理
		◎6.19.3 プロセッサ割込みハンドラの登録
	◎6.20 プロセッサコントロールブロック
	◎6.21 スピンロック
		◎6.21.1 スピンロック方式
		◎6.21.2 スピンロック方式の指定
		◎6.21.3 スピンロックの初期化・取得・解放機能
	◎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.3 パス3の生成スクリプトのターゲット依存部
		7.3.1 ターゲット非依存部をインクルードする前に定義すべき変数と関数
		7.3.2 ターゲット依存部で行うべきエラーチェック
	○7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル
◎８．システムサービス等のターゲット依存部
	◎8.1 システムログ機能のターゲット依存定義
	◎8.2 シリアルインタフェースドライバのターゲット依存部
		◎8.2.1 変数，データ型，管理関数
		◎8.2.2 デバイスサービスルーチン
		◎8.2.3 コールバックルーチン
	◎8.3 システムログタスクのターゲット依存定義
	◎8.4 低レベル出力
	◎8.5 テストプログラム用サービスのターゲット依存定義
	◎8.6 実行時間分布集計サービスのターゲット依存定義
	◎8.7 カーネル起動メッセージの出力のターゲット依存定義
９．その他
	○9.1 ドキュメント
	9.2 パッケージ記述ファイル
１０．リファレンス
	○10.1 ターゲット依存部のファイル一覧

○がついている項目はASP3カーネルから変更があった箇所を，◎はFMP3カーネ
ルで新規に追加された箇所を示す．本文で特に記載がない箇所はASP3カーネル
から変更がない箇所である．

０．動作アーキテクチャ

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

(0-1) アドレス

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

(0-2) 共有メモリ

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

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

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

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

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

(0-4) ロックの個数

プロセッサ間の排他制御機構を用いてロックを2個作成可能であること．

(0-5) プロセッサID

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

(0-6) 高分解能タイマのカウンタ

各プロセッサから読み込み可能な分解能が1マイクロ秒の32bitカウンタ（タイ
マ）を持つこと．

(0-7) 高分解能タイマの数と分解能

あるプロセッサから操作可能かつ，そのプロセッサに割込みを発生可能な分解
能が1マイクロ秒かつカウンタ値が32bitタイマを，タイムイベント処理プロセ
ッサとするプロッサと同じ数だけ持つこと．
   
１．共通事項

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

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

1.1.2 開発環境依存部ディレクトリ

1.1.3 プロセッサコア依存部ディレクトリ

1.1.4 チップ依存部ディレクトリ

1.2 名前の衝突の防止

1.3 ヘッダファイルの記述ルール

1.3.1 ヘッダファイルの自己完結

1.3.2 多重インクルードへの対応

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

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

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


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

2.1 システム略称・開発環境略称等の設定

2.2 依存部ディレクトリの設定

2.3 コマンド名の設定

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

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

2.6 リンク方法の設定

2.7 依存関係の定義（オプション）

2.8 その他の設定


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

3.1 ターゲット識別マクロ

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

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

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

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

3.6 標準的な定義の上書き

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


４．システムインタフェースレイヤ（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 微少時間待ち

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

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

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

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) CLS_ALL_PRC1

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

(5-9-2) CLS_ALL_PRC2

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

(5-9-3) CLS_ALL_PRC3

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

(5-9-4) CLS_ALL_PRC4

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

(5-9-5) CLS_PRC1

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

(5-9-6) CLS_PRC2

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

(5-9-7) CLS_PRC3

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

(5-9-8) CLS_PRC4

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


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

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

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

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

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

6.3 システム状態の管理

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

FMP3カーネルでは，全割込みロック状態はプロセッサ毎に管理する．

6.3.2 コンテキストの管理

(6-3-2-1) bool_t sense_context(PCB *p_my_pcb)

引数に自プロセッサのPCBを指定して呼び出される．

6.3.3 CPUロック状態の管理

(6-3-3-1) void lock_cpu(void)

(6-3-3-2) void lock_cpu_dsp(void)

(6-3-3-3) void unlock_cpu(void)

(6-3-3-4) void unlock_cpu_dsp(void)

(6-3-3-5) bool_t sense_lock(void)

(6-3-3-6) void delay_for_interrupt(void)

6.3.4 チェック関数

(6-3-4-1) OMIT_CHECK_TSKCTX（オプション）

標準のcheck_tskctx()を使用せず，ターゲット依存部で用意する場合には，こ
のシンボルをマクロ定義する．

(6-3-4-2) bool_t check_tskctx(void)（オプション）

OMIT_CHECK_TSKCTXをマクロ定義した場合は，この関数をターゲット依存部で
用意する．実行中の処理単位が，タスクコンテキストで実行されている場合に
はfalse，非タスクコンテキストで実行されている場合にはtrueを返す．本関
数実行中にマイグレーションが発生する可能性があるため，考慮して実装する
必要がある．

(6-3-4-3) OMIT_CHECK_UNL_MYSTATE（オプション）

標準のcheck_unl_mystate()を使用せず，ターゲット依存部で用意する場合に
は，このシンボルをマクロ定義する．

(6-3-4-4) bool_t check_unl_mystate(TCB **pp_selftsk, bool_t *p_context)（オプション）

OMIT_CHECK_UNL_MYSTATEをマクロ定義した場合は，この関数をターゲット依存
部で用意する．現在のシステム状態が，CPUロック状態の場合はtrue，CPUロッ
ク解除状態の場合にはfalseを返す関数．pp_selftskには実行状態のタスクの
TCPへのポインタを，p_contextは実行中の処理単位が，タスクコンテキストで
実行されている場合にはfalse，非タスクコンテキストで実行されている場合
にはtrueを返す．本関数実行中にマイグレーションが発生する可能性があるた
め，考慮して実装する必要がある．

(6-3-4-5) OMIT_CHECK_TSKCTX_UNL_MYSTATE（オプション）

標準のcheck_tskctl_unl_mystate()を使用せず，ターゲット依存部で用意する
場合には，このシンボルをマクロ定義する．

(6-3-4-6) bool_t check_tskctx_unl_mystate(TCB **pp_selftsk)（オプション）

OMIT_CHECK_TSKCTX_UNL_MYSTATEをマクロ定義した場合は，この関数をターゲ
ット依存部で用意する．実行中の処理単位が，タスクコンテキストで実行され，
かつ現在のシステム状態が，CPUロック解除状態の場合はfalse，それ以外の場
合はtrueを返す．pp_selftskには実行状態のタスクのTCPへのポインタを返す．
本関数実行中にマイグレーションが発生する可能性があるため，考慮して実装
する必要がある．

(6-3-4-7) OMIT_CHECK_TSKCTX_UNL（オプション）

標準のcheck_tskctx_unl()を使用せず，ターゲット依存部で用意する場合には，
このシンボルをマクロ定義する．

(6-3-4-8) bool_t check_tskctx_unl(void)（オプション）

OMIT_CHECK_TSKCTX_UNLをマクロ定義した場合は，この関数をターゲット依存
部で用意する．実行中の処理単位が，タスクコンテキストで実行され，かつ現
在のシステム状態が，CPUロック解除状態の場合はfalse，それ以外の場合は
trueを返す．本関数実行中にマイグレーションが発生する可能性があるため，
考慮して実装する必要がある．

(6-3-4-9) OMIT_CHECK_DISPATCH（オプション）

標準のcheck_dispatch()を使用せず，ターゲット依存部で用意する場合には，こ
のシンボルをマクロ定義する．

(6-3-4-10) bool_t check_dispatch(void)（オプション）

OMIT_CHECK_DISPATCHをマクロ定義した場合は，この関数をターゲット依存部
で用意する．実行中の処理単位が，タスクコンテキストで実行され，かつ現在
のシステム状態が，CPUロック解除状態，かつディスパッチ可能状態の場合は
false，それ以外の場合はtrueを返す．本関数実行中にマイグレーションが発
生する可能性があるため，考慮して実装する必要がある．

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

(6-4-0-1) bool_t VALID_INTNO(INTNO intno)

(6-4-0-2) bool_t VALID_INHNO(INHNO inhno)（オプション）

(6-4-0-3) bool_t check_intno_cfg(INTNO intno)

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

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

(6-4-1-2) void t_set_ipm(PRI intpri)

(6-4-1-3) PRI t_get_ipm(void)

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
を返すようにする．

このマクロを定義しない場合，VALID_INTNOが使われる．VALID_INTNOで有効と
判断される割込み番号が，dis_int／ena_intに対して有効な割込み番号と一致
している場合，このマクロを用意する必要はない．

(6-4-2-2) void disable_int(INTNO intno)

(6-4-2-3) void enable_int(INTNO intno)

6.4.3 割込み要求のクリア

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

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

このマクロを定義しない場合，VALID_INTNOが使われる．VALID_INTNOで有効と
判断される割込み番号が，clr_intに対して有効な割込み番号と一致している
場合，このマクロを用意する必要はない．

(6-4-3-2) bool_t check_intno_clear(INTNO intno)

(6-4-3-3) void clear_int(INTNO intno)

6.4.4 割込みの要求

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

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

このマクロを定義しない場合，VALID_INTNOが使われる．VALID_INTNOで有効と
判断される割込み番号が，ras_intに対して有効な割込み番号と一致している
場合，このマクロを用意する必要はない．

(6-4-4-2) bool_t check_intno_raise(INTNO intno)

(6-4-3-3) void raise_int(INTNO intno)

6.4.5 割込み要求のチェック

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

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

このマクロを定義しない場合，VALID_INTNOが使われる．VALID_INTNOで有効と
判断される割込み番号が，prb_intに対して有効な割込み番号と一致している
場合，このマクロを用意する必要はない．

(6-4-5-2) bool_t probe_int(INTNO intno)


6.5 タスクディスパッチャ

6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック

(6-5-1-1) TSKCTXB

(6-5-1-2) USE_TSKINICTXB（オプション）
(6-5-1-3) TSKINICTXB（オプション）

6.5.2 ディスパッチャ本体

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

----------------------------------------
void
dispatcher(void)
{
#ifdef LOG_DSP_ENTER
	log_dsp_enter(my_pcb.p_runtsk);
#endif /* LOG_DSP_ENTER */

  dispatcher_0:
	my_pcb.p_runtsk = my_pcb.p_schedtsk;
	if (my_pcb.p_runtsk != NULL) {
		自タスク（my_pcb.p_runtsk）のTCBからスタックポインタを復帰する
#ifdef LOG_DSP_LEAVE
		log_dsp_leave(my_pcb.p_runtsk);
#endif /* LOG_DSP_LEAVE */
		自タスクのTCBから実行再開番地を復帰し，そこへ分岐する … (*a)
	}

	/*
	 *  アイドル処理
	 */
	アイドル処理用のスタックに切り替える … (*c)
	割込みを許可したらCPUロック解除状態になるよう準備する
	割込みをすべて許可する
	while (true) {
		割込み発生を待つ … (*b)
	}
}
----------------------------------------

(*c)において，アイドル処理用のスタックを用意して切り替える．ASPカーネ
ルでは直前に実行していたタスクのスタックを使用するが，FMPカーネルはプ
ロセッサにタスクが1つも割り当てられない状況があるため，アイドル処理用
のスタックに切り替える．

6.5.3 自発的なディスパッチ

(6-5-3-1) void dispatch(void)

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

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

----------------------------------------
void
dispatch(void)
{
#ifdef TOPPERS_SUPPORT_OVRHDR
	ovrtimer_stop();					/* オーバランタイマの停止 */
#endif /* TOPPERS_SUPPORT_OVRHDR */
	スクラッチレジスタ(*)を除くすべてのレジスタをスタックに保存する
	スタックポインタを自タスク（my_pcb.p_runtsk）のTCBに保存する
	dispatch_rを，実行再開番地として自タスクのTCBに保存する … (*a)
	dispatcherに分岐する

  dispatch_r:
	スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
#ifdef TOPPERS_SUPPORT_OVRHDR
	ovrtimer_start();					/* オーバランタイマの動作開始 */
#endif /* TOPPERS_SUPPORT_OVRHDR */
}
----------------------------------------

(6-5-3-2) void request_dispatch(void)

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)

6.5.6 タスクの起動準備

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

6.5.7 ディスパッチの要求

(6-5-3-3) void request_dispatch_prc(uint_t prcid)

prcidで示すプロセッサに対してディスパッチを要求する．prcidで示すプロセ
ッサに対してプロセッサ間割込みを発生することを想定している．

プロセッサ間割込みを発生させる前には，メモリバリア命令等を発行して，
自プロセッサのAPI実行の結果を他のプロセッサが参照できるようにする．

割込みハンドラの出入口処理を，標準通りに実装する（dispatchを明示的に呼
び出す）場合には，プロセッサ間割込みにより呼び出されるハンドラでは何も
しなくてもよい．ターゲット依存部の最適化として，割込みハンドラを呼び出
さずに，ディスパッチ処理を呼び出してもよい．


6.6 割込みハンドラ

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

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

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

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

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

----------------------------------------
void
<割込みの出入口処理>(void)
{
	少なくともカーネル管理の割込みを禁止した状態にする … (*d)
	スクラッチレジスタをスタックに保存する … (*p)
	if (割込みがタスクコンテキストで発生) {
#ifdef TOPPERS_SUPPORT_OVRHDR
		ovrtimer_stop();				/* オーバランタイマの停止 */ … (*e)
#endif /* TOPPERS_SUPPORT_OVRHDR */
		スタックを非タスクコンテキスト用のスタックに切り換え，
								非タスクコンテキストに切り換える
	}
	割込み優先度マスクを，受け付けた割込みの割込み優先度に設定する
	割込みハンドラの入口で必要なIRCの操作を行う（割込み要求ラインがエッ
				ジトリガである場合のトリガされた割込み要求のクリアなど）
	CPUロック解除状態にする（受け付けた割込みよりも優先度の高い割込みを
												受け付けるようにする）

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

	少なくともカーネル管理の割込みを禁止した状態にする
	割込みハンドラの出口で必要なIRCの操作を行う（IRCに対する割込み処理
														の終了通知など）
	割込み優先度マスクを，割込みを受け付ける前の値に戻す … (*f)

	if (割込みがタスクコンテキストで発生) {
		スタックをタスク用のスタックに戻し，タスクコンテキストに切り換える
																… (*g)
		if (my_pcb.p_runtsk == NULL) {
			タスクのスタックに保存したスクラッチレジスタ等を捨てる … (*o)
			CPUロック状態にする … (*h)
			割込み優先度マスクは，全解除状態（TIPM_ENAALL）になって
												いなければならない … (*i)
			dispatcher_0に分岐する
		}

		if (my_pcb.p_runtsk != my_pcb.p_schedtsk) {
			CPUロック状態にする … (*h)
			割込み優先度マスクは，全解除状態（TIPM_ENAALL）になって
												いなければならない … (*i)
			スクラッチレジスタを除くすべてのレジスタをスタックに保存する
			スタックポインタを自タスク（my_pcb.p_runtsk）のTCBに保存する
			ret_int_rを，実行再開番地として自タスクのTCBに保存する … (*a)
			dispatcherに分岐する

		  ret_int_r:
			スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
		}
#ifdef TOPPERS_SUPPORT_OVRHDR
		ovrtimer_start();			/* オーバランタイマの動作開始 */
#endif /* TOPPERS_SUPPORT_OVRHDR */
	}
	割込み処理からのリターンにより，CPUロック解除状態に戻るように準備する
	スクラッチレジスタをスタックから復帰する … (*p)
	割込み処理からのリターン
}
----------------------------------------

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

6.6.3 割込みハンドラの設定

(6-6-3-1) void define_inh(INHNO inhno, FP int_entry, uint_t affinity)

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

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

(6-6-4-1) void config_int(INTNO intno, ATR intatr, PRI intpri, uint_t affinity)

affinity には，割付け可能なプロセッサをビットパターンで渡される．
複数のプロセッサで動的に割込みを受け付けるプロセッサを変更可能な場合は，
affinity で指定されたプロセッサのみで割込みを受け付けるようにする．

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

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

(6-6-6-1) void default_int_handler(void)（オプション）

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

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

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例外の出入口処理で扱うp_runtsk/p_schedtskは，自プロセッサのPCB（
my_pcb）が保持しているものとする．

----------------------------------------
void
<CPU例外の出入口処理>(void)
{
	スクラッチレジスタをスタックに保存する … (*p)
	CPU例外が発生した状況を判断するための追加情報をスタックに保存する … (*j)
	この時点でのスタックポインタ±nを，CPU例外の情報を記憶している領域の
										先頭番地とする（必要なら保存する）
	if (カーネル管理外のCPU例外) {
		if (CPU例外がタスクコンテキストで発生) {
			スタックを非タスクコンテキスト用のスタックに切り換え，
									非タスクコンテキストに切り換える … (*k)
		}
		システム状態（コンテキストは除く）を，CPU例外発生時の状態にする
		CPU例外ハンドラを，CPU例外の情報を記憶している領域の先頭番地を
									パラメータ（p_excinf）として呼び出す
		if (CPU例外がタスクコンテキストで発生) {
			スタックをタスク用のスタックに戻し，
									タスクコンテキストに切り換える … (*k)
		}
		CPU例外処理からのリターン後に，CPU例外発生時のシステム状態に
													戻るように準備する
	}
	else {
		if (CPU例外がタスクコンテキストで発生) {
			少なくともカーネル管理の割込みを禁止した状態にする
#ifdef TOPPERS_SUPPORT_OVRHDR
			ovrtimer_stop();			/* オーバランタイマの停止 */ … (*e)
#endif /* TOPPERS_SUPPORT_OVRHDR */
			スタックを非タスクコンテキスト用のスタックに切り換え，
									非タスクコンテキストに切り換える
		}
		割込み優先度マスクを，CPU例外発生時の値に設定する … (*l)
		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 */

		少なくともカーネル管理の割込みを禁止した状態にする … (*m)
		割込み優先度マスクを，CPU例外発生時の値に設定する … (*n)

		if (CPU例外がタスクコンテキストで発生) {
			スタックをタスク用のスタックに戻し，タスクコンテキストに切り換える
																	… (*g)
			if (my_pub.p_runtsk == NULL) {							… (*q)
				タスクのスタックに保存したスクラッチレジスタ，追加
													情報等を捨てる … (*o)
				CPUロック状態にする … (*h)
				割込み優先度マスクは，全解除状態（TIPM_ENAALL）になって
												いなければならない … (*i)
				dispatcher_0に分岐する
			}

			if (my_pcb.p_runtsk != my_pcb.p_schedtsk) {
				CPUロック状態にする … (*h)
				割込み優先度マスクは，全解除状態（TIPM_ENAALL）になって
												いなければならない … (*i)
				スクラッチレジスタを除くすべてのレジスタをスタックに保存する
				スタックポインタを自タスク（my_pcb.p_runtsk）のTCBに保存する
				ret_exc_rを，実行再開番地として自タスクのTCBに保存する … (*a)
				dispatcherに分岐する

			  ret_exc_r:
				スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
			}
#ifdef TOPPERS_SUPPORT_OVRHDR
			ovrtimer_start();		/* オーバランタイマの動作開始 */
#endif /* TOPPERS_SUPPORT_OVRHDR */
		}
		CPU例外処理からのリターン後に，CPUロック解除状態に戻るように準備する
	}
	CPU例外が発生した状況を判断するための追加情報をスタック上から捨てる
	スクラッチレジスタをスタックから復帰する … (*p)
	CPU例外処理からのリターン
}
----------------------------------------

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

(6-7-2-1) EXC_ENTRY(excno, exchdr)

(6-7-2-2) EXCHDR_ENTRY(excno, excno_num, exchdr)

6.7.3 CPU例外ハンドラの設定

(6-7-3-1) bool_t VALID_EXCNO(EXCNO excno)（オプション）

(6-7-3-2) void define_exc(EXCNO excno, FP exc_entry)

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

(6-7-4-1) OMIT_INITIALIZE_EXCEPTION（オプション）

(6-7-4-2) void initialize_exception(void)（オプション）

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

(6-7-5-1) void default_exc_handler(void *p_excinf)（オプション）

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

(6-7-6-1) bool_t exc_sense_intmask(void *p_excinf)

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)現在時刻の算出
(l)バリア同期5 ---------------------------------------------------------
                    (m)高分解能タイマ割込みの発生タイミングの設定
                    (n)カーネルの動作を開始


(a) プロセッサ状態の初期化

(b) hardware_init_hookを呼び出す

(c) bssセクションとdataセクションの初期化

マスタプロセッサのみ行うのが一般的である．プライベートメモリは，それぞ
れのプロセッサで初期化する．

ただし，カーネル本体は，kerflg_tableのすべての要素がfalse（＝0）に初期
化されること以外に，これらのセクションが初期化されることに依存していな
い．そのため，スタートアップモジュールをアプリケーションで用意する場合
で，システムサービスやアプリケーションがこれらのセクションが初期化され
ることに依存していない場合には，システムの起動時間を短縮するために，
kerflg_tableの各要素をfalseに初期化するだけで十分である．

(d) software_init_hookを呼び出す

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

(e)target_mprc_initialize()の呼び出し

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

(f)バリア同期1

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

(g) sta_kerへ分岐

(h)バリア同期2

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

(i)バリア同期3

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

(j)バリア同期4

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

(k)現在時刻の算出

タイムマスタプロセッサにおいて，高分解能タイマを設定して現在時刻を算出
する．

(l)バリア同期4

現在時刻の更新待ちの同期．

(m)高分解能タイマ割込みの発生タイミングの設定

タイムイベント処理プロセッサにおいて高分解能タイマ割込みの発生タイミン
グの設定を行う．
                       
(n)カーネルの動作を開始

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

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

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

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

(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) void request_ext_ker(ID prcid)

prcidで指定したプロセッサに対してカーネル終了処理要求を送る関数．プロ
セッサ間割込みハンドラとして，ext_ker_handler()を呼び出すことを想定し
ている．ext_ker_handler()は，カーネル終了処理関数（ext_ker()）で呼び出
す．

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

6.9.1 ビットマップサーチ

(6-9-1-1) OMIT_BITMAP_SEARCH（オプション）
(6-9-1-2) uint_t bitmap_search(uint16_t bitmap)（オプション）

(6-9-1-3) uint16_t PRIMAP_BIT(PRI pri)（オプション）

6.9.2 ビットフィールド

(6-9-2-1) BIT_FIELD_UINT（オプション）

(6-9-2-2) BIT_FIELD_BOOL（オプション）

(6-9-2-3) TBIT_TCB_PRIORITY（オプション）

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

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

(6-10-1-1) TARGET_TSKATR（オプション）	ターゲット定義のタスク属性
(6-10-1-2) TARGET_ISRATR（オプション）	ターゲット定義のISR属性
(6-10-1-3) TARGET_INHATR（オプション）	ターゲット定義の割込みハンドラ属性
(6-10-1-4) TARGET_INTATR（オプション）	ターゲット定義の割込み属性
(6-10-1-5) TARGET_EXCATR（オプション）	ターゲット定義のCPU例外ハンドラ属性

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

(6-10-2-1) TARGET_MIN_STKSZ（オプション）

(6-10-2-2) TARGET_MIN_ISTKSZ（オプション）

(6-10-2-3) CHECK_STKSZ_ALIGN（オプション）

(6-10-2-12) CHECK_MB_ALIGN（オプション）	管理領域のアライン単位

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-3-3) STK_T *TOPPERS_ISTKPT(STK_T *istk, size_t istksz)（オプション）

(6-10-3-4) DEFAULT_PRC<プロセッサID>_IDSTKSZ

アイドル処理時のスタック領域のサイズ．プロセッサ毎に定義する．

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

アイドル処理時のスタック領域の先頭番地．このマクロが定義されない場合に
は，サイズがDEFAULT_IDSTKSZのスタック領域が，配列により確保される．プ
ロセッサ毎に定義する．

6.10.4 空ラベルの定義

(6-10-4-1) TOPPERS_EMPTY_LABEL(type, symbol)（オプション）

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

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

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

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

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

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

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

6.13 高分解能タイマドライバ

6.13.1 高分解能タイマドライバのファイル構成

6.13.2 高分解能タイマの操作と割込み処理

(6-13-2-1) void target_hrt_initialize(intptr_t exinf)

(6-13-2-2) void target_hrt_terminate(intptr_t exinf)

(6-13-2-3) HRTCNT target_hrt_get_current(void)

すべてのプロセッサから実行できる必要がある．

(6-13-2-4) void target_hrt_set_event(ID prcid, HRTCNT hrtcnt)

prcidには，対象のタイマのタイマ処理プロセッサのIDを指定する．

(6-13-2-5) void target_hrt_raise_event(ID prcid)

prcidには，対象のタイマのタイマ処理プロセッサのIDを指定する．

(6-13-2-6) HRTCNT_BOUND

(6-13-2-7) void target_hrt_handler(void)
    または void target_hrt_isr(intptr_t exinf)

(6-13-2-8) TOPPERS_SUPPORT_CONTROL_OTHER_HRT

他のタイマ処理プロセッサのタイマを操作可能な場合に定義する．具体的には
，前述の target_hrt_set_event() や target_hrt_raise_event() が他のタイ
マ処理プロセッサのタイマに対して実行可能な場合に定義する．

(6-13-2-9) void request_set_hrt_event(ID prcid)

prcid のプロセッサに対して，高分解能タイマのイベントのセットを依頼する
．プロセッサ間割込みで実現することを想定している．要求されたプロセッサ
では，set_hrt_event_handler() を呼び出す．

6.13.3 高分解能タイマドライバの実装アプローチ

6.13.4 タイムティックを用いたタイマドライバの実装

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

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

6.14.1 オーバランタイマドライバのファイル構成

6.14.2 オーバランタイマの操作と割込み処理

(6-14-2-1) void target_ovrtimer_initialize(intptr_t exinf)

(6-14-2-2) void target_ovrtimer_terminate(intptr_t exinf)

(6-14-2-3) void target_ovrtimer_start(PRCTIM ovrtim)

(6-14-2-4) PRCTIM target_ovrtimer_stop(void)

(6-14-2-5) PRCTIM target_ovrtimer_get_current(void)

(6-14-2-6) void target_ovrtimer_handler(void)
    または void target_ovrtimer_isr(intptr_t exinf)

(6-14-2-7) OMIT_OVRTIMER_START（オプション）
(6-14-2-8) OMIT_OVRTIMER_STOP（オプション）

6.15 動的メモリ管理（オプション）

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

(6-15-1) OMIT_MEMPOOL_DEFAULT（オプション）

(6-15-2) bool_t initialize_mempool(MB_T *mempool, size_t size)（オプション）

(6-15-3) void *malloc_mempool(MB_T *mempool, size_t size)（オプション）

(6-15-4) void free_mempool(MB_T *mempool, void *ptr)（オプション）

6.15.1 TLSFを用いたメモリプール管理機能の例

6.16 カーネル実装のコンフィギュレーションファイル

カーネル実装に必要な静的APIを含むファイルとして，カーネル実装のコンフィ
ギュレーションファイル（target_kernel.cfg）を用意する．

標準的なターゲット依存部では，target_kernel.cfgには，高分解能タイマド
ライバを組み込むためのコンフィギュレーションファイル（target_timer.cfg）
とプロセッサ間割込みのドライバを組み込むためのコンフィギュレーションフ
ァイル（target_ipi.cfg）のインクルード記述のみが含まれる．

6.17 プロセッサ識別

6.17.1 プロセッサINDEX

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

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

(6-17-1-1) ID get_my_prcindex(void)

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

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

6.17.2 マスタプロセッサ

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

(6-17-2-1) TOPPERS_MASTER_PRCID

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

6.17.3 タイムマスタプロセッサ

システム中の特定の1個のプロセッサを示す．タイムマスタプロセッサは高分
解能タイマの現在時刻の更新を行う．

(6-17-3-1) TOPPERS_TMASTER_PRCID

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

(6-17-3-2) OMIT_IS_TMPRC

自時プロセッサがタイムマスタプロセッサであるか判定する関数 is_tmprc() 
を共通部のものは使用せず，ターゲット依存部で用意する場合に定義する．

6.17.4 タイムイベント処理プロセッサ

高分解能タイマを持ち，タイムイベント処理を行うことが可能なプロセッサを
タイムイベント処理プロセッサと呼ぶ．

(6-17-4-1) TOPPERS_TEPP_PRC

タイムイベント処理プロセッサを示すビットマスク．例えばプロセッサ1がタ
イムイベント処理プロセッサであれば，ビット0を'1'とする．


6.18 ロック

6.18.1 ロック変数の型定義

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

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

(6-18-1-1) LOCK 

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

ロック変数はグローバル変数として mp.c 内で宣言される．

6.18.2 ロック操作関数

ターゲット依存部では，ロックを操作する機能を提供する．

(6-18-2-1) void initialize_lock(LOCK *p_lock)

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

(6-18-2-2) void acquire_lock(LOCK *p_lock)

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

(6-18-2-3) void release_lock(LOCK *p_lock)

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

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 プロセッサ割込みハンドラの登録

共通部では，プロセッサ間割込みで呼び出される割込みハンドラがそれぞれの
機能で用意されている．

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

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

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

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

  ・前方参照用のPCBのtypedef宣言
    typedef struct processor_control_block PCB
  ・TPCBの定義
  ・prc_index() の定義
  ・ロック変数の型定義

(6-20-1) OMIT_TARGET_PCB

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

(6-20-2) OMIT_GET_P_MY_PCB

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

(6-20-3) OMIT_GET_P_MY_TPCB

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

6.21 スピンロック

6.21.1 スピンロック方式

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

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

(6-21-2-1) TMAX_NATIVE_SPN

ネイティブスピンロックの最大値．

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

ネイティブスピンロックでは，ターゲット依存部でスピンロックの，取得，解
放の機能を提供する必要がある．
     
(6-21-3-1) void initialize_native_spn(const SPNINIB *p_spninib)

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

(6-21-3-2) void lock_native_spn(const SPNINIB *p_spninib)

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

(6-21-3-3) bool_t try_native_spn(const SPNINIB *p_spninib)

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

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

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

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

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

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

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

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

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

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

----------------------------------------
void
exit_and_migrate(PCB *p_my_pcb, TCB *p_selftsk)
{
	スタックを非タスクコンテテキスト用のスタックに切り替える
	migrate_activate_self(p_my_pcb, p_selftsk)
}


７．コンフィギュレータ設定ファイルのターゲット依存部

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

7.2 パス2の生成スクリプトのターゲット依存部

この節では，パス2の生成スクリプトのターゲット依存部を記述する上で必要
な事項について説明する．

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

(7-2-1-1) $INTNO_VALID			有効な割込み番号のリスト
(7-2-1-2) $INHNO_VALID			有効な割込みハンドラ番号のリスト
(7-2-1-3) $EXCNO_VALID			有効なCPU例外ハンドラ番号のリスト
(7-2-1-4) $INTNO_CREISR_VALID（オプション）
(7-2-1-5) $INHNO_CREISR_VALID（オプション）
(7-2-1-6) $INTPRI_CFGINT_VALID（オプション）
(7-2-1-7) $INTNO_FIX_KERNEL（オプション）	カーネル管理に固定されている
											割込み番号のリスト
(7-2-1-8) $INHNO_FIX_KERNEL（オプション）	カーネル管理に固定されている
		 									割込みハンドラ番号のリスト
(7-2-1-9) $INHNO_FIX_NONKERNEL（オプション）カーネル管理外に固定されている
											割込み番号のリスト
(7-2-1-10) $INHNO_FIX_NONKERNEL（オプション）カーネル管理外に固定されてい
		 									る割込みハンドラ番号のリスト

(7-2-1-11) GenerateTskinictxb(key, params)（オプション）

(7-2-1-12) AllocStack(stack, size)（オプション）

(7-2-1-13) TargetCheckCreIsr(params)（オプション）

ターゲット依存でATT_ISRのチェックが必要な場合に定義する．


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

(7-2-2-1) $toIntnoVal[inhnoVal]		割込みハンドラ番号inhnoValを，対応す
									る割込み番号に変換するためのハッシュ
(7-2-2-2) $toInhnoVal[intnoVal]		割込み番号intnoValを，対応する割込み
									ハンドラ番号に変換するためのハッシュ

7.2.3 クラス内容の定義

ターゲット依存部では，taget_class.trbという名前のファイルを作成して，
以下のクラスの内容を定義する必要がある．

(7-2-3-1) clsData 

初期割り付けプロセッサのID(iprcid) と 割り付け可能プロセッサのビ
ットマスク(affinity)のハッシュを持つ配列．

7.2.4 カーネルオブジェクトのデータ構造の配置場所

以下に示すカーネルオブジェクトのコントロールブロック以外のメモリ領域の
配置を制御するため，ターゲット依存部のパス2の生成スクリプトにおいて，
以下の関数を用意する 

(7-2-4-1)  SecnameKernelData(cls)

カーネルオブジェクトデータのデータ構造を配置するセクションを返す．cls
には対象のカーネルオブジェクトデータの所属するクラスが渡される．

(7-2-4-2)  SecnameStack(cls)

タスクスタックの配置するセクションを返す．clsには対象のタスクの所属す
るクラスが渡される．

(7-2-4-3)  DefineVariableSection(genFile, defvar, secname) 

配置するセクションを指定した変数定義を生成する関数．配置するセクション
の指定がない場合はsecnameは空白で渡される．

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

カーネル内でプロセッサ毎に必要となる以下のデータ構造に対しては，初期割
り付けプロセッサが対象のプロセッサに一致する最初のクラスのセクションを
使用する．初期割付けプロセッサがprcidに一致するクラスがない時はセクシ
ョン指定を行わない．

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

7.3 パス3の生成スクリプトのターゲット依存部

この節では，パス3の生成スクリプトのターゲット依存部を記述する上で必要
な事項について説明する．

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

7.3.2 ターゲット依存部で行うべきエラーチェック

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

この定義を与えるために，cfg1_out.cから，ターゲット依存部の
target_cfg1_out.hをインクルードしている．target_cfg1_out.h（または，そ
こからインクルードされるファイル）には，スタートアップモジュールから参
照されるシンボルのスタブの定義を含める．典型的には，以下のような定義を
含める必要がある．

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

void hardware_init_hook(void)
{
}

void software_init_hook(void)
{
}

void _kernel_target_mprc_initialize(void)
{
}

uint_t _kernel_start_sync;

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

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

シリアルインタフェースドライバのターゲット依存部と低レベル出力は，ター
ゲット依存部で用意する必要がある．

その他のシステムサービスは，ターゲット非依存部で用意されているが，ター
ゲット依存に設定を変更することができる．具体的には，システムサービスの
設定を変更するための定義を，target_syssvc.h，target_stddef.h，またはそ
こからインクルードされるファイル（開発環境依存部／プロセッサコア依存部／
チップ依存部で用意されるヘッダファイルなど）に記述する．

8.1 システムログ機能のターゲット依存定義

システムログ機能を使用する場合で，スタートアップモジュールでbssセクショ
ンのクリアを省略している場合には，syslog_logmaskとsyslog_lowmask_notを
0に初期化するコードを追加する．これは，システムログ機能が初期化される前
に出力されたログ情報を，低レベル出力機能を用いて出力するためである．

ターゲット依存部で提供すべきシステムログ機能のための定義は次の通りであ
る．

(8-1-1) TCNT_SYSLOG_BUFFER（オプション）

システムログ機能のログバッファのサイズを定義するマクロ．定義しない場合
のデフォルト値は32．

(8-1-2) LOGTIM，SYSLOG_GET_LOGTIM（オプション）

システムログ機能において記録する時刻（ログ時刻）のデータ型をLOGTIMに，
時刻を取得するための処理をSYSLOG_GET_LOGTIMにマクロ定義する．これらを定
義しない場合，高分解能タイマのカウント値をログ時刻に用いる．

なお，LOGTIMの定義は，target_stddef.hまたはそこからインクルードされるファ
イルに含めなければならない．

(8-1-3) LOGPAR，ULOGPAR（オプション）

システムログ機能において記録するログパラメータのデータ型をLOGPARにマク
ロ定義する．LOGPARに定義したデータ型は，符号付きの整数型でなければなら
ない．また，LOGPARと同じサイズの符号無しの整数型を，ULOGPARにマクロ定
義する．これらを定義しない場合，ログパラメータのデータ型はintptr_tとす
る．

なお，LOGPARおよびULOGPARの定義は，target_stddef.hまたはそこからインク
ルードされるファイルに含めなければならない．

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

ターゲット依存部で提供すべきシリアルインタフェースドライバのための定義
は次の通りである．これらの定義は，別に指定がない限り，target_serial.hま
たはそこからインクルードされるファイルに含め，必要なコンフィギュレーショ
ン情報をtarget_serial.cfgに記述する．関数の実体が必要な場合には，
target_serial.c等のファイルを用意する．

シリアルインタフェースドライバのターゲット依存部の中で，ターゲットのシ
リアルI/Oデバイス（SIO）のみに依存する部分を，SIOドライバと呼ぶ．SIOド
ライバは，おおよそ，ITRONデバイスドライバ設計ガイドラインのPDICに相当
する．

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

(8-2-1-1) TNUM_PORT

シリアルインタフェースドライバがサポートするシリアルポート数を定義する
マクロ．このマクロの定義は，target_syssvc.hまたはそこからインクルード
されるファイルに含める．

(8-2-1-2) void sio_initialize(intptr_t exinf)（オプション）

SIOドライバの初期化処理．target_serial.cfgに，この関数を初期化ルーチン
として登録する静的APIを含める．ただし，低レベル出力をSIOポート経由で行
う場合には，SIOドライバの初期化を初期化ルーチンの実行前に行いたいため，
target_initializeから呼び出す必要がある．

(8-2-1-3) void sio_terminate(intptr_t exinf)（オプション）

SIOドライバの終了処理．target_serial.cfgに，この関数を終了処理ルーチン
として登録する静的APIを含める．

(8-2-1-4) void sio_isr(intptr_t exinf)

SIOの割込みサービスルーチン．target_serial.cfgに，この関数を割込みサー
ビスルーチンとして登録する静的APIを含める．また，その静的APIに必要な
SIOの割込み番号などは，target_serial.hでマクロ定義する．割込みサービス
ルーチンではなく，割込みハンドラとすることもできる．

(8-2-1-5) SIOPCB

SIOポート管理ブロックのデータ型（target_serial.hには，データ型の宣言だ
け含まれていればよい）．

(8-2-1-6) SIO_RDY_SND，SIO_RDY_RCV

送信可能コールバックの識別番号をSIO_RDY_SNDに，受信通知コールバックの識
別番号をSIO_RDY_RCVにマクロ定義する．コールバックの禁止／許可を行なうサー
ビスコール（sio_ena_cbrとsio_dis_cbr）で用いる．

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

以下のデバイスサービルルーチンは，（少なくとも）SIOポートからの割込み
がマスクされた状態で呼び出される．また，タスクコンテキスト，非タスクコ
ンテキストのいずれで呼び出される場合もある（いずれで呼び出されても動作
するようにしなければならない）．

(8-2-2-1) SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)

siopidで指定されるSIOポートをオープンする関数．exinfはSIOポートに対す
る拡張情報で，コールバックを呼ぶ時にSIOポートを区別するために渡す．

(8-2-2-2) void sio_cls_por(SIOPCB *siopcb)

siopcbで指定されるSIOポートをクローズする関数．

(8-2-2-3) bool_t sio_snd_chr(SIOPCB *siopcb, char c)

siopcbで指定されるSIOポートに，cで示される文字を送信する関数．文字を送
信レジスタに入れた場合にはtrueを，前に送信した文字の送信が終わっていな
いために，文字を送信レジスタに入れられなかった場合にはfalseを返す．

(8-2-2-4) int_t sio_rcv_chr(SIOPCB *siopcb)

siopcbで指定されるSIOポートから文字を読む関数．文字を受信していた場合，
読んだ文字のコードは正の値として返し，文字を受信していない場合には-1を
返す．

(8-2-2-5) void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)

siopcbで指定されるSIOポートからの，cbrtnで指定されるコールバックを許可
する．cbrtnには，SIO_RDY_SNDかSIO_RDY_RCVを指定できる．

(8-2-2-6) void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)

siopcbで指定されるSIOポートからの，cbrtnで指定されるコールバックを禁止
する．cbrtnには，SIO_RDY_SNDかSIO_RDY_RCVを指定できる．

8.2.3 コールバックルーチン

ターゲット依存部は，必要なタイミングで，シリアルインタフェースドライバ
のターゲット非依存部に含まれる以下のコールバックルーチンを呼び出びださ
なければならない．ただし，それぞれのコールバックが禁止されている時は，
コールバックルーチンを呼び出してはならない．

コールバックルーチンは，（少なくとも）SIOポートからの割込みが禁止され
た状態で，非タスクコンテキストで呼び出す．exinfには，SIOポートのオープ
ン時に指定された拡張情報を渡す．

(8-2-3-1) void sio_irdy_snd(intptr_t exinf)

送信可能コールバックルーチン．SIOポートに対して文字が送信できる状態に
なった場合に呼び出す．シリアルインタフェースドライバは，このコールバッ
クルーチンの中で，sio_snd_chrを呼び出して次の文字を送信するか，送信す
べき文字がない場合には送信可能コールバックを禁止する．

(8-2-3-2) void sio_irdy_rcv(intptr_t exinf)

受信通知コールバックルーチン．SIOポートから文字を受信した場合に呼び出
す．シリアルインタフェースドライバは，このコールバックルーチンの中で，
必ずsio_rcv_chrを呼び出して受信した文字を取り出す．

8.3 システムログタスクのターゲット依存定義

ターゲット依存部で提供すべきシステムログタスクのための定義は次の通りで
ある．これらの定義は，target_syssvc.hまたはそこからインクルードされるファ
イルに含める．

(8-3-1) LOGTASK_PRIORITY（オプション）

システムログタスクの優先度を定義するマクロ．定義しない場合のデフォルト
値は3．

(8-3-2) LOGTASK_STACK_SIZE（オプション）

システムログタスクのスタックサイズを定義するマクロ．定義しない場合のデ
フォルト値は1024．

(8-3-3-1) LOGTASK_PORTID_PRC1（オプション）

プロセッサ1用のシステムログタスクの出力先のシリアルポート番号．定義し
ない場合のデフォルト値は1．

(8-3-3-2) LOGTASK_PORTID_PRC2（オプション）

プロセッサ2用のシステムログタスクの出力先のシリアルポート番号．定義し
ない場合のデフォルト値は2．

(8-3-3-3) LOGTASK_PORTID_PRC3（オプション）

プロセッサ3用のシステムログタスクの出力先のシリアルポート番号．定義し
ない場合のデフォルト値は3．

(8-3-3-4) LOGTASK_PORTID_PRC4（オプション）

プロセッサ4用のシステムログタスクの出力先のシリアルポート番号．定義し
ない場合のデフォルト値は4．

(8-3-4) LOGTASK_INTERVAL（オプション）

システムログタスクの動作間隔（単位はマイクロ秒）．定義しない場合のデフォ
ルト値は10000．

(8-3-5) LOGTASK_FLUSH_WAIT（オプション）

ログ出力を待ち合わせる処理において，タスクを待たせる単位となる時間（単
位はマイクロ秒）．定義しない場合のデフォルト値は1000．


8.4 低レベル出力

ターゲット依存部で提供すべき低レベル出力のための関数は次の通りである．
この関数宣言は，target_syssvc.hまたはそこからインクルードされるファイ
ルに含める．また，関数の本体は，それ用のファイルを用意しても良いし，
（例外的に）target_serial.cまたはそこからインクルードされるファイルに
含めても良いこととする．

(8-4-1) void target_fput_log(char c)

低レベル出力のための文字出力関数．ターゲット依存の方法で，文字cを表示/
出力/保存する．

この関数は，リエントラントに実装しなければならない．この関数内で排他制
御が必要な場合には，SILを用いて全割込みロック状態にすること．また，全割
込みロック状態で呼ばれる場合があるため，全割込みロック状態から呼び出す
ことができない関数を呼ばないように実装しなければならない．

低レベル出力をシリアルポート経由で行う場合で，シリアルインタフェースド
ライバとポートを共用しないことが望ましいが，ポート数が足りないためにや
むをえず共用する場合には，両者が競合しないように注意が必要である．具体
的には，両者が同じ設定でSIOを使うようにし，シリアルインタフェースドラ
イバの動作中に低レベル出力が行われても差し支えないように設計する．また，
低レベル出力が動作開始後にシリアルインタフェースドライバがSIOを初期化
すると，文字化けが起こる可能性がある．これを避けるためには，共用するポー
トは低レベル出力側で初期化し，シリアルインタフェースドライバでは初期化
しないようにするとよい．

8.5 テストプログラム用サービスのターゲット依存定義

ターゲット依存部で提供すべきテストプログラム用サービスのための定義はな
い．

8.6 実行時間分布集計サービスのターゲット依存定義

実行時間分布集計サービスの設定をターゲット依存部で変更する場合に，ター
ゲット依存部で提供すべき実行時間分布集計サービスのための定義は次の通り
である．これらの定義は，target_syssvc.hまたはそこからインクルードされ
るファイルに含める．

(8-6-1) HISTTIM，HISTTIM_CYCLE（オプション）

実行時間計測用の時刻のデータ型をHISTTIMに，実行時間計測用の時刻の周期
をHISTTIM_CYCLEにマクロ定義する．HISTTIMを定義しない場合，HISTTIMと
HISTTIM_CYCLEのデフォルト値は，それぞれ，HRTCNTとTCYC_HRTCNTである．

(8-6-2) void HIST_GET_TIM(HISTTIM *p_time)（オプション）

実行時間計測用の現在時刻を*p_timeに取得する処理に定義するマクロ．定義し
ない場合のデフォルトは，fch_hrtの返値を*p_timeに取得する処理になる．

(8-6-3) uint_t HIST_CONV_TIM(HISTTIM time)（オプション）

実行時間計測用の時刻の差（時間）を，実行時間分布集計用の値に変換する処
理に定義するマクロ．時刻が過去に戻ったかオーバフローしたかの区別がつか
ない場合には，最上位ビットが1の値（INT_MAXよりも大きい値）を返す．定義
しない場合のデフォルトは，timeをuint_tにキャストする処理になる．

(8-6-4) void HIST_BM_HOOK(void)（オプション）

実行時間計測直前に行うべき処理に定義するマクロ．キャッシュのパージやフィ
ル，メモリバリア処理等を行いたい場合には，このマクロに定義する．定義し
ない場合のデフォルトは，空の処理になる．

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

ターゲット依存部で提供すべきカーネル起動メッセージの出力のための定義は
次の通りである．これらの定義は，target_syssvc.hまたはそこからインクルー
ドされるファイルに含める．

(8-7-1) TARGET_NAME

ターゲットの名称に定義する．

(8-7-2) TARGET_COPYRIGHT（オプション）

カーネル起動メッセージに，ターゲット依存部の著作権表示を追加するための
マクロ．デフォルトでは，ターゲット依存部の著作権表示を追加しない．


９．その他

9.1 ドキュメント

(1) 対応しているターゲットシステムの種類・構成，バージョン番号
	・サポートしているプロセッサ数

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

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


１０．リファレンス

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

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

以上
