
		TOPPERS/FMP3カーネル
		コンフィギュレータ仕様

		対応バージョン: Release 3.0.0
		最終更新: 2019年3月19日

このドキュメントは，TOPPERS/FMP3カーネルのコンフィギュレータが標準的に
生成すべきファイルの内容について解説したものである．ターゲット依存に生
成する内容については，このドキュメントの範囲外である．

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

 Copyright (C) 2005-2019 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: configurator.txt 149 2019-03-29 17:39:56Z ertl-honda $
----------------------------------------------------------------------

○目次

ASP3カーネルのからの変更点には◎を付けている．

１．生成するファイルの種類
２．静的API一覧◎
３．カーネル構成・初期化ヘッダファイル（kernel_cfg.h）
	3.1 固定生成部分
	3.2 オブジェクト数の定義◎
	3.3 オブジェクトのID番号の定義
４．カーネル構成・初期化ファイル（kernel_cfg.c）
	4.1 固定生成部分
	4.2 カーネルの種類のチェック◎
	4.3 インクルードディレクティブ（#include）の処理
	4.4 オブジェクトのID番号を保持する変数の定義
	4.5 各カーネルオブジェクトに関する定義
		4.5.1 カーネルオブジェクトに関する定義の標準構成◎
		4.5.2 タスクに関する定義◎
		4.5.3 セマフォに関する定義◎
		4.5.4 イベントフラグに関する定義◎
		4.5.5 データキューに関する定義◎
		4.5.6 優先度データキューに関する定義◎
		4.5.7 ミューテックスに関する定義◎
		4.5.8 固定長メモリプールに関する定義◎
		4.5.9 周期通知に関する定義◎
		4.5.10 アラーム通知に関する定義◎
		4.5.11 スピンロックに関する定義◎
	4.6 通知ハンドラの生成
		4.6.1 変数の設定によるイベント通知
		4.6.2 変数のインクリメントによるイベントの通知
		4.6.3 タスクの起動によるイベント通知
		4.6.4 タスクの起床によるイベント通知
		4.6.5 セマフォの返却によるイベント通知
		4.6.6 イベントフラグのセットによるイベント通知
		4.6.7 データキューへの送信によるイベント通知
		4.6.8 変数の設定によるエラー通知
		4.6.9 変数のインクリメントによるエラー通知
		4.6.10 タスクの起動によるエラー通知
		4.6.11 タスクの起床によるエラー通知
		4.6.12 セマフォの返却によるエラー通知
		4.6.13 イベントフラグのセットによるエラー通知
		4.6.14 データキューへの送信によるエラー通知
		4.6.15 エラー条件
	4.7 割込みに関する定義
		4.7.1 割込みサービスルーチンに関する定義◎
		4.7.2 割込みハンドラに関する定義
		4.7.3 割込み要求ラインに関する定義◎
	4.8 CPU例外に関する定義◎
	4.9 非タスクコンテキスト用のスタック領域に関する定義
	4.10 タイムイベント管理に関する定義◎
	4.11 各モジュールの初期化関数の定義
	4.12 初期化ルーチンの実行関数の定義◎
	4.13 終了処理ルーチンの実行関数の定義◎
	4.14 プロセッサに関する定義◎
	4.15 アイドル時のスタックに関する定義◎
	4.16 サブ優先度機能に関する定義◎ 


１．生成するファイルの種類

FMP3カーネルのコンフィギュレータは，システムコンフィギュレーションファ
イルを処理して，カーネル構成・初期化ファイル（kernel_cfg.c）と構成・初
期化ヘッダファイル（kernel_cfg.h）を生成する．コンフィギュレータの処理
の途中に，この他にいくつかの中間ファイルを生成する．


２．静的API一覧◎

FMP3カーネルのコンフィギュレータが処理する静的APIは次の通り．

(1) タスク管理機能
	CRE_TSK(ID tskid, { ATR tskatr, intptr_t exinf, TASK task,
								PRI itskpri, size_t stksz, STK_T *stk })

(2) 同期・通信機能◎
	CRE_SEM(ID semid, { ATR sematr, uint_t isemcnt, uint_t maxsem })
	CRE_FLG(ID flgid, { ATR flgatr, FLGPTN iflgptn })
	CRE_DTQ(ID dtqid, { ATR dtqatr, uint_t dtqcnt, void *dtqmb })
	CRE_PDQ(ID pdqid, { ATR pdqatr, uint_t pdqcnt, PRI maxdpri, void *pdqmb })
	CRE_MTX(ID mtxid, { ATR mtxatr, PRI ceilpri })
	CRE_SPN(ID spnid, { ATR spnatr })

※ dtqmb，pdqmbがNULLでない場合はサポートしない．

(3) メモリプール管理機能
	CRE_MPF(ID mpfid, { ATR mpfatr, uint_t blkcnt, uint_t blksz,
										MPF_T *mpf, void *mpfmb })

※ mpfmbがNULLでない場合はサポートしない．

(4) 時間管理機能
	CRE_CYC(ID cycid, { ATR cycatr, ＜通知方法の指定＞,
										RELTIM cyctim, RELTIM cycphs })
	CRE_ALM(ID almid, { ATR almatr, ＜通知方法の指定＞ })

(5) 割込み管理機能
	CFG_INT(INTNO intno, { ATR intatr, PRI intpri })
	CRE_ISR(ID isrid, { ATR isratr, intptr_t exinf,
								INTNO intno, ISR isr, PRI isrpri })
	DEF_INH(INHNO inhno, { ATR inhatr, INTHDR inthdr })

(6) CPU例外管理機能
	DEF_EXC(EXCNO excno, { ATR excatr, EXCHDR exchdr })

(7) システム構成管理機能
	DEF_ICS({ size_t istksz, STK_T *istk })
	ATT_INI({ ATR iniatr, intptr_t exinf, INIRTN inirtn })
	ATT_TER({ ATR teratr, intptr_t exinf, TERRTN terrtn })

(9) システム状態管理機能◎
	ENA_SPR(PRI tskpri)

FMP3カーネルでは，カーネルオブジェクトはいずれか1つのクラスに所属する
ことから，オブジェクトの登録を行う静的APIは，次のようにクラスの囲みの
中に記述する．

CLASS(<clsid>) {
	そのクラスに属するオブジェクトの登録など
}

clsidは，整数定数式パラメータとする．

３．カーネル構成・初期化ヘッダファイル（kernel_cfg.h）

この章では，カーネル構成・初期化ヘッダファイル（kernel_cfg.h）に生成す
べき定義について説明する．なお，生成位置が明示されているものを除いては，
定義の生成順序は以下の順でなくてもよい．

3.1 固定生成部分

kernel_cfg.hが複数回インクルードされるのを防ぐための記述を生成する．具
体的には，ファイルの先頭に次の行を生成する．

#ifndef	TOPPERS_KERNEL_CFG_H
#define	TOPPERS_KERNEL_CFG_H

また，ファイルの末尾に次の行を生成する．

#endif	/* TOPPERS_KERNEL_CFG_H */

3.2 オブジェクト数の定義◎

カーネルがサポートするオブジェクトの数をマクロ定義するプリプロセッサディ
レクティブ（#define）を生成する．具体的には，次のような記述を生成する．

#define TNUM_TSKID	<タスクの数>
#define TNUM_SEMID	<セマフォの数>
#define TNUM_FLGID	<イベントフラグの数>
#define TNUM_DTQID	<データキューの数>
#define TNUM_PDQID	<優先度データキューの数>
#define TNUM_MTXID	<ミューテックスの数>
#define TNUM_MPFID	<固定長メモリプールの数>
#define TNUM_SPNID	<スピンロックの数>
#define TNUM_CYCID	<周期ハンドラの数>
#define TNUM_ALMID	<アラームハンドラの数>
#define TNUM_ISRID	<割込みサービスルーチンの数>

3.3 オブジェクトのID番号の定義

コンフィギュレータがID番号を割り付けたオブジェクトの名前を，割り付けた
ID番号にマクロ定義するプリプロセッサディレクティブ（#define）を生成する．
例えば，次のような記述を生成する．

#define TASK1	1
#define TASK2	2
#define SEM1	1


４．カーネル構成・初期化ファイル（kernel_cfg.c）

この章では，カーネル構成・初期化ファイル（kernel_cfg.c）に生成すべき定
義について説明する．なお，生成位置が明示されているものを除いては，定義
の生成順序は以下の順でなくてもよい．

4.1 固定生成部分

kernel_cfg.c用のヘッダファイルと，カーネル構成・初期化ヘッダファイルを
インクルードするプリプロセッサディレクティブ（#include）を生成する．具
体的には，次の行を生成する．

#include "kernel/kernel_int.h"
#include "kernel_cfg.h"

4.2 カーネルの種類のチェック◎

kernel_cfg.cとカーネルの種類が一致しているかをチェックするために，次の
行を生成する．

#if !(TKERNEL_PRID == 0x0008U && (TKERNEL_PRVER & 0xf000U) == 0x3000U)
#error The kernel does not match this configuration file.
#endif

4.3 インクルードディレクティブ（#include）の処理

システムコンフィギュレーションファイルに含まれるC言語プリプロセッサのイ
ンクルードディレクティブ（#include）と同一のディレクティブ（#include）
を生成する．例えば，

#include "sample1.h"

というインクルードディレクティブに対して，

#include "sample1.h"

というディレクティブを生成する．生成するディレクティブの順序は，システ
ムコンフィギュレーションファイル中でのインクルードディレクティブの記述
順序に一致させる．

4.4 オブジェクトのID番号を保持する変数の定義

USE_EXTERNAL_IDが定義されている場合（cfg1_out.cをコンパイルする際のコン
パイルオプションにより定義することを想定）には，コンフィギュレータがID
番号を割り付けたオブジェクトの名前の末尾に"_id"を付加した名前の変数を生
成する．変数は，const属性を付加したID型の変数とし，割り付けたID番号を値
とする．例えば，次のような記述を生成する．

const ID TASK1_id = 1;
const ID TASK2_id = 2;
const ID SEM1_id = 1;

4.5 各カーネルオブジェクトに関する定義

4.5.1 カーネルオブジェクトに関する定義の標準構成

システムコンフィギュレーションファイル中に，オブジェクトを生成する静的
API「CRE_XXX」が含まれる各カーネルオブジェクトに関して，オブジェクト生
成のための定義を生成する．

コンフィギュレータは，同じ種類のオブジェクトを生成する静的APIを集め，各
オブジェクトにID番号を割り付ける．ID番号は，他のオブジェクトのID番号と
重複がなく，ID番号が1から連続するように割り付ける．

コンフィギュレータに対するオプション指定（--id-input-file）により，コン
フィギュレータがオブジェクトに割り付けるID番号を指定することができる．
同じ種類の異なるオブジェクトに対して同じID番号を指定したり，コンフィギュ
レータがID番号をできる限り連続するように割り付けたとしてもID番号が連続
しない場合には（FMP3カーネルは，オブジェクトのID番号が連続していること
を仮定して実装してある），コンフィギュレータはエラーを報告する．

また，コンフィギュレータに対するオプション指定（--id-output-file）によ
り，コンフィギュレータがID番号を割り付けたオブジェクトの名前と割り付け
たID番号の組を，オプションで指定したファイルに出力する．

各カーネルオブジェクトに関する定義の標準的な構成は，次の通りである．オ
ブジェクトによって例外がある場合には，オブジェクト毎の項で説明する．

(a) オブジェクトIDの最大値の変数の定義

オブジェクトIDの最大値を保持する変数の定義を生成する．具体的には，オブ
ジェクトの省略記号を「XXX／xxx」とすると，次のような行を生成する．

const ID _kernel_tmax_xxxid = (TMIN_XXXID + TNUM_XXXID - 1);

(b) オブジェクトに必要なメモリ領域の定義

オブジェクトによっては，オブジェクトに必要なメモリ領域の定義を生成する．
具体的には，オブジェクト毎の項で説明する．

(c) オブジェクトの初期化ブロックの定義

オブジェクトの初期化ブロックの定義を生成する．具体的には，オブジェクト
の省略記号を「XXX／xxx」とすると，次のような行を生成する．

const XXXINIB _kernel_xxxinib_table[TNUM_XXXID] = {
	<オブジェクトIDが1のオブジェクトの初期化情報>,
	<オブジェクトIDが2のオブジェクトの初期化情報>,
				……
	<オブジェクトIDがTNUM_XXXIDのオブジェクトの初期化情報>
};

オブジェクトの初期化情報の形式は，オブジェクト毎に異なる．具体的には，
オブジェクト毎の項で説明する．

オブジェクトが1つも生成されなかった場合には，次のような行を生成する．

	TOPPERS_EMPTY_LABEL(const XXXINIB, _kernel_xxxinib_table);

(d) オブジェクトのコントロールブロックの定義◎

オブジェクトのコントロールブロックの定義を生成する．具体的には，具体的
には，オブジェクトの省略記号を「XXX／xxx」とし，オブジェクトの名前を
「yyy」とすると，オブジェクト毎に次のような行を生成する．

XXXCB _kernel_xxxcb_<オブジェクト名1>;

オブジェクトが1つも生成されなかった場合には，次のような行を生成する．

	TOPPERS_EMPTY_LABEL(XXXCB, _kernel_xxxcb_table);$NL$

(e) オブジェクトのコントロールブロックへのアクセステーブル◎

各オブジェクトのオブジェクトIDを用いてそのオブジェクトのコントロールブ
ロックへアクセスするためのテーブルの定義を生成する．具体的にはオブジェ
クトの省略記号を「XXX／xxx」とすると，次のような行を生成する．

XXXCB* const _kernel_p_xxx_table[TNUM_XXX] = {
	&_kernel_xxxcb_<オブジェクト名1>,
	&_kernel_xxxcb_<オブジェクト名2>,
	...
};

4.5.2 タスクに関する定義

FMP3カーネルは，タスクが1つもないケースに対応していない．タスクを生成す
る静的APIが1つもなかった場合，コンフィギュレータはエラーを報告する．

タスクの省略記号は「TSK／tsk」である．ただし，タスク初期化ブロックのデー
タ型はTINIB，その変数名は_kernel_tinib_table，タスクコントロールブロッ
クのデータ型はTCB，その変数名は_kernel_tcb_table である（いずれも「TSK／
tsk」に代えて「T／t」を用いている）．

以下では，システムコンフィギュレーションファイルに次の静的APIが含まれ
ている時に生成すべき情報について述べる．

	CRE_TSK(tskid, { tskatr, exinf, task, itskpri, stksz, stk });

4.5.2.1 タスクに必要なメモリ領域の定義◎

タスクに必要なメモリ領域として，タスクのスタック領域がある．stkがNULLの
場合には，生成するタスク毎に，指定されたサイズのスタック領域を確保する．
具体的には，上記の静的APIに対して，次の定義を生成する．

＊stkがNULLの場合のみ生成
static STK_T _kernel_stack_<タスク名>[COUNT_STK_T(stksz)];

ただし，この方法でスタック領域が確保できないターゲットにおいては，ター
ゲット依存の方法でスタック領域を確保する．

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenTSKSTKを定義することにより，任意のフォーマットを変更できるた
め，セクション指定等が可能である．

4.5.2.2 タスクの初期化情報◎

タスク初期化ブロック中に生成するタスクの初期化情報は，次の形式とする．

＊stkがNULLでない場合
	{ (tskatr), (intptr_t)(exinf), (TASK)(task), INT_PRIORITY(itskpri),
											(stksz), (void *)(stk),
											(iprcid), (affinity) }

＊stkがNULLの場合
	{ (tskatr), (intptr_t)(exinf), (TASK)(task), INT_PRIORITY(itskpri),
							ROUND_STK_T(stksz), _kernel_stack_<タスク名>,
											(iprcid), (affinity) }

4.5.2.3 タスク生成順序テーブルの定義

タスクの生成された順序で，タスクの初期化（より具体的には，タスクの起動）
を行う必要があることからに，タスクが生成された順序（タスクを生成する静
的APIが記述された順序）をテーブルに出力する．

具体的には，次のような行を生成する．

const ID _kernel_torder_table[TNUM_TSKID] = {
	<最初に生成されたタスクのタスクID>,
	<2番目に生成されたタスクのタスクID>,
				……
	<最後に生成されたタスクのタスクID>
};

(6-1-4) エラー条件◎

タスクに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じtskidに対するCRE_TSKが複数ある場合（E_OBJ）［NGKI1040］

＊パス2で検出するもの
・タスクが1つも登録されていない場合［NGKI0033］
・tskatrが無効の場合（E_RSATR）［NGKI1028］
　（TA_ACT，TA_NOACTQUE，TARGET_TSKATR以外のビットがセットされている場合）
	※ TAGET_TSKATRは，ターゲット依存部で追加するタスク属性
・(TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合（E_PAR）［NGKI1034］
・stkszが0以下か，ターゲット定義の最小値（TARGET_MIN_STKSZ）よりも小さ
　い場合（E_PAR）［NGKI1042］
・stkszがスタック領域のサイズとして正しくない場合（E_PAR）［NGKI1056］
	- ターゲット依存の値（CHECK_STKSZ_ALIGN）の倍数でない場合
	※ このエラーチェックは，stkがNULLでない場合にのみ行う
・CRE_TSKがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

＊パス3で検出するもの
・taskがプログラムの開始番地として正しくない場合（E_PAR）［NGKI1033］
	- ターゲット依存の値（CHECK_FUNC_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_FUNC_NONNULL）
・stkがスタック領域の先頭番地として正しくない場合（E_PAR）［NGKI1056］
	- ターゲット依存の値（CHECK_STACK_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_STACK_NONNULL）

4.5.3 セマフォに関する定義

セマフォの省略記号は「SEM／sem」である．以下では，システムコンフィギュレー
ションファイルに次の静的APIが含まれている時に生成すべき情報について述べ
る．なお，セマフォに必要なメモリ領域はない．

	CRE_SEM(semid, { sematr, isemcnt, maxsem });

4.5.3.1 セマフォの初期化情報

セマフォ初期化ブロック中に生成するセマフォの初期化情報は，次の形式とす
る．

	{ (sematr), (isemcnt), (maxsem) }

4.5.3.2 エラー条件◎

セマフォに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じsemidに対するCRE_SEMが複数ある場合（E_OBJ）［NGKI1463］

＊パス2で検出するもの
・sematrが無効の場合（E_RSATR）［NGKI1456］
　（TA_TPRI以外のビットがセットされている場合）
・(1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合（E_PAR）［NGKI1468］
・(0 <= isemcnt && isemcnt <= maxsem)でない場合（E_PAR）［NGKI1466］
・CRE_SEMがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

4.5.4 イベントフラグに関する定義

イベントフラグの省略記号は「FLG／flg」である．以下では，システムコンフィ
ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報につ
いて述べる．なお，イベントフラグに必要なメモリ領域はない．

	CRE_FLG(flgid, { flgatr, iflgptn });

4.5.4.1 イベントフラグの初期化情報

イベントフラグ初期化ブロック中に生成するイベントフラグの初期化情報は，
次の形式とする．

	{ (flgatr), (iflgptn) }

4.5.4.2 エラー条件◎

イベントフラグに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じflgidに対するCRE_FLGが複数ある場合（E_OBJ）［NGKI1569］

＊パス1で検出するもの
・iflgptnがFLGPTNに格納できない場合（E_PAR）
	→ iflgptnがuint32_tに格納できない場合は，cfg1_out.cのコンパイル時
	   にエラーとなる．

＊パス2で検出するもの
・flgatrが無効の場合（E_RSATR）［NGKI1562］
　（TA_TPRI，TA_WMUL，TA_CLR以外のビットがセットされている場合）
・iflgptnがFLGPTNに格納できない場合（E_PAR）［NGKI3275］
	→ iflgptnがuint32_tには格納できるが，FLGPTNに格納できない場合は，
	   パス2でエラーを検出する．
・CRE_FLGがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

4.5.5 データキューに関する定義

データキューの省略記号は「DTQ／dtq」である．以下では，システムコンフィギュ
レーションファイルに次の静的APIが含まれている時に生成すべき情報について
述べる．

	CRE_DTQ(dtqid, { dtqatr, dtqcnt, dtqmb });

4.5.5.1 データキューに必要なメモリ領域の定義◎

データキューに必要なメモリ領域として，データキュー管理領域がある．生成
するデータキュー毎に，必要なサイズのデータキュー管理領域を定義する．具
体的には，上記の静的APIに対して，次の定義を生成する．

＊dtqcntが0でない場合のみ生成
static DTQMB _kernel_dtqmb_<データキュー名>[dtqcnt];

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenDTQMBを定義することにより，任意のフォーマットを変更できるため，
セクション指定等が可能である．◎

4.5.5.2 データキューの初期化情報

データキュー初期化ブロック中に生成するデータキューの初期化情報は，次の
形式とする．

	{ (dtqatr), (dtqcnt), _kernel_dtqmb_<データキュー名> }

ここで，dtqcntが0の場合には，_kernel_dtqmb_<データキュー名>に代えて，
NULLを用いる．

4.5.5.3 エラー条件◎

データキューに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じdtqidに対するCRE_DTQが複数ある場合（E_OBJ）［NGKI1677］

＊パス2で検出するもの
・dtqatrが無効の場合（E_RSATR）［NGKI1669］
　（TA_TPRI以外のビットがセットされている場合）
・dtqcntが負の値の場合（E_PAR）［NGKI3288］
・dtqmbがNULLでない場合（E_NOSPT）［FMPS0132］
・CRE_DTQがクラスの囲みの中に記述されていない場合（E_RSATR）
・使用出来ないクラスIDを指定している場合 (E_ID)◎

4.5.6 優先度データキューに関する定義

優先度データキューの省略記号は「PDQ／pdq」である．以下では，システムコ
ンフィギュレーションファイルに次の静的APIが含まれている時に生成すべき情
報について述べる．

	CRE_PDQ(ID pdqid, { pdqatr, pdqcnt, maxdpri, pdqmb });

4.5.6.1 優先度データキューに必要なメモリ領域の定義◎

優先度データキューに必要なメモリ領域として，優先度データキュー管理領域
がある．生成する優先度データキュー毎に，必要なサイズの優先度データキュー
管理領域を定義する．具体的には，上記の静的APIに対して，次の定義を生成す
る．

＊pdqcntが0でない場合のみ生成
static PDQMB _kernel_pdqmb_<優先度データキュー名>[pdqcnt];

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenPDTQMBを定義することにより，任意のフォーマットを変更できるた
め，セクション指定等が可能である．◎

4.5.6.2 優先度データキューの初期化情報

優先度データキュー初期化ブロック中に生成する優先度データキューの初期化
情報は，次の形式とする．

	{ (pdqatr), (pdqcnt), (maxdpri), _kernel_pdqmb_<優先度データキュー名> }

ここで，pdqcntが0の場合には，_kernel_pdqmb_<優先度データキュー名>に代え
て，NULLを用いる．

4.5.6.3 エラー条件◎

優先度データキューに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じpdqidに対するCRE_PDQが複数ある場合（E_OBJ）［NGKI1812］

＊パス2で検出するもの
・pdqatrが無効の場合（E_RSATR）［NGKI1804］
　（TA_TPRI以外のビットがセットされている場合）
・pdqcntが負の値の場合（E_PAR）［NGKI3289］
・(TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合（E_PAR）［NGKI1819］
・pdqmbがNULLでない場合（E_NOSPT）［FMPS0142］
・CRE_PDQがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

4.5.7 ミューテックスに関する定義

ミューテックスの省略記号は「MTX／mtx」である．以下では，システムコンフィ
ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報につ
いて述べる．なお，ミューテックスに必要なメモリ領域はない．

	CRE_MTX(mtxid, { mtxatr, maxmpri, mprihd });

4.5.7.1 ミューテックスの初期化情報

ミューテックス初期化ブロック中に生成するミューテックスの初期化情報は，
次の形式とする．

	{ (mtxatr), (maxmpri) }

4.5.7.2 エラー条件◎

ミューテックスに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じmtxidに対するCRE_MTXが複数ある場合（E_OBJ）［NGKI2032］

＊パス2で検出するもの
・mtxatrが無効の場合（E_RSATR）［NGKI2025］
　（TA_NULL，TA_TPRI，TA_CEILINGのいずれでもない場合）
・優先度上限ミューテックスで，(TMIN_MPRI <= maxmpri && maxmpri <=
　TMAX_MPRI)でない場合（E_PAR）［NGKI2037］
・CRE_MTXがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎
・ceilpriがサブ優先度を使用すると設定されている場合（E_ILUSE）◎

4.5.8 固定長メモリプールに関する定義

固定長メモリプールの省略記号は「MPF／mpf」である．以下では，システムコ
ンフィギュレーションファイルに次の静的APIが含まれている時に生成すべき情
報について述べる．

	CRE_MPF(mpfid, { mpfatr, blkcnt, blksz, mpf, mpfmb });

4.5.8.1 固定長メモリプールに必要なメモリ領域の定義◎

固定長メモリプールに必要なメモリ領域として，固定長メモリプール領域と固
定長メモリプール管理領域がある．生成する固定長メモリプール毎に，必要な
サイズの固定長メモリプール領域（mpfがNULLの場合のみ）と固定長メモリプー
ル管理領域を確保する．具体的には，上記の静的APIに対して，次の定義を生成
する．

＊mpfがNULLの場合のみ生成
static MPF_T _kernel_mpf_<固定長メモリプール名>[(blkcnt) * COUNT_MPF_T(blksz)];

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenMPF_Tを定義することにより，任意のフォーマットを変更できるため，
セクション指定等が可能である．◎

＊必ず生成
static MPFMB _kernel_mpfmb_<固定長メモリプール名>[blkcnt];

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenMPFMBを定義することにより，任意のフォーマットを変更できるため，
セクション指定等が可能である．◎

4.5.8.2 固定長メモリプールの初期化情報

固定長メモリプール初期化ブロック中に生成する固定長メモリプールの初期化
情報は，次の形式とする．

＊mpfがNULLでない場合
	{ (mpfatr), (blkcnt), ROUND_MPF_T(blksz), (void *)(mpf),
						_kernel_mpfmb_<固定長メモリプール名> }

＊mpfがNULLの場合
	{ (mpfatr), (blkcnt), ROUND_MPF_T(blksz),
						_kernel_mpf_<固定長メモリプール名>,
						_kernel_mpfmb_<固定長メモリプール名> }

4.5.8.3 エラー条件◎

固定長メモリプールに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じmpfidに対するCRE_MPFが複数ある場合（E_OBJ）［NGKI2236］

＊パス2で検出するもの
・mpfatrが無効の場合（E_RSATR）［NGKI2225］
　（TA_TPRI以外のビットがセットされている場合）
・blkcntが0以下の場合（E_PAR）［NGKI2229］
・blkszが0以下の場合（E_PAR）［NGKI2230］
・mpfmbがNULLでない場合（E_NOSPT）［FMPS0166］
・CRE_MPFがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

＊パス3で検出するもの
・mpfが固定長メモリプール領域の先頭番地として正しくない場合（E_PAR）
　［NGKI2249］
	- ターゲット依存の値（CHECK_MPF_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_MPF_NONNULL）

4.5.9 周期通知に関する定義

周期通知の省略記号は「CYC／cyc」である．以下では，システムコンフィギュ
レーションファイルに次の静的APIが含まれている時に生成すべき情報について
述べる．なお，周期通知に必要なメモリ領域はない．

	CRE_CYC(cycid, { cycatr, ＜通知方法の指定＞, cyctim, cycphs });

4.5.9.1 通知ハンドラの生成

静的API中の＜通知方法の指定＞に従って，通知ハンドラを生成する．以下では，
生成した通知ハンドラの関数名をnfyhdr，拡張情報をexinfと記述する．

ただし，＜通知方法の指定＞の最初のパラメータである通知処理モード
（nfymode）がTNFY_HANDLER（タイムイベントハンドラの呼出しによる通知）で
ある場合には，続く2つのパラメータ（タイムイベントハンドラの拡張情報と先
頭番地）の指定に従ってタイムイベントハンドラを呼び出すものとし，通知ハ
ンドラは生成しない．この場合，nfyhdrとexinfは，次の通りとする．

	nfyhdr		(NFYHDR)(＜タイムイベントハンドラの先頭番地＞)
	exinf		＜タイムイベントハンドラの拡張情報＞

なお，通知ハンドラの生成方法については，「4.6 通知ハンドラの生成」の節
を参照すること．

4.5.9.2 周期通知の初期化情報◎

周期通知初期化ブロック中に生成する周期通知の初期化情報は，次の形式とす
る．

	{ (cycatr), (intptr_t)(exinf), nfyhdr, (cyctim), (cycphs),
								 (iprcid), (affinity) }◎

4.5.9.3 エラー条件

周期通知に関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じcycidに対するCRE_CYCが複数ある場合（E_OBJ）［NGKI2392］

＊パス2で検出するもの
・cycatrが無効の場合（E_RSATR）［NGKI2383］
　（TA_STA以外のビットがセットされている場合）
・(0 < cyctim && cyctim <= TMAX_RELTIM)でない場合（E_PAR）［NGKI2397］
・(0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合（E_PAR）［NGKI2399］
・その他，通知ハンドラの生成に関するエラー（4.6.15節）を参照
・CRE_CYCがクラスの囲みの中に記述されていない場合（E_RSATR）
・割り付け可能プロセッサが時刻管理プロッサのみでない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

＊パス3で検出するもの
・通知方法中のタイムイベントハンドラの先頭番地または変数の番地が正しく
　ない（E_PAR）［NGKI3693］
	- ターゲット依存の値（CHECK_FUNC_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_FUNC_NONNULL）
・その他，通知ハンドラの生成に関するエラー（4.6.15節）を参照

4.5.10 アラーム通知に関する定義

アラーム通知の省略記号は「ALM／alm」である．以下では，システムコンフィ
ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報につ
いて述べる．なお，アラーム通知に必要なメモリ領域はない．

	CRE_ALM(ID almid, { almatr, ＜通知方法の指定＞ });

4.5.10.1 通知ハンドラの生成

静的API中の＜通知方法の指定＞に従って，通知ハンドラを生成する．以下では，
生成した通知ハンドラの関数名をnfyhdr，拡張情報をexinfと記述する．

ただし，＜通知方法の指定＞の最初のパラメータである通知処理モード
（nfymode）がTNFY_HANDLER（タイムイベントハンドラの呼出しによる通知）で
ある場合には，続く2つのパラメータ（タイムイベントハンドラの拡張情報と先
頭番地）の指定に従ってタイムイベントハンドラを呼び出すものとし，通知ハ
ンドラは生成しない．この場合，nfyhdrとexinfは，次の通りとする．

	nfyhdr		(NFYHDR)(＜タイムイベントハンドラの先頭番地＞)
	exinf		＜タイムイベントハンドラの拡張情報＞

なお，通知ハンドラの生成方法については，「4.6 通知ハンドラの生成」の節
を参照すること．

4.5.10.2 アラーム通知の初期化情報◎

アラーム通知初期化ブロック中に生成するアラーム通知の初期化情報は，次の
形式とする．

	{ (almatr), (intptr_t)(exinf), nfyhdr, (iprcid), (affinity) }

4.5.10.3 エラー条件◎

アラーム通知に関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じalmidに対するCRE_ALMが複数ある場合（E_OBJ）［NGKI2500］

＊パス2で検出するもの
・almatrが無効の場合（E_RSATR）［NGKI2491］
　（TA_STA以外のビットがセットされている場合）
・その他，通知ハンドラの生成に関するエラー（4.6.15節）を参照
・CRE_ALMがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・割り付け可能プロセッサが時刻管理プロッサのみでない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

＊パス3で検出するもの
・通知方法中のタイムイベントハンドラの先頭番地または変数の番地が正しく
　ない（E_PAR）［NGKI3693］
	- ターゲット依存の値（CHECK_FUNC_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_FUNC_NONNULL）
・その他，通知ハンドラの生成に関するエラー（4.6.15節）を参照

4.5.11 スピンロックに関する定義◎

スピンロックの省略記号は「SPN／spn」である．以下では，システムコンフィ
ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報に
ついて述べる．なお，スピンロックに必要なメモリ領域はない．

	CRE_SPN(ID spnid, {spnatr});

4.5.3.1 スピンロックの初期化情報

スピンロック初期化ブロック中に生成するスピンロックの初期化情報は，次の
形式とする．

	{ (spnatr) }

4.5.3.2 エラー条件

スピンロックに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じspnidに対するCRE_SPNが複数ある場合（E_OBJ）

＊パス2で検出するもの
・CRE_SPNがクラスの囲みの中に記述されていない場合（E_RSATR）
・使用出来ないクラスIDを指定している場合 (E_ID)
・割付け可能なハードウェアスピンロックハードウェアがない（E_NOID）
  (ネイティブスピンロック方式の場合)
・sematrが（［TA_TPRI］）でない場合（E_RSATR）
・(0 <= isemcnt && isemcnt <= maxsem)でない場合（E_PAR）
・(1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合（E_PAR）

4.6 通知ハンドラの生成

通知ハンドラは，周期通知機能とアラーム通知機能のためのイベントの通知お
よびイベント通知時に発生したエラーの通知を行うためのハンドラである．通
知ハンドラは，カーネル実装上の概念であり，外部仕様書には登場しない（タ
イムイベントハンドラと位置付けが類似しているため，混同しないように注意
すること）．

FMP3カーネルでは，コンフィギュレータにより，周期通知毎およびアラーム通
知毎に通知ハンドラを生成する．ただし，タイムイベントハンドラの呼出しに
よる通知の場合には，通知ハンドラを生成せず，直接タイムイベントハンドラ
を呼び出す．

生成する通知ハンドラの枠組みは次の通り．

(a) エラーの通知を行わない場合

static void
_kernel_nfyhdr_<cycid または almid>(intptr_t exinf)
{
	(void) ＜イベントの通知処理＞;
}

(b) エラーの通知を行う場合

static void
_kernel_nfyhdr_<cycid または almid>(intptr_t exinf)
{
	ER		ercd;

	ercd = ＜イベントの通知処理＞;
	if (ercd != E_OK) {
		(void) ＜エラーの通知処理＞;
	}
}

＜イベントの通知処理＞と＜エラーの通知処理＞は，＜通知方法の指定＞の最
初のパラメータである通知処理モード（nfymode）により定まる．具体的には，
nfymodeの下位4ビット（以下，これをnfymode1と書く）でイベントの通知方法
を，残りのビット（以下，これをnfymode2と書く）でエラーの通知方法を指定
する．

4.6.1 変数の設定によるイベント通知

nfymode1がTNFY_SETVAR（変数の設定によるイベント通知）の場合には，続く2
つのパラメータ（変数の番地と設定する値）の指定に従って変数を設定するも
のとする．コンフィギュレータのパス3でのエラーチェックを可能にするために，
変数の番地は，exinfとして通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	*((intptr_t *) exinf) = (＜設定する値＞);

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜変数の番地＞

なお，変数の設定によるイベント通知の場合，エラーが検出されることはない
ため，エラーの通知は意味がない．エラーの通知が指定されていた場合，コン
フィギュレータはエラーを報告する．

4.6.2 変数のインクリメントによるイベントの通知

nfymode1がTNFY_INCVAR（変数のインクリメントによるイベント通知）の場合に
は，続く1つのパラメータ（変数の番地）の指定に従って変数をインクリメント
するものとする．コンフィギュレータのパス3でのエラーチェックを可能にする
ために，変数の番地は，exinfとして通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	loc_cpu();
	*((intptr_t *) exinf) += 1;
	unl_cpu();

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜変数の番地＞

なお，変数の設定によるイベント通知の場合，エラーが検出されることはない
ため，エラーの通知は意味がない．エラーの通知が指定されていた場合，コン
フィギュレータはエラーを報告する．

4.6.3 タスクの起動によるイベント通知

nfymode1がTNFY_ACTTSK（タスクの起動によるイベント通知）の場合には，続く
1つのパラメータ（タスクID）の指定に従ってタスクを起動するものとする．コ
ンフィギュレータのパス3でのエラーチェックを可能にするために，タスクIDは，
exinfとして通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	act_tsk((ID) exinf);

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜タスクID＞

4.6.4 タスクの起床によるイベント通知

nfymode1がTNFY_WUPTSK（タスクの起床によるイベント通知）の場合には，続く
1つのパラメータ（タスクID）の指定に従ってタスクを起床するものとする．コ
ンフィギュレータのパス3でのエラーチェックを可能にするために，タスクIDは，
exinfとして通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	wup_tsk((ID) exinf);

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜タスクID＞

4.6.5 セマフォの返却によるイベント通知

nfymode1がTNFY_SIGSEM（セマフォの返却によるイベント通知）の場合には，続
く1つのパラメータ（セマフォID）の指定に従ってセマフォを返却を起動するも
のとする．コンフィギュレータのパス3でのエラーチェックを可能にするために，
セマフォIDは，exinfとして通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	sig_sem((ID) exinf);

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜セマフォID＞

4.6.6 イベントフラグのセットによるイベント通知

nfymode1がTNFY_SETFLG（イベントフラグのセットによるイベント通知）の場合
には，続く2つのパラメータ（イベントフラグIDとセットするビットパターン）
の指定に従ってイベントフラグをセットするものとする．コンフィギュレータ
のパス3でのエラーチェックを可能にするために，イベントフラグIDは，exinf
として通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	set_flg((ID) exinf, ＜セットするビットパターン＞);

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜イベントフラグID＞

4.6.7 データキューへの送信によるイベント通知

nfymode1がTNFY_SNDDTQ（データキューへの送信によるイベント通知）の場合に
は，続く2つのパラメータ（データキューIDと送信する値）の指定に従ってデー
タキューへ送信するものとする．コンフィギュレータのパス3でのエラーチェッ
クを可能にするために，データキューIDは，exinfとして通知ハンドラに渡す．

具体的には，＜イベントの通知処理＞には，次のコードを生成する．

	snd_dtq((ID) exinf, ＜送信する値＞);

周期／アラーム通知初期化ブロックに登録するnfyhdrとexinfは，次の通りとす
る．

	nfyhdr		_kernel_nfyhdr_<cycid または almid>
	exinf		＜データキューID＞

4.6.8 変数の設定によるエラー通知

nfymode2がTENFY_SETVAR（変数の設定によるエラー通知）の場合には，続く1つ
のパラメータ（変数の番地）の指定に従って，エラーコードを変数に設定する
ものとする．コンフィギュレータのパス3でのエラーチェックを可能にするため
に，変数の番地は，グローバル変数を通じてて通知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	intptr_t *const _kernel_nfyhdr_<cycid または almid>_p_evar
										= (intptr_t *)(＜変数の番地＞);

また，＜エラーの通知処理＞には，次のコードを生成する．

	*((intptr_t *) _kernel_nfyhdr_<cycid または almid>_p_evar)
													= (intptr_t) ercd;

4.6.9 変数のインクリメントによるエラー通知

nfymode2がTENFY_INCVAR（変数のインクリメント設定によるエラー通知）の場
合には，続く1つのパラメータ（変数の番地）の指定に従って変数をインクリメ
ントするものとする．コンフィギュレータのパス3でのエラーチェックを可能に
するために，変数の番地は，グローバル変数を通じてて通知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	intptr_t *const _kernel_nfyhdr_<cycid または almid>_p_evar
										= (intptr_t *)(＜変数の番地＞);

また，＜エラーの通知処理＞には，次のコードを生成する．

	loc_cpu();
	*((intptr_t *) _kernel_nfyhdr_<cycid または almid>_p_evar) += 1;
	unl_cpu();

4.6.10 タスクの起動によるエラー通知

nfymode2がTENFY_ACTTSK（タスクの起動によるエラー通知）の場合には，続く
1つのパラメータ（タスクID）の指定に従ってタスクを起動するものとする．コ
ンフィギュレータのパス3でのエラーチェックを可能にするために，タスクIDは，
グローバル変数を通じて通知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	const ID _kernel_nfyhdr_<cycid または almid>_etskid
													= ＜タスクID＞;

また，＜エラーの通知処理＞には，次のコードを生成する．

	act_tsk(_kernel_nfyhdr_<cycid または almid>_etskid);

4.6.11 タスクの起床によるエラー通知

nfymode2がTENFY_WUPTSK（タスクの起床によるエラー通知）の場合には，続く
1つのパラメータ（タスクID）の指定に従ってタスクを起床するものとする．コ
ンフィギュレータのパス3でのエラーチェックを可能にするために，タスクIDは，
グローバル変数を通じて通知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	const ID _kernel_nfyhdr_<cycid または almid>_etskid
													= ＜タスクID＞;

また，＜エラーの通知処理＞には，次のコードを生成する．

	wup_tsk(_kernel_nfyhdr_<cycid または almid>_ptskid);

4.6.12 セマフォの返却によるエラー通知

nfymode2がTENFY_SIGSEM（セマフォの返却によるエラー通知）の場合には，続
く1つのパラメータ（セマフォID）の指定に従ってセマフォを返却するものとす
る．コンフィギュレータのパス3でのエラーチェックを可能にするために，セマ
フォIDは，グローバル変数を通じて通知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	const ID _kernel_nfyhdr_<cycid または almid>_esemid
													= ＜セマフォID＞;

また，＜エラーの通知処理＞には，次のコードを生成する．

	sig_sem(_kernel_nfyhdr_<cycid または almid>_esemid);

4.6.13 イベントフラグのセットによるエラー通知

nfymode2がTENFY_SETFIG（イベントフラグのセットによるエラー通知）の場合
には，続く2つのパラメータ（イベントフラグIDとセットするビットパターン）
の指定に従ってイベントフラグをセットするものとする．コンフィギュレータ
のパス3でのエラーチェックを可能にするために，イベントフラグIDは，グロー
バル変数を通じて通知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	const ID _kernel_nfyhdr_<cycid または almid>_eflgid
												= ＜イベントフラグID＞;

また，＜エラーの通知処理＞には，次のコードを生成する．

	set_flg(_kernel_nfyhdr_<cycid または almid>_eflgid,
										＜セットするビットパターン＞);

4.6.14 データキューへの送信によるエラー通知

nfymode2がTENFY_SNDDTQ（データキューへの送信によるエラー通知）の場合に
は，続く1つのパラメータ（データキューID）の指定に従って，エラーコードを
データキューへ送信するものとする．コンフィギュレータのパス3でのエラー
チェックを可能にするために，データキューIDは，グローバル変数を通じて通
知ハンドラに渡す．

具体的には，通知ハンドラの定義に先立ち，次のコードを生成する．

	const ID _kernel_nfyhdr_<cycid または almid>_edtqid
												= ＜データキューID＞;

また，＜エラーの通知処理＞には，次のコードを生成する．

	snd_dtq(_kernel_nfyhdr_<cycid または almid>_edtqid, (intptr_t) ercd);

4.6.15 エラー条件

通知ハンドラの生成に関するエラー条件は次の通りである．

＊パス2で検出するもの
・nfymodeの値が正しくない（E_PAR）［NGKI3730］［NGKI3721］

＊パス3で検出するもの
・通知方法中の変数の番地が正しくない（E_PAR）［NGKI3699］［NGKI3701］
	- ターゲット依存の値（CHECK_INTPTR_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_INTPTR_NONNULL）
・通知方法中のタスクIDが有効範囲外の場合（E_ID）［NGKI3704］
・通知方法中のセマフォIDが有効範囲外の場合（E_ID）［NGKI3707］
・通知方法中のイベントフラグIDが有効範囲外の場合（E_ID）［NGKI3710］
・通知方法中のデータキューIDが有効範囲外の場合（E_ID）［NGKI3713］
　［NGKI3715］

4.7 割込みに関する定義

4.7.1 割込みサービスルーチンに関する定義

4.7.1.1 トレースログマクロのデフォルト定義

生成する割込みハンドラcの中で使用するトレースログマクロのデフォルト定義
を生成する．具体的には，次の行を生成する．

#ifndef LOG_ISR_ENTER
#define LOG_ISR_ENTER(isrid)
#endif /* LOG_ISR_ENTER */

#ifndef LOG_ISR_LEAVE
#define LOG_ISR_LEAVE(isrid)
#endif /* LOG_ISR_LEAVE */

4.7.1.2 割込みハンドラの生成

システムコンフィギュレーションファイル中に含まれる割込みサービスルーチ
ンを追加する静的API「CRE_ISR」に対して，同一の割込み番号に対して追加さ
れた割込みサービスルーチンを順に呼び出す関数を生成する．

具体的には，同一の割込み番号に対して割込みサービスルーチンを追加する

	CRE_ISR(ISR_1, { isratr_1, exinf_1, intno, isr_1, isrpri_1 });
	CRE_ISR(ISR_2, { isratr_2, exinf_2, intno, isr_2, isrpri_2 });
		……
	CRE_ISR(ISR_N, { isratr_n, exinf_n, intno, isr_n, isrpri_n });

という静的APIに対して，次のような関数を生成する．ここで，isrpri_1，
isrpri_2，……，isrpri_nは，値の小さい順に並べ替えられているものとする．
値が同じものの間では，システムコンフィギュレーションファイル中での静的
APIの順序の通りに並んでいるものとする．

static void
_kernel_inthdr_<intno>(void)
{
	LOG_ISR_ENTER(ISR_1);		/* ISR_1の呼出し */
	((ISR)(isr_1))((intptr_t)(exinf_1));
	LOG_ISR_LEAVE(ISR_1);

	if (sense_lock()) {			/* ISRの呼出し前の状態に戻す */
		unlock_cpu();
	}

	LOG_ISR_ENTER(ISR_2);		/* ISR_2の呼出し */
	((ISR)(isr_2))((intptr_t)(exinf_2));
	LOG_ISR_LEAVE(ISR_2);

	if (sense_lock()) {			/* ISRの呼出し前の状態に戻す */
		unlock_cpu();
	}

	……

	LOG_ISR_ENTER(ISR_N);		/* ISR_Nの呼出し */
	((ISR)(isr_n))((intptr_t)(exinf_n));
	LOG_ISR_LEAVE(ISR_N);
}

ここで，ISR_Nの呼出しの後に呼出し前の状態に戻さないのは，割込みハンドラ
からのリターンにより，カーネルが元の状態に戻すためである．

同一の割込み番号に対して追加された割込みサービスルーチンが1つのみの場合
には，次のような関数を生成する．

static void
_kernel_inthdr_<intno>(void)
{
	LOG_ISR_ENTER(ISR_1);
	((ISR)(isr_1))((intptr_t)(exinf_1));
	LOG_ISR_LEAVE(ISR_1);
}

4.7.1.3 割込みハンドラの定義に相当する処理

上のように割込みハンドラを生成した場合には，次に説明する割込みハンドラ
に関する定義において，システムコンフィギュレーションファイル中に次の静
的APIが含まれているのと同様に処理する．

	DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> });

ここでinhnoは，intnoに対応する割込みハンドラ番号である．

4.7.1.4 エラー条件◎

割込みサービスルーチンに関するエラー条件は次の通りである．

＊コンフィギュレータ本体が検出するもの
・同じisridに対するCRE_ISRが複数ある場合（E_OBJ）［NGKI3009］

＊パス2で検出するもの
・isratrが無効の場合（E_RSATR）［NGKI2998］
　（TARGET_ISRATR以外のビットがセットされている場合）
	※ TAGET_ISRATRは，ターゲット依存部で追加する割込みサービスルーチン属性
・intnoがCRE_ISRに対する割込み番号として正しくない場合（E_PAR）［NGKI3003］
	※ intnoに対応するinhnoがない場合を含む
・(TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合（E_PAR）
　［NGKI3005］
・intnoに対するCFG_INTがない場合（E_OBJ）［NGKI3012］
・intnoに対応するinhnoに対してDEF_INHがある場合（E_OBJ）［NGKI3013］
・intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小さい
　場合（E_OBJ）［NGKI3014］
	※ カーネル管理外の割込みサービスルーチンはサポートしないため
・intnoがATT_ISRに対する割込み番号として正しくない場合（E_PAR）◎
  ・intnoの上位ビットで指定した割込み可能プロセッサとクラスで指定され
    ている割付け可能プロセッサが矛盾する場合．
・ATT_ISRがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎
・対応するCFG_INTと異なるクラスに属する場合（E_RSATR）◎

＊可能であればターゲット依存部で検出するもの［NGKI3020］
・isrがプログラムの開始番地として正しくない場合（E_PAR）［NGKI3004］

4.7.2 割込みハンドラに関する定義

割込みハンドラに関して生成する情報は，ターゲット毎に定めることができる．
ターゲット毎に定めない場合には，以下で述べるターゲットに依存しない標準
的な情報を生成する．

割込みハンドラを定義する静的API「DEF_INH」で定義した割込みハンドラ（上
述の割込みサービスルーチンの追加によりコンフィギュレータが生成した割込
みハンドラを含む）に関する定義を生成する．具体的には次の通り．

以下では，システムコンフィギュレーションファイルに次の静的APIが含まれ
ている時に生成すべき情報について述べる．

	DEF_INH(inhno, { inhatr, inthdr });

4.7.2.1 定義する割込みハンドラの数

定義する割込みハンドラの数をマクロ定義するプリプロセッサディレクティブ
（#define）を生成する．また，その値を持つ変数の定義を生成する．具体的
には，次のような行を生成する．

#define TNUM_DEF_INHNO <定義する割込みハンドラの数>
const uint_t	_kernel_tnum_def_inhno = TNUM_DEF_INHNO;

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

定義する割込みハンドラ毎に，割込みハンドラの出入口処理ルーチンを生成す
る．具体的には，次のような行を生成する．

INTHDR_ENTRY(inhno, inhno_num, inthdr)

ここでinhno_numは，inhno（割込みハンドラ番号）を数値で表現したもので，
アセンブリ言語記述に使用するためのものである．

4.7.2.3 割込みハンドラ初期化ブロックの定義◎

割込みハンドラ初期化ブロックを生成する．具体的には，次のような行を生成
する．

const INHINIB _kernel_inhinib_table[TNUM_DEF_INHNO] = {
	<割込みハンドラ1の初期化情報>,
	<割込みハンドラ2の初期化情報>,
				……
	<割込みハンドラTNUM_DEF_INHNOの初期化情報>
};

この中の割込みハンドラの初期化情報は，次の形式とする．◎

	{ (inhno), (inhatr), (FP)(INT_ENTRY(inhno, inthdr)), (iprcid), (affinity) }

iprcidは初期割付けプロセッサ, affinityは割付け可能プロセッサで
ある．

4.7.2.4 エラー条件

割込みハンドラに関するエラー条件は次の通りである．

＊パス2で検出するもの
・inhnoが割込みハンドラ番号として正しくない場合（E_PAR）［NGKI3055］
・inhnoがDEF_INHによって設定済みの場合（E_OBJ）［NGKI3063］
・inhatrが無効の場合（E_RSATR）［NGKI3052］
　（TARGET_INHATR以外のビットがセットされている場合）
	※ TAGET_INHATRは，ターゲット依存部で追加する割込みハンドラ属性
・カーネル管理外に固定されているinhnoに対して，inhatrにTA_NONKERNELが指
　定されていない場合（E_RSATR）［NGKI3067］
・カーネル管理に固定されているinhnoに対して，inhatrにTA_NONKERNELが指定
　されている場合（E_RSATR）［NGKI3068］
・inhnoに対応するintnoに対するCFG_INTがない場合（E_OBJ）［NGKI3062］
	※ inhnoに対応するintnoがない場合には，このチェックを行わない
#・inhnoに対応するintnoに対してCRE_ISRがある場合（E_OBJ）［NGKI3063］
#	※ inhnoに対応するintnoがない場合には，このチェックを行わない
#	→ このチェックは，割込みサービスルーチン側で行う
・inhatrにTA_NONKERNELが指定されておらず，inhnoに対応するintnoに対して
　CFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小さい場合（E_OBJ）
　［NGKI3065］
	※ inhnoに対応するintnoがない場合には，このチェックを行わない
・inhatrにTA_NONKERNELが指定されており，inhnoに対応するintnoに対して
　CFG_INTで設定された割込み優先度がTMIN_INTPRI以上である場合（E_OBJ）
　［NGKI3066］
	※ inhnoに対応するintnoがない場合には，このチェックを行わない
・intnoがDEF_INHに対する割込み番号として正しくない場合（E_PAR）◎
  ・intnoの上位ビットで指定した割込み可能プロセッサとクラスで指定され
    ている割付け可能プロセッサが矛盾する場合．
・ATT_ISRがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎
・対応するCFG_INTと異なるクラスに属する場合（E_RSATR）◎

＊可能であればターゲット依存部で検出するもの［NGKI3080］
・inthdrがプログラムの開始番地として正しくない場合（E_PAR）［NGKI3056］

4.7.3 割込み要求ラインに関する定義◎

割込み要求ラインに関して生成する情報は，ターゲット毎に定めることができ
る．ターゲット毎に定めない場合には，以下で述べるターゲットに依存しない
標準的な情報を生成する．

割込み要求ラインの属性を設定する静的API「CFG_INT」で設定した割込み要求
ラインに関する定義を生成する．具体的には次の通り．

以下では，システムコンフィギュレーションファイルに次の静的APIが含まれ
ている時に生成すべき情報について述べる．

	CFG_INT(INTNO intno, { intatr, intpri });

4.7.3.1 設定する割込み要求ラインの数

設定する割込み要求ラインの数をマクロ定義するプリプロセッサディレクティ
ブ（#define）を生成する．また，その値を持つ変数の定義を生成する．具体的
には，次のような行を生成する．

#define TNUM_CFG_INTNO <設定する割込み要求ラインの数>
const uint_t	_kernel_tnum_cfg_intno = TNUM_CFG_INTNO;

4.7.3.2 割込み要求ライン初期化ブロックの定義◎

割込み要求ライン初期化ブロックを生成する．具体的には，次のような行を生
成する．

const INTINIB _kernel_intinib_table[TNUM_CFG_INTNO] = {
	<割込み要求ライン1の初期化情報>,
	<割込み要求ライン2の初期化情報>,
				……
	<割込み要求ラインTNUM_CFG_INTNOの初期化情報>
};

この中の割込み要求ラインの初期化情報は，次の形式とする． 

	{ (intno), (intatr), (intpri),  (iprcid), (affinity)} ◎

4.7.3.3 エラー条件◎

割込み要求ラインに関するエラー条件は次の通りである．

＊パス2で検出するもの
・intnoが割込み番号として正しくない場合（E_PAR）［NGKI2972］
・intnoがCFG_INTによって設定済みの場合（E_OBJ）［NGKI2976］
・intatrが無効の場合（E_RSATR）［NGKI2969］
　（TA_ENAINT，TA_EDGE，TARGET_INTATR以外のビットがセットされている場合）
	※ TAGET_INTATRは，ターゲット依存部で追加する割込み要求ライン属性
・intpriがCFG_INTに対する割込み優先度として正しくない場合（E_PAR）［NGKI2973］
・カーネル管理外に固定されているintnoに対して，intpriにTMIN_INTPRIより
　も小さい値が指定されなかった場合（E_OBJ）［NGKI2983］
・カーネル管理に固定されているintnoに対して，intpriにTMIN_INTPRIよりも
　小さい値が指定された場合（E_OBJ）［NGKI2984］
・intnoがCFG_INTに対する割込み番号として正しくない場合（E_PAR）◎
  ・intnoの上位ビットで指定した割込み可能プロセッサとクラスで指定され
    ている割付け可能プロセッサが矛盾する場合．
・CFG_INTがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎
・対応するDEF_INH/ATT_ISRと異なるクラスに属する場合（E_RSATR）◎


＊必要に応じてターゲット依存部で検出するもの［NGKI2986］
・intatrが割込み属性として設定できない値の場合（E_RSATR）［NGKI2985］
・intpriが割込み優先度として設定できない値の場合（E_PAR）［NGKI2985］
・同一の割込み優先度しか設定できない割込み要求ラインに対して，異なる割
　込み優先度を設定した場合（E_PAR）［NGKI2985］

4.8 CPU例外に関する定義

CPU例外に関して生成する情報は，ターゲット毎に定めることができる．ターゲッ
ト毎に定めない場合には，以下で述べるターゲットに依存しない標準的な情報
を生成する．

システムコンフィギュレーションファイル中に，CPU例外ハンドラを定義する
静的API「DEF_EXC」が含まれている場合に，CPU例外ハンドラに関する定義を
生成する．

以下では，システムコンフィギュレーションファイルに次の静的APIが含まれ
ている時に生成すべき情報について述べる．

	DEF_EXC(excno, { excatr, exchdr });

4.8.1 定義するCPU例外ハンドラの数

定義するCPU例外ハンドラの数をマクロ定義するプリプロセッサディレクティブ
（#define）を生成する．また，その値を持つ変数の定義を生成する．具体的に
は，次のような行を生成する．

#define TNUM_DEF_EXCNO <定義するCPU例外ハンドラの数>
const uint_t	_kernel_tnum_def_excno = TNUM_DEF_EXCNO;

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

定義するCPU例外ハンドラ毎に，CPU例外ハンドラの出入口処理ルーチンを生成
する．具体的には，次のような行を生成する．

EXCHDR_ENTRY(excno, excno_num, exchdr)

ここでexcno_numは，excno（CPU例外ハンドラ番号）を数値で表現したもので，
アセンブリ言語記述に使用するためのものである．

4.8.3 CPU例外ハンドラ初期化ブロックの定義

CPU例外ハンドラ初期化ブロックを生成する．具体的には，次のような行を生成
する．

const EXCINIB _kernel_excinib_table[TNUM_DEF_EXCNO] = {
	<CPU例外ハンドラ1の初期化情報>,
	<CPU例外ハンドラ2の初期化情報>,
				……
	<CPU例外ハンドラTNUM_DEF_EXCNOの初期化情報>
};

この中のCPU例外ハンドラの初期化情報は，次の形式とする．

	{ (excno), (excatr), (FP)(EXC_ENTRY(excno, exchdr)) }

4.8.4 エラー条件◎

CPU例外ハンドラに関するエラー条件は次の通りである．

＊パス2で検出するもの
・excnoがCPU例外ハンドラ番号として正しくない場合（E_PAR）［NGKI3134］
・excnoがDEF_EXCによって設定済みの場合（E_OBJ）［NGKI3141］
・excatrが無効の場合（E_RSATR）［NGKI3131］
　（TARGET_EXCATR以外のビットがセットされている場合）
	※ TAGET_EXCATRは，ターゲット依存部で追加するCPU例外ハンドラ属性
・DEF_EXCがクラスの囲みの中に記述されていない場合（E_RSATR）◎
・使用出来ないクラスIDを指定している場合 (E_ID)◎

＊可能であればターゲット依存部で検出するもの［NGKI3149］
・exchdrがプログラムの開始番地として正しくない場合（E_PAR）［NGKI3135］

4.9 非タスクコンテキスト用のスタック領域に関する定義

非タスクコンテキスト用のスタック領域に関する定義は，必ず生成しなければ
ならない．

4.9.1 DEF_ICSがない場合◎

システムコンフィギュレーションファイルに，静的API「DEF_ICS」が含まれて
いない場合には，プロセッサIDを「x」とするとプロセッサ毎に次のような行
を生成する．

#ifdef DEFAULT_PRCx_ISTK
#define TOPPERS_PRCx_ISTKSZ		DEFAULT_PRCx_ISTKSZ
#define TOPPERS_PRCx_ISTK		DEFAULT_PRCx_ISTK
#else /* DEFAULT_ISTK */
static STK_T				_kernel_prcx_istack[COUNT_STK_T(DEFAULT_PRCx_ISTKSZ)];
#define TOPPERS_PRCx_ISTKSZ	ROUND_STK_T(DEFAULT_PRCx_ISTKSZ)
#define TOPPERS_PRCx_ISTK	_kernel_prcx_istack
#endif /* DEFAULT_ISTK */

_kernel_prcx_istack に関しては，ターゲット依存部のコンフィギュレータテ
ンプレートファイルで，関数TargetGenISTACKを定義することにより，任意の
フォーマットを変更できるため，セクション指定等が可能である．

4.9.2 DEF_ICSがある場合◎

以下では，システムコンフィギュレーションファイルに次の静的APIが含まれて
いる時に生成すべき情報について述べる．

	DEF_ICS({ istksz, istk });

istkがNULLの場合には，指定されたサイズの非タスクコンテキスト用のスタッ
ク領域を確保し，非タスクコンテキスト用のスタック領域の初期化情報を生成
する．具体的には，上記の静的APIに対して，プロセッサIDを「x」とすると，
次の行を生成する．

static STK_T				_kernel_prcx_istack[COUNT_STK_T(istksz)];
#define TOPPERS_PRCx_ISTKSZ	ROUND_STK_T(istksz)
#define TOPPERS_PRCx_ISTK	_kernel_istack

_kernel_prcx_istack に関しては，ターゲット依存部のコンフィギュレータテ
ンプレートファイルで，関数TargetGenISTACK_ICSを定義することにより，任
意のフォーマットを変更できるため，セクション指定等が可能である．

istkがNULLでない場合には，非タスクコンテキスト用のスタック領域の初期化
情報を，プロセッサIDを「x」とすると，次の形式で生成する．

#define TOPPERS_PRCx_ISTKSZ		(istksz)
#define TOPPERS_PRCx_ISTK		(istk)

4.9.3 変数の生成◎

DEF_ICSの有無によらず，次の定義を生成する．「x/y」は，プロセッサIDを示
す．

const SIZE		_kernel_istksz_table[TNUM_PRCID] = {
	TOPPERS_PRCx_ISTKSZ,
	TOPPERS_PRCy_ISTKSZ,
	...
};

STK_T *const	_kernel_istk_table[TNUM_PRCID] = {
	TOPPERS_PRCx_ISTK,
	TOPPERS_PRCy_ISTK,
	...
}

#ifdef TOPPERS_ISTKPT
STK_T *const	_kernel_istkpt_table[TNUM_PRCID] = {
	TOPPERS_ISTKPT(TOPPERS_PRCx_ISTK, TOPPERS_PRCx_ISTKSZ),
	TOPPERS_ISTKPT(TOPPERS_PRCy_ISTK, TOPPERS_PRCy_ISTKSZ),
	...
}
#endif /* TOPPERS_ISTKPT */

4.9.4 エラー条件

非タスクコンテキスト用のスタック領域に関するエラー条件は次の通りである．

＊パス2で検出するもの
・静的API「DEF_ICS」が複数ある（E_OBJ）［NGKI3216］
・istkszが0以下か，ターゲット定義の最小値（TARGET_MIN_ISTKSZ）よりも小
　さい場合（E_PAR）［NGKI3254］
・istkszがスタック領域のサイズとして正しくない場合（E_PAR）［NGKI3222］
	- ターゲット依存の値（CHECK_STKSZ_ALIGN）の倍数でない場合
	※ このエラーチェックは，istkがNULLでない場合にのみ行う
・1つのプロセッサに対する静的API「DEF_ICS」が複数ある（E_OBJ）◎

＊パス3で検出するもの
・istkがスタック領域の先頭番地として正しくない場合（E_PAR）［NGKI3222］
	- ターゲット依存の値（CHECK_STACK_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_STACK_NONNULL）

4.10 タイムイベント管理に関する定義◎

タイムイベント処理プロセッサ毎に，以下の定義を生成する．「x」はプロセ
ッサIDを示す．

TMEVTN	_kernel_prcx_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];

非タイムイベント処理プロセッサでは上記を0の配列として宣言する．

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenTMEVTN_HEAPを定義することにより，任意のフォーマットを変更でき
るため，セクション指定等が可能である．

また，上記配列へのアクセスのためのテーブルを生成する．「x/y」はプロセ
ッサIDを示す．

TEVTCB* const _kernel_p_tevtcb_table[TNUM_PRCID] = {
	 &_kernel_prcx_tevtcb,
	 &_kernel_prcy_tevtcb,
	...
};

4.11 各モジュールの初期化関数の定義

各カーネルオブジェクトの管理，割込み管理，CPU例外ハンドラ管理の各機能を
初期化関数を順に呼び出す関数（_kernel_initialize_object）を生成する．次
の3つの初期化関数を除いては，使用しない機能の初期化関数は呼び出さない．

	_kernel_initialize_task
	_kernel_initialize_interrupt
	_kernel_initialize_exception

すべての機能を使った場合に生成される関数は次の通りである．

void
_kernel_initialize_object(void)
{
	_kernel_initialize_task();
	_kernel_initialize_semaphore();
	_kernel_initialize_eventflag();
	_kernel_initialize_dataqueue();
	_kernel_initialize_pridataq();
	_kernel_initialize_mutex();
	_kernel_initialize_mempfix();
	_kernel_initialize_cyclic();
	_kernel_initialize_alarm();
	_kernel_initialize_interrupt();
	_kernel_initialize_exception();
}

4.12 初期化ルーチンの実行関数の定義◎

システムコンフィギュレーションファイル中に含まれる初期化ルーチンを追加
する静的API「ATT_INI」に対して，追加した初期化ルーチンを順に呼び出す関
数を生成する．

初期化ルーチンは，クラスに属さないグローバル初期化ルーチンとクラスに属
するローカル初期化ルーチンに分けられる．

ATT_INI({ TA_NULL, 0, timer_initialize });

CLASS(1){
	ATT_INI({ TA_NULL, CONSOLE_PORTID1, serial_initialize });
}

CLASS(2){
	ATT_INI({ TA_NULL, CONSOLE_PORTID2, serial_initialize });
}

という3つの静的APIがこの順序で記述された時に生成する関数は次の通りであ
る．クラスID1,2の初期割付けプロセッサのIDはそれぞれ1,2である．

void
_kernel_call_global_inirtn(void)
{
	(timer_initialize)((intptr_t)(0));
}

void
_kernel_call_inirtn(void)
{
	if (x_prc_index() == INDEX_PRC(1)) {
		(serial_initialize)((intptr_t)(CONSOLE_PORTID1));
	}
	if (x_prc_index() == INDEX_PRC(2)) {
		(serial_initialize)((intptr_t)(CONSOLE_PORTID2));
	}
}

4.12.1 エラー条件

初期化ルーチンに関するエラー条件は次の通りである．

＊パス2で検出するもの
・iniatrが無効の場合（E_RSATR）［NGKI3241］
　（TA_NULLでない場合）

＊可能であればターゲット依存部で検出するもの［NGKI3246］
・inirtnがプログラムの開始番地として正しくない場合（E_PAR）［NGKI3243］

4.13 終了処理ルーチンの実行関数の定義

システムコンフィギュレーションファイル中に含まれる終了処理ルーチンを追
加する静的API「ATT_TER」に対して，追加した終了処理ルーチンを順に呼び出
す関数を生成する．

終了処理ルーチンは，クラスに属さないグローバル終了処理ルーチンと，クラ
スに属するローカル初期化ルーチンに分かれる．

ATT_TER({ TA_NULL, 0, timer_terminate });

CLASS(1){
	ATT_TER({ TA_NULL, CONSOLE_PORTID1, serial_terminate });
}

CLASS(2){
	ATT_TER({ TA_NULL, CONSOLE_PORTID1, serial_terminate });
}

という3つの静的APIがこの順序で記述された時に生成する関数は次の通りであ
る．

void
_kernel_call_global_terrtn(void)
{
	(timer_terminate)((intptr_t)(0));
}

void
_kernel_call_local_terrtn(void)
{
	if (x_prc_index() == INDEX_PRC(1)) {
		(serial_terminate)((intptr_t)(CONSOLE_PORTID1));
	}

	if (x_prc_index() == INDEX_PRC(2)) {
		(serial_terminate)((intptr_t)(CONSOLE_PORTID2));
	}
}

4.13.1 エラー条件

終了処理ルーチンに関するエラー条件は次の通りである．

＊パス2で検出するもの
・teratrが無効の場合（E_RSATR）［NGKI3248］
　（TA_NULLでない場合）

＊可能であればターゲット依存部で検出するもの［NGKI3253］
・terrtnがプログラムの開始番地として正しくない場合（E_PAR）［NGKI3250］

4.14 プロセッサに関する定義

(a) コントロールブロックの定義

プロセッサ毎にプロセッサコントロールブロック(Processor Control Block)
の定義を生成する．具体的には，プロセッサIDを「x」とするとプロセッサ毎
に次のような行を生成する．

PCB _kernel_prcX_pcb;

ターゲット依存部のコンフィギュレータテンプレートファイルで，関数
TargetGenPCBを定義することにより，任意のフォーマットを変更できるため，
セクション指定等が可能である．

(b) プロセッサコントロールブロックへのアクセステーブル

各プロセッサのプロセッサIDを用いてそのプロセッサのプロセッサコントロー
ルブロックへアクセスするためのテーブルの定義を生成する．具体的には次の
ような行を生成する．

PCB* const _kernel_p_pcb_table[TNUM_PRCID] = {
	&_kernel_prc1_pcb,
	&_kernel_prc2_pcb,
	...
};

4.15 アイドル時のスタックに関する定義

アイドル時のスタック領域に関する定義は，必ず生成しなければならない．

プロセッサIDを「x」とするとプロセッサ毎に次のような行
を生成する．

#ifdef DEFAULT_PRCx_IDSTK
#define TOPPERS_PRCx_IDSTKSZ	DEFAULT_PRCx_IDSTKSZ
#define TOPPERS_PRCx_IDSTK		DEFAULT_PRCx_IDSTK
#else /* DEFAULT_IDSTK */
static STK_T					_kernel_prcx_istack[COUNT_STK_T(DEFAULT_PRCx_IDSTKSZ)];
#define TOPPERS_PRCx_IDSTKSZ	ROUND_STK_T(DEFAULT_PRCx_IDSTKSZ)
#define TOPPERS_PRCx_IDSTK		_kernel_prcx_istack
#endif /* DEFAULT_IDSTK */

#ifdef TOPPERS_ISTKPT
STK_T *const	_kernel_istkpt_table[TNUM_PRCID] = {
	TOPPERS_ISTKPT(TOPPERS_PRCx_IDSTK, TOPPERS_PRCx_IDSTKSZ),
	TOPPERS_ISTKPT(TOPPERS_PRCy_IDSTK, TOPPERS_PRCy_IDSTKSZ),
	...
}
#endif /* TOPPERS_ISTKPT */

_kernel_prcx_idstack に関しては，ターゲット依存部のコンフィギュレータ
テンプレートファイルで，関数TargetGenIDSTACKを定義することにより，任意
のフォーマットを変更できるため，セクション指定等が可能である．

4.16 サブ優先度機能に関する定義◎

システムコンフィギュレーションファイルに次の静的APIが含まれている時に
必要なエラー条件について述べる．なお，サブ優先度機能に必要なメモリ領域は
ない．

	ENA_SPR(PRI tskpri)

＊パス2で検出するもの
・(TMIN_TPRI <= tskpri && tskpri <= TMAX_TPRI)でない場合 (E_PAR)［NGKI3678］
・クラスの囲みの中に記述されている (E_RSATR) [NGKI3677]

以上
