TOPPERS/ASP3カーネル コンフィギュレータ仕様 対応バージョン: Release 3.0.0 最終更新: 2015年8月8日 このドキュメントは,TOPPERS/ASP3カーネルのコンフィギュレータが標準的に 生成すべきファイルの内容について解説したものである.ターゲット依存に生 成する内容については,このドキュメントの範囲外である. ---------------------------------------------------------------------- TOPPERS/ASP Kernel Toyohashi Open Platform for Embedded Real-Time Systems/ Advanced Standard Profile Kernel Copyright (C) 2005-2015 by Embedded and Real-Time Systems Laboratory Graduate School of Information Science, Nagoya Univ., JAPAN 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 権表示,この利用条件および下記の無保証規定が,そのままの形でソー スコード中に含まれていること. (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 の無保証規定を掲載すること. (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 用できない形で再配布する場合には,次のいずれかの条件を満たすこ と. (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 作権表示,この利用条件および下記の無保証規定を掲載すること. (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 報告すること. (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを 免責すること. 本ソフトウェアは,無保証で提供されているものである.上記著作権者お よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ の責任を負わない. $Id: configurator.txt 431 2015-08-08 12:05:02Z ertl-hiro $ ---------------------------------------------------------------------- ○目次 1.生成するファイルの種類 2.静的API一覧 3.カーネル構成・初期化ヘッダファイル(kernel_cfg.h) 3.1 固定生成部分 3.2 オブジェクト数の定義 3.3 オブジェクトのID番号の定義 4.カーネル構成・初期化ファイル(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.6 通知ハンドラの生成 4.7 割込みに関する定義 4.7.1 割込みサービスルーチンに関する定義 4.7.2 割込みハンドラに関する定義 4.7.3 割込み要求ラインに関する定義 4.8 CPU例外に関する定義 4.9 非タスクコンテキスト用のスタック領域に関する定義 4.10 タイムイベント管理に関する定義 4.11 各モジュールの初期化関数の定義 4.12 初期化ルーチンの実行関数の定義 4.13 終了処理ルーチンの実行関数の定義 1.生成するファイルの種類 ASP3カーネルのコンフィギュレータは,システムコンフィギュレーションファ イルを処理して,カーネル構成・初期化ファイル(kernel_cfg.c)と構成・初 期化ヘッダファイル(kernel_cfg.h)を生成する.コンフィギュレータの処理 の途中に,この他にいくつかの中間ファイルを生成する. 2.静的API一覧 ASP3カーネルのコンフィギュレータが処理する静的APIは次の通り. (1) タスク管理機能 CRE_TSK(ID tskid, { ATR tskatr, intptr_t exinf, TASK task, PRI itskpri, SIZE 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 }) ※ 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 istksz, STK_T *istk }) ATT_INI({ ATR iniatr, intptr_t exinf, INIRTN inirtn }) ATT_TER({ ATR teratr, intptr_t exinf, TERRTN terrtn }) 3.カーネル構成・初期化ヘッダファイル(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_CYCID <周期ハンドラの数> #define TNUM_ALMID <アラームハンドラの数> #define TNUM_ISRID <割込みサービスルーチンの数> 3.3 オブジェクトのID番号の定義 コンフィギュレータがID番号を割り付けたオブジェクトの名前を,割り付けた ID番号にマクロ定義するプリプロセッサディレクティブ(#define)を生成する. 例えば,次のような記述を生成する. #define TASK1 1 #define TASK2 2 #define SEM1 1 4.カーネル構成・初期化ファイル(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 == 0x0007U && (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番号を保持する変数の定義 コンフィギュレータに対するオプション指定(--external-id)により,コンフィ ギュレータが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番号が連続 しない場合には(ASP3カーネルは,オブジェクトの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」とすると,次のような行を生成する. XXXCB _kernel_xxxcb_table[TNUM_XXXID]; オブジェクトが1つも生成されなかった場合には,次のような行を生成する. TOPPERS_EMPTY_LABEL(XXXCB, _kernel_xxxcb_table);$NL$ 4.5.2 タスクに関する定義 ASP3カーネルは,タスクが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)]; ただし,この方法でスタック領域が確保できないターゲットにおいては,ター ゲット依存の方法でスタック領域を確保する. 4.5.2.2 タスクの初期化情報 タスク初期化ブロック中に生成するタスクの初期化情報は,次の形式とする. *stkがNULLでない場合 { (tskatr), (intptr_t)(exinf), (TASK)(task), INT_PRIORITY(itskpri), (stksz), (void *)(stk) } *stkがNULLの場合 { (tskatr), (intptr_t)(exinf), (TASK)(task), INT_PRIORITY(itskpri), ROUND_STK_T(stksz), _kernel_stack_<タスク名> } 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でない場合にのみ行う *パス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] 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でエラーを検出する. 4.5.5 データキューに関する定義 データキューの省略記号は「DTQ/dtq」である.以下では,システムコンフィギュ レーションファイルに次の静的APIが含まれている時に生成すべき情報について 述べる. CRE_DTQ(dtqid, { dtqatr, dtqcnt, dtqmb }); 4.5.5.1 データキューに必要なメモリ領域の定義 データキューに必要なメモリ領域として,データキュー管理領域がある.生成 するデータキュー毎に,必要なサイズのデータキュー管理領域を定義する.具 体的には,上記の静的APIに対して,次の定義を生成する. *dtqcntが0でない場合のみ生成 static DTQMB _kernel_dtqmb_<データキュー名>[dtqcnt]; 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)[ASPS0132] 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]; 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)[ASPS0142] 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] 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)]; *必ず生成 static MPFMB _kernel_mpfmb_<固定長メモリプール名>[blkcnt]; 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)[ASPS0166] *パス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) } 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.13節)を参照 *パス3で検出するもの ・通知方法中のタイムイベントハンドラの先頭番地または変数の番地が正しく  ない(E_PAR)[NGKI3693] - ターゲット依存の値(CHECK_FUNC_ALIGN)の倍数でない場合 - NULLの場合(ターゲット依存,CHECK_FUNC_NONNULL) ・その他,通知ハンドラの生成に関するエラー(4.6.13節)を参照 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 } 4.5.10.3 エラー条件 アラーム通知に関するエラー条件は次の通りである. *コンフィギュレータ本体が検出するもの ・同じalmidに対するCRE_ALMが複数ある場合(E_OBJ)[NGKI2500] *パス2で検出するもの ・almatrが無効の場合(E_RSATR)[NGKI2491]  (TA_STA以外のビットがセットされている場合) ・その他,通知ハンドラの生成に関するエラー(4.6.13節)を参照 *パス3で検出するもの ・通知方法中のタイムイベントハンドラの先頭番地または変数の番地が正しく  ない(E_PAR)[NGKI3693] - ターゲット依存の値(CHECK_FUNC_ALIGN)の倍数でない場合 - NULLの場合(ターゲット依存,CHECK_FUNC_NONNULL) ・その他,通知ハンドラの生成に関するエラー(4.6.13節)を参照 4.6 通知ハンドラの生成 通知ハンドラは,周期通知機能とアラーム通知機能のためのイベントの通知お よびイベント通知時に発生したエラーの通知を行うためのハンドラである.通 知ハンドラは,カーネル実装上の概念であり,外部仕様書には登場しない(タ イムイベントハンドラと位置付けが類似しているため,混同しないように注意 すること). ASP3カーネルでは,コンフィギュレータにより,周期通知毎およびアラーム通 知毎に通知ハンドラを生成する.ただし,タイムイベントハンドラの呼出しに よる通知の場合には,通知ハンドラを生成せず,直接タイムイベントハンドラ を呼び出す. 生成する通知ハンドラの枠組みは次の通り. (a) エラーの通知を行わない場合 static void _kernel_nfyhdr_(intptr_t exinf) { (void) <イベントの通知処理>; } (b) エラーの通知を行う場合 static void _kernel_nfyhdr_(intptr_t exinf) { ER ercd; ercd = <イベントの通知処理>; if (ercd != E_OK) { (void) <エラーの通知処理>; } } <イベントの通知処理>と<エラーの通知処理>は,<通知方法の指定>の最 初のパラメータである通知処理モード(nfymode)により定まる.具体的には, nfymodeの下位4ビット(以下,これをnfymode1と書く)でイベントの通知方法 を,残りのビット(以下,これをnfymode2と書く)でエラーの通知方法を指定 する. 4.6.1 変数の設定によるイベント通知 nfymode1がTNFY_SETVER(変数の設定によるイベント通知)の場合には,続く2 つのパラメータ(変数の番地と設定する値)の指定に従って変数を設定するも のとする.コンフィギュレータのパス3でのエラーチェックを可能にするために, 変数の番地は,exinfとして通知ハンドラに渡す. 具体的には,<イベントの通知処理>には,次のコードを生成する. *((intptr_t *) exinf) = (<設定する値>); 周期/アラーム通知初期化ブロックに登録するnfyhdrとexinfは,次の通りとす る. nfyhdr _kernel_nfyhdr_ exinf <変数の番地> なお,変数の設定によるイベント通知の場合,エラーが検出されることはない ため,エラーの通知は意味がない.エラーの通知が指定されていた場合,コン フィギュレータはエラーを報告する. 4.6.2 タスクの起動によるイベント通知 nfymode1がTNFY_ACTTSK(タスクの起動によるイベント通知)の場合には,続く 1つのパラメータ(タスクID)の指定に従ってタスクを起動するものとする.コ ンフィギュレータのパス3でのエラーチェックを可能にするために,タスクIDは, exinfとして通知ハンドラに渡す. 具体的には,<イベントの通知処理>には,次のコードを生成する. act_tsk((ID) exinf); 周期/アラーム通知初期化ブロックに登録するnfyhdrとexinfは,次の通りとす る. nfyhdr _kernel_nfyhdr_ exinf <タスクID> 4.6.3 タスクの起床によるイベント通知 nfymode1がTNFY_WUPTSK(タスクの起床によるイベント通知)の場合には,続く 1つのパラメータ(タスクID)の指定に従ってタスクを起床するものとする.コ ンフィギュレータのパス3でのエラーチェックを可能にするために,タスクIDは, exinfとして通知ハンドラに渡す. 具体的には,<イベントの通知処理>には,次のコードを生成する. wup_tsk((ID) exinf); 周期/アラーム通知初期化ブロックに登録するnfyhdrとexinfは,次の通りとす る. nfyhdr _kernel_nfyhdr_ exinf <タスクID> 4.6.4 セマフォの返却によるイベント通知 nfymode1がTNFY_SIGSEM(セマフォの返却によるイベント通知)の場合には,続 く1つのパラメータ(セマフォID)の指定に従ってセマフォを返却を起動するも のとする.コンフィギュレータのパス3でのエラーチェックを可能にするために, セマフォIDは,exinfとして通知ハンドラに渡す. 具体的には,<イベントの通知処理>には,次のコードを生成する. sig_sem((ID) exinf); 周期/アラーム通知初期化ブロックに登録するnfyhdrとexinfは,次の通りとす る. nfyhdr _kernel_nfyhdr_ exinf <セマフォID> 4.6.5 イベントフラグのセットによるイベント通知 nfymode1がTNFY_SETFLG(イベントフラグのセットによるイベント通知)の場合 には,続く2つのパラメータ(イベントフラグIDとセットするビットパターン) の指定に従ってイベントフラグをセットするものとする.コンフィギュレータ のパス3でのエラーチェックを可能にするために,イベントフラグIDは,exinf として通知ハンドラに渡す. 具体的には,<イベントの通知処理>には,次のコードを生成する. set_flg((ID) exinf, <セットするビットパターン>); 周期/アラーム通知初期化ブロックに登録するnfyhdrとexinfは,次の通りとす る. nfyhdr _kernel_nfyhdr_ exinf <イベントフラグID> 4.6.6 データキューへの送信によるイベント通知 nfymode1がTNFY_SNDDTQ(データキューへの送信によるイベント通知)の場合に は,続く2つのパラメータ(データキューIDと送信する値)の指定に従ってデー タキューへ送信するものとする.コンフィギュレータのパス3でのエラーチェッ クを可能にするために,データキューIDは,exinfとして通知ハンドラに渡す. 具体的には,<イベントの通知処理>には,次のコードを生成する. snd_dtq((ID) exinf, <送信する値>); 周期/アラーム通知初期化ブロックに登録するnfyhdrとexinfは,次の通りとす る. nfyhdr _kernel_nfyhdr_ exinf <データキューID> 4.6.7 変数の設定によるエラー通知 nfymode2がTENFY_SETVER(変数の設定によるエラー通知)の場合には,続く1つ のパラメータ(変数の番地)の指定に従って,エラーコードを変数に設定する ものとする.コンフィギュレータのパス3でのエラーチェックを可能にするため に,変数の番地は,グローバル変数を通じてて通知ハンドラに渡す. 具体的には,通知ハンドラの定義に先立ち,次のコードを生成する. intptr_t *const _kernel_nfyhdr__p_evar = (intptr_t *)(<変数の番地>); また,<エラーの通知処理>には,次のコードを生成する. *((intptr_t *) _kernel_nfyhdr__p_evar) = (intptr_t) ercd; 4.6.8 タスクの起動によるエラー通知 nfymode2がTENFY_ACTTSK(タスクの起動によるエラー通知)の場合には,続く 1つのパラメータ(タスクID)の指定に従ってタスクを起動するものとする.コ ンフィギュレータのパス3でのエラーチェックを可能にするために,タスクIDは, グローバル変数を通じて通知ハンドラに渡す. 具体的には,通知ハンドラの定義に先立ち,次のコードを生成する. const ID _kernel_nfyhdr__etskid = <タスクID>; また,<エラーの通知処理>には,次のコードを生成する. act_tsk(_kernel_nfyhdr__etskid); 4.6.9 タスクの起床によるエラー通知 nfymode2がTENFY_WUPTSK(タスクの起床によるエラー通知)の場合には,続く 1つのパラメータ(タスクID)の指定に従ってタスクを起床するものとする.コ ンフィギュレータのパス3でのエラーチェックを可能にするために,タスクIDは, グローバル変数を通じて通知ハンドラに渡す. 具体的には,通知ハンドラの定義に先立ち,次のコードを生成する. const ID _kernel_nfyhdr__etskid = <タスクID>; また,<エラーの通知処理>には,次のコードを生成する. wup_tsk(_kernel_nfyhdr__ptskid); 4.6.10 セマフォの返却によるエラー通知 nfymode2がTENFY_SIGSEM(セマフォの返却によるエラー通知)の場合には,続 く1つのパラメータ(セマフォID)の指定に従ってセマフォを返却するものとす る.コンフィギュレータのパス3でのエラーチェックを可能にするために,セマ フォIDは,グローバル変数を通じて通知ハンドラに渡す. 具体的には,通知ハンドラの定義に先立ち,次のコードを生成する. const ID _kernel_nfyhdr__esemid = <セマフォID>; また,<エラーの通知処理>には,次のコードを生成する. sig_sem(_kernel_nfyhdr__esemid); 4.6.11 イベントフラグのセットによるエラー通知 nfymode2がTENFY_SETFIG(イベントフラグのセットによるエラー通知)の場合 には,続く2つのパラメータ(イベントフラグIDとセットするビットパターン) の指定に従ってイベントフラグをセットするものとする.コンフィギュレータ のパス3でのエラーチェックを可能にするために,イベントフラグIDは,グロー バル変数を通じて通知ハンドラに渡す. 具体的には,通知ハンドラの定義に先立ち,次のコードを生成する. const ID _kernel_nfyhdr__eflgid = <イベントフラグID>; また,<エラーの通知処理>には,次のコードを生成する. set_flg(_kernel_nfyhdr__eflgid, <セットするビットパターン>); 4.6.12 データキューへの送信によるエラー通知 nfymode2がTENFY_SNDDTQ(データキューへの送信によるエラー通知)の場合に は,続く1つのパラメータ(データキューID)の指定に従って,エラーコードを データキューへ送信するものとする.コンフィギュレータのパス3でのエラー チェックを可能にするために,データキューIDは,グローバル変数を通じて通 知ハンドラに渡す. 具体的には,通知ハンドラの定義に先立ち,次のコードを生成する. const ID _kernel_nfyhdr__edtqid = <データキューID>; また,<エラーの通知処理>には,次のコードを生成する. snd_dtq(_kernel_nfyhdr__edtqid, (intptr_t) ercd); 4.6.13 エラー条件 通知ハンドラの生成に関するエラー条件は次の通りである. *パス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_(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_(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_ }); ここで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] ※ カーネル管理外の割込みサービスルーチンはサポートしないため *可能であればターゲット依存部で検出するもの[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)) } 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がない場合には,このチェックを行わない *可能であればターゲット依存部で検出するもの[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) } 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] *必要に応じてターゲット依存部で検出するもの[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例外ハンドラの初期化情報は,次の形式とする. { (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例外ハンドラ属性 *可能であればターゲット依存部で検出するもの[NGKI3149] ・exchdrがプログラムの開始番地として正しくない場合(E_PAR)[NGKI3135] 4.9 非タスクコンテキスト用のスタック領域に関する定義 非タスクコンテキスト用のスタック領域に関する定義は,必ず生成しなければ ならない. 4.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 */ 4.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) 4.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 */ 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でない場合にのみ行う *パス3で検出するもの ・istkがスタック領域の先頭番地として正しくない場合(E_PAR)[NGKI3222] - ターゲット依存の値(CHECK_STACK_ALIGN)の倍数でない場合 - NULLの場合(ターゲット依存,CHECK_STACK_NONNULL) 4.10 タイムイベント管理に関する定義 タイムイベント管理に関連して,次の定義を生成する. TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID]; 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({ iniatr, exinf, inirtn }); という静的APIに対して, ((INIRTN)(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) { ((INIRTN)(timer_initialize))((intptr_t)(0)); ((INIRTN)(serial_initialize))((intptr_t)(CONSOLE_PORTID)); } 4.12.1 エラー条件 初期化ルーチンに関するエラー条件は次の通りである. *パス2で検出するもの ・iniatrが無効の場合(E_RSATR)[NGKI3241]  (TA_NULLでない場合) *可能であればターゲット依存部で検出するもの[NGKI3246] ・inirtnがプログラムの開始番地として正しくない場合(E_PAR)[NGKI3243] 4.13 終了処理ルーチンの実行関数の定義 システムコンフィギュレーションファイル中に含まれる終了処理ルーチンを追 加する静的API「ATT_TER」に対して,追加した終了処理ルーチンを順に呼び出 す関数を生成する.具体的には, ATT_TER({ teratr, exinf, terrtn }); という静的APIに対して, ((TERRTN)(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) { ((TERRTN)(serial_terminate))((intptr_t)(CONSOLE_PORTID)); ((TERRTN)(timer_terminate))((intptr_t)(0)); } 4.13.1 エラー条件 終了処理ルーチンに関するエラー条件は次の通りである. *パス2で検出するもの ・teratrが無効の場合(E_RSATR)[NGKI3248]  (TA_NULLでない場合) *可能であればターゲット依存部で検出するもの[NGKI3253] ・terrtnがプログラムの開始番地として正しくない場合(E_PAR)[NGKI3250] 以上