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

		対応バージョン: Release 1.9.2
		最終更新: 2013年12月31日

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

----------------------------------------------------------------------
 TOPPERS/ASP Kernel
     Toyohashi Open Platform for Embedded Real-Time Systems/
     Advanced Standard Profile Kernel

 Copyright (C) 2005-2013 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 2728 2015-12-30 01:46:11Z ertl-honda $
----------------------------------------------------------------------

○目次

・生成するファイルの種類
・静的API一覧
・カーネル構成・初期化ヘッダファイル（kernel_cfg.h）
	(1) 固定生成部分
	(2) オブジェクト数の定義
	(3) オブジェクトのID番号の定義
・カーネル構成・初期化ファイル（kernel_cfg.c）
	(1) 固定生成部分
	(2) カーネルの種類のチェック
	(3) インクルードディレクティブ（#include）の処理
	(4) トレースログマクロのデフォルト定義
	(5) オブジェクトのID番号を保持する変数の定義
	(6) 各カーネルオブジェクトに関する定義
	(7) 割込みに関する定義
	(8) CPU例外に関する定義
	(9) 非タスクコンテキスト用のスタック領域に関する定義
	(10) タイムイベント管理に関する定義
	(11) 各モジュールの初期化関数の定義
	(12) 初期化ルーチンの実行関数の定義
	(13) 終了処理ルーチンの実行関数の定義


○生成するファイルの種類

ASPカーネルのコンフィギュレータは，システムコンフィギュレーションファイ
ルを処理して，カーネル構成・初期化ファイル（kernel_cfg.c）と構成・初期
化ヘッダファイル（kernel_cfg.h）を生成する．また，コンフィギュレータの
処理の途中に，必要な中間ファイルを生成する．


○静的API一覧

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

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

(2) タスク例外処理機能
	DEF_TEX(ID tskid, { ATR texatr, TEXRTN texrtn })

(3) 同期・通信機能
	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_MBX(ID mbxid, { ATR mbxatr, PRI maxmpri, void *mprihd })

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

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

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

(5) 時間管理機能
	CRE_CYC(ID cycid, { ATR cycatr, intptr_t exinf, CYCHDR cychdr,
								RELTIM cyctim, RELTIM cycphs })
	CRE_ALM(ID almid, { ATR almatr, intptr_t exinf, ALMHDR almhdr })

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

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

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

これらの静的APIのパラメータの内，ID型のパラメータはオブジェクト識別名，
ポインタ型（void *，TASK，TEXRTN，CYCHDR，ALMHDR，ISR，INTHDR，EXCHDR，
INIRTN，TERRTN，STK_T *，MPF_T *）およびintptr_t型のパラメータは一般定
数式パラメータとする．その他のパラメータは，整数定数式パラメータとする．


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

カーネル構成・初期化ヘッダファイル（kernel_cfg.h）には，次の定義を生成
する．

(1) 固定生成部分

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

#ifndef	TOPPERS_KERNEL_CFG_H
#define	TOPPERS_KERNEL_CFG_H

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

#endif	/* TOPPERS_KERNEL_CFG_H */

(2) オブジェクト数の定義

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

#define TNUM_TSKID	<タスクの数>
#define TNUM_SEMID	<セマフォの数>
#define TNUM_FLGID	<イベントフラグの数>
#define TNUM_DTQID	<データキューの数>
#define TNUM_PDQID	<優先度データキューの数>
#define TNUM_MBXID	<メールボックスの数>
#define TNUM_MPFID	<固定長メモリプールの数>
#define TNUM_CYCID	<周期ハンドラの数>
#define TNUM_ALMID	<アラームハンドラの数>

(3) オブジェクトのID番号の定義

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

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


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

(1) 固定生成部分

kernel_cfg.c用のヘッダファイルとID自動割付け結果ファイルをインクルード
するプリプロセッサディレクティブ（#include）を生成する．具体的には，次
の行を生成する．

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

(2) カーネルの種類のチェック

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

#if TKERNEL_PRID != 0x07u
#error The kernel does not match this configuration file.
#endif

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

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

#include "sample1.h"

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

#include "sample1.h"

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

(4) トレースログマクロのデフォルト定義

kernel_cfg.cの中で使用するトレースログマクロのデフォルト定義を生成する．
具体的には，次の行を生成する．

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

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

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

コンフィギュレータに対するオプション指定（--external-id）により，コンフィ
ギュレータがID 番号を割り付けたオブジェクトの名前の末尾に"_id"を付加し
た名前の変数を生成する．変数は，const属性を付加したID型の変数とし，割り
付けたID番号を値とする．例えば，次のような記述を生成する．

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

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

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

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

コンフィギュレータに対するオプション指定（--id-input-file）により，コン
フィギュレータがオブジェクトに割り付けるID番号を指定することができる．
同じ種類の異なるオブジェクトに対して同じID番号を指定したり，コンフィギュ
レータがID番号をできる限り連続するように割り付けたとしてもID番号が連続
しない場合には（ASPカーネルは，オブジェクトの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のオブジェクトの初期化情報>
};

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

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

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

XXXCB _kernel_xxxcb_table[TNUM_XXXID];

(6-1) タスクに関する定義

ASPカーネルは，タスクが一つもないケースに対応していないため，タスクに関
する定義は必ず生成しなければならない．

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

タスク初期化ブロックには，「CRE_TSK」静的APIで指定される情報に加えて，
「DEF_TEX」静的APIで指定される情報を含める．

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

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

(6-1-1) タスクに必要なメモリ領域の定義

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

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

(6-1-2) タスクの初期化情報

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

	{ (tskatr), (intptr_t)(exinf), (task), INT_PRIORITY(itskpri),
								(stksz), (stk), (texatr), (texrtn) }

ここで，stkがNULLの場合には，(stksz)に代えてROUND_STK_T(stksz)を，
(stk)に代えて(_kernel_stack_<タスク名>)を生成する．CRE_TSKに対応する
DEF_TEXがない場合には，texatrをTA_NULL，texrtnをNULLとする．

(6-1-3) タスク生成順序テーブルの定義

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

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

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

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

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

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

＊パス2で検出するもの
・tskatrが（［TA_ACT］）でない場合（E_RSATR）
	※ ターゲット依存部でタスク属性を追加可（TARGET_TSKATR）
・(TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合（E_PAR）
・stkszが0以下か，ターゲット定義の最小値（TARGET_MIN_STKSZ）よりも小さ
　い場合（E_PAR）
・stkszがスタック領域のサイズとして正しくない場合（E_PAR）
	- ターゲット依存の値（CHECK_STKSZ_ALIGN）の倍数でない場合
	※ このエラーチェックは，stkがNULLでない場合にのみ行う
・texatrが（TA_NULL）でない場合（E_RSATR）

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

(6-2) セマフォに関する定義

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

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

(6-2-1) セマフォの初期化情報

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

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

(6-2-2) エラー条件

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

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

＊パス2で検出するもの
・sematrが（［TA_TPRI］）でない場合（E_RSATR）
・(0 <= isemcnt && isemcnt <= maxsem)でない場合（E_PAR）
・(1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合（E_PAR）

(6-3) イベントフラグに関する定義

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

CRE_FLG(flgid, { flgatr, iflgptn });

(6-3-1) イベントフラグの初期化情報

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

	{ (flgatr), (iflgptn) }

(6-3-2) エラー条件

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

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

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

＊パス2で検出するもの
・flgatrが（［TA_TPRI］｜［TA_WMUL］｜［TA_CLR］）でない場合（E_RSATR）
・iflgptnがFLGPTNに格納できない場合（E_PAR）
	→ iflgptnがuint32_tには格納できるが，FLGPTNに格納できない場合は，
	   パス2でエラーを検出する．

(6-4) データキューに関する定義

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

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

(6-4-1) データキューに必要なメモリ領域の定義

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

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

(6-4-2) データキューの初期化情報

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

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

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

(6-4-3) エラー条件

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

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

＊パス2で検出するもの
・dtqatrが（［TA_TPRI］）でない場合（E_RSATR）
・dtqcntが負の値の場合（E_PAR）
・dtqmbがNULLでない場合（E_NOSPT）

(6-5) 優先度データキューに関する定義

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

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

(6-5-1) 優先度データキューに必要なメモリ領域の定義

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

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

(6-5-2) 優先度データキューの初期化情報

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

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

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

(6-5-3) エラー条件

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

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

＊パス2で検出するもの
・pdqatrが（［TA_TPRI］）でない場合（E_RSATR）
・pdqcntが負の値の場合（E_PAR）
・(TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合（E_PAR）
・pdqmbがNULLでない場合（E_NOSPT）

(6-6) メールボックスに関する定義

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

CRE_MBX(mbxid, { mbxatr, maxmpri, mprihd });

(6-6-1) メールボックスの初期化情報

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

	{ (mbxatr), (maxmpri) }

(6-6-2) エラー条件

メールボックスに関するエラー条件は次の通りである．

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

＊パス2で検出するもの
・mbxatrが（［TA_TPRI］｜［TA_MPRI］）でない場合（E_RSATR）
・(TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合（E_PAR）
・mprihdがNULLでない場合（E_NOSPT）

(6-7) 固定長メモリプールに関する定義

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

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

(6-7-1) 固定長メモリプールに必要なメモリ領域の定義

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

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

(6-7-2) 固定長メモリプールの初期化情報

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

	{ (mpfatr), (blkcnt), ROUND_MPF_T(blksz), mpf,
						(_kernel_mpfmb_<固定長メモリプール名>) }

ここで，mpfがNULLの場合には，mpfに代えて，_kernel_mpf_<固定長メモリプー
ル名>を用いる．

(6-7-3) エラー条件

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

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

＊パス2で検出するもの
・mpfatrが（［TA_TPRI］）でない場合（E_RSATR）
・blkcntが0以下の場合（E_PAR）
・blkszが0以下の場合（E_PAR）
・mpfmbがNULLでない場合（E_NOSPT）

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

(6-8) 周期ハンドラに関する定義

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

CRE_CYC(cycid, { cycatr, exinf, cychdr, cyctim, cycphs });

(6-8-1) 周期ハンドラの初期化情報

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

	{ (cycatr), (intptr_t)(exinf), (cychdr), (cyctim), (cycphs) }

(6-8-2) エラー条件

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

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

＊パス2で検出するもの
・cycatrが（［TA_STA］）でない場合（E_RSATR）
・(0 < cyctim && cyctim <= TMAX_RELTIM)でない場合（E_PAR）
・(0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合（E_PAR）
・警告：cycatrにTA_STAが設定されていて，(cycphs == 0)の場合

＊パス3で検出するもの
・cychdrがプログラムの開始番地として正しくない場合（E_PAR）
	- ターゲット依存の値（CHECK_FUNC_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_FUNC_NONNULL）

(6-9) アラームハンドラに関する定義

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

CRE_ALM(ID almid, { almatr, (intptr_t)(exinf), almhdr });

(6-9-1) アラームハンドラの初期化情報

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

	{ (almatr), (exinf), (almhdr) }

(6-9-2) エラー条件

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

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

＊パス2で検出するもの
・almatrが（TA_NULL）でない場合（E_RSATR）

＊パス3で検出するもの
・almhdrがプログラムの開始番地として正しくない場合（E_PAR）
	- ターゲット依存の値（CHECK_FUNC_ALIGN）の倍数でない場合
	- NULLの場合（ターゲット依存，CHECK_FUNC_NONNULL）

(7) 割込みに関する定義

割込みに関して生成する情報は，ターゲット毎に定めることができる．ターゲッ
ト毎に定めない場合には，以下で述べるターゲットに依存しない標準的な情報
を生成する．ターゲット毎に定める場合には，(7-1)と(7-3)に述べる情報は生
成しない（(7-2)に述べる情報は生成する）．

(7-1) 割込み要求ラインに関する定義

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

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

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

(7-1-1) 設定する割込み要求ラインの数

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

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

(7-1-2) 割込み要求ライン初期化ブロックの定義

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

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

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

	{ (intno), (intatr), (intpri) }

(7-1-3) エラー条件

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

＊パス2で検出するもの
・intnoがCFG_INTに対する割込み番号として正しくない場合（E_PAR）
・intnoがCFG_INTによって設定済みの場合（E_OBJ）
・intatrが（［TA_ENAINT］｜［TA_EDGE］）でない場合（E_RSATR）
	※ ターゲット依存部で割込み属性を追加可（TARGET_INTATR）
・カーネル管理に固定されているintnoに対して，intpriにTMIN_INTPRIよりも
　小さい値が指定された場合（E_OBJ）
・カーネル管理外に固定されているintnoに対して，intpriにTMIN_INTPRIより
　も小さい値が指定されなかった場合（E_OBJ）
・intpriがCFG_INTに対する割込み優先度として正しくない場合（E_PAR）

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

(7-2) 割込みサービスルーチンに関する定義

(7-2-1) 割込みハンドラの生成

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

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

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

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

static void
_kernel_inthdr_<intno>(void)
{
	PRI		saved_ipm;

	i_begin_int(intno);
	saved_ipm = i_get_ipm();

	LOG_ISR_ENTER(<intno>);		/* ISR1の呼出し */
	isr_1((intptr_t)(exinf_1));
	LOG_ISR_LEAVE(intno);

	if (i_sense_lock()) {		/* ISRの呼出し前の状態に戻す */
		i_unlock_cpu();
	}
	i_set_ipm(saved_ipm);

	LOG_ISR_ENTER(<intno>);		/* ISR2の呼出し */
	isr_2((intptr_t)(exinf_2));
	LOG_ISR_LEAVE(intno);

	if (i_sense_lock()) {		/* ISRの呼出し前の状態に戻す */
		i_unlock_cpu();
	}
	i_set_ipm(saved_ipm);

	……

	LOG_ISR_ENTER(<intno>);		/* ISRnの呼出し */
	isr_n((intptr_t)(exinf_n));
	LOG_ISR_LEAVE(intno);

	i_end_int(intno);
}

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

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

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

【課題】ここで，LOG_ISR_ENTER，LOG_ISR_LEAVEの引数をどうするかが課題と
して残っている．ATT_ISRで登録されたISRに対してはISR IDが付与されないた
め，IDでISRを区別することができない．やむなく割込み番号を渡しているが，
拡張情報（exinf）も渡すべきかもしれない．

(7-2-2) 割込みハンドラの定義に相当する処理

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

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

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

(7-2-3) エラー条件

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

＊パス2で検出するもの
・isratrが（TA_NULL）でない場合（E_RSATR）
	※ ターゲット依存部で割込みサービスルーチン属性を追加可（TARGET_ISRATR）
・intnoがATT_ISRに対する割込み番号として正しくない場合（E_PAR）
	※ intnoに対応するinhnoがない場合を含む
・(TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合（E_PAR）
・intnoに対応するinhnoに対してDEF_INHがある場合（E_OBJ）
・intnoに対するCFG_INTがない場合（E_OBJ）
・intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小さい
　場合（E_OBJ）
	※ カーネル管理外のISRはサポートしないため

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

(7-3) 割込みハンドラに関する定義

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

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

DEF_INH(inhno, { inhatr, inthdr });

(7-3-1) 定義する割込みハンドラの数

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

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

(7-3-2) 割込みハンドラの出入口処理

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

INTHDR_ENTRY(inhno, inhno_num, inthdr)

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

(7-3-3) 割込みハンドラ初期化ブロックの定義

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

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

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

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

(7-3-4) エラー条件

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

＊パス2で検出するもの
・inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合（E_PAR）
・inhnoがDEF_INHによって設定済みの場合（E_OBJ）
#・inhnoに対応するintnoに対してATT_ISRがある場合（E_OBJ）
#	※ inhnoに対応するintnoがない場合には，このチェックを行わない
#	→ このチェックは，割込みサービスルーチン側で行う
・inhatrが（TA_NULL）でない場合（E_RSATR）
	※ ターゲット依存部で割込みハンドラ属性を追加可（TARGET_INHATR）
	※ TA_NONKERNELを使う場合には，TARGET_INHATRに設定する
・カーネル管理に固定されているinhnoに対して，inhatrにTA_NONKERNELが指定
　されている場合（E_RSATR）
・カーネル管理外に固定されているinhnoに対して，inhatrにTA_NONKERNELが指
　定されていない場合（E_RSATR）
・inhnoに対応するintnoに対するCFG_INTがない場合（E_OBJ）
	※ inhnoに対応するintnoがない場合には，このチェックを行わない
・inhatrにTA_NONKERNELが指定されておらず，inhnoに対応するintnoに対して
　CFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小さい場合（E_OBJ）
	※ inhnoに対応するintnoがない場合には，このチェックを行わない
・inhatrにTA_NONKERNELが指定されており，inhnoに対応するintnoに対して
　CFG_INTで設定された割込み優先度がTMIN_INTPRI以上である場合（E_OBJ）
	※ inhnoに対応するintnoがない場合には，このチェックを行わない

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

(8) CPU例外に関する定義

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

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

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

DEF_EXC(excno, { excatr, exchdr });

(8-1) 定義するCPU例外ハンドラの数

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

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

(8-2) CPU例外ハンドラの出入口処理

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

EXCHDR_ENTRY(excno, excno_num, exchdr)

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

(8-3) CPU例外ハンドラ初期化ブロックの定義

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

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

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

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

(8-4) エラー条件

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

＊パス2で検出するもの
・excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合（E_PAR）
・excnoがDEF_EXCによって設定済みの場合（E_OBJ）
・excatrが（TA_NULL）でない場合（E_RSATR）
	※ ターゲット依存部でCPU例外ハンドラ属性を追加可（TARGET_EXCATR）

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

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

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

(9-1) DEF_ICSがない場合

システムコンフィギュレーションファイルに，静的API「DEF_ICS」が含まれて
いない場合には，次の行を生成する．

#ifdef DEFAULT_ISTK

#define TOPPERS_ISTKSZ		DEFAULT_ISTKSZ
#define TOPPERS_ISTK		DEFAULT_ISTK

#else /* DEFAULT_ISTK */

static STK_T				_kernel_istack[COUNT_STK_T(DEFAULT_ISTKSZ)];
#define TOPPERS_ISTKSZ		ROUND_STK_T(DEFAULT_ISTKSZ)
#define TOPPERS_ISTK		_kernel_istack

#endif /* DEFAULT_ISTK */

(9-2) DEF_ICSがある場合

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

DEF_ICS({ istksz, istk });

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

static STK_T				_kernel_istack[COUNT_STK_T(istksz)];
#define TOPPERS_ISTKSZ		ROUND_STK_T(istksz)
#define TOPPERS_ISTK		_kernel_istack

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

#define TOPPERS_ISTKSZ		(istksz)
#define TOPPERS_ISTK		(istk)

(9-3) 変数の生成

DEF_ICSの有無によらず，次の定義を生成する．

const SIZE		_kernel_istksz = TOPPERS_ISTKSZ;
STK_T *const	_kernel_istk = TOPPERS_ISTK;

#ifdef TOPPERS_ISTKPT
STK_T *const	_kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);
#endif /* TOPPERS_ISTKPT */

(9-4) エラー条件

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

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

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

(10) タイムイベント管理に関する定義

タイムイベント管理に関連して，次の定義を生成する．

TMEVTN	_kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];

(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_mailbox();
	_kernel_initialize_mempfix();
	_kernel_initialize_cyclic();
	_kernel_initialize_alarm();
	_kernel_initialize_interrupt();
	_kernel_initialize_exception();
}

(12) 初期化ルーチンの実行関数の定義

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

ATT_INI({ iniatr, exinf, inirtn });

という静的APIに対して，

	(inirtn)((intptr_t)(exinf));

を呼び出す関数を，_kernel_call_inirtnという名前で生成する．初期化ルーチ
ンを呼び出す順序は，システムコンフィギュレーションファイル中での静的
APIの順序に一致させる．

例えば，

ATT_INI({ TA_NULL, 0, timer_initialize });
ATT_INI({ TA_NULL, CONSOLE_PORTID, serial_initialize });

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

void
_kernel_call_inirtn(void)
{
	(timer_initialize)((intptr_t)(0));
	(serial_initialize)((intptr_t)(CONSOLE_PORTID));
}

(12-1) エラー条件

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

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

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

(13) 終了処理ルーチンの実行関数の定義

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

ATT_TER({ teratr, exinf, terrtn });

という静的APIに対して，

	(terrtn)((intptr_t)(exinf));

を呼び出す関数を，_kernel_call_terrtnという名前で生成する．終了処理ルー
チンを呼び出す順序は，システムコンフィギュレーションファイル中での静的
APIの逆順に一致させる．

例えば，

ATT_TER({ TA_NULL, 0, timer_terminate });
ATT_TER({ TA_NULL, CONSOLE_PORTID, serial_terminate });

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

void
_kernel_call_terrtn(void)
{
	(serial_terminate)((intptr_t)(CONSOLE_PORTID));
	(timer_terminate)((intptr_t)(0));
}

(13-1) エラー条件

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

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

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

以上
