カーネル起動パラメータの設定
アプリケーションが使用するタスクやセマフォなどのカーネル資源の数や属性などを
設定ファイル (kernel_cfg.c
及び kernel_cfg.h
) に記述します。
静的資源の定義に加え、動的生成APIを利用する場合の各資源タイプの最大資源数もここで記述します。
設定ファイルの編集 (ASP3)
SOLID-IDEを使用してアプリケーションの新規作成を行うとアプリケーションのスケルトンコードの他に以下の二つのファイルがアプリケーションと同じフォルダに生成されます。以下のファイルを編集し、ビルドすることでカーネル資源の設定を行います。
kernel_cfg.c
カーネルが起動時に生成する各資源の数や属性等のパラメータを記述したテーブルを定義します。ビルド時にアプリケーションと同時にビルドされ、カーネルとリンクされます。
kernel_cfg.h
静的生成される各資源のID (数値) をC言語の定数 (
enum
列挙子) として定義し、アプリケーションコードから資源を参照するための名前を対応付けます。カーネル内部では各資源のIDしか扱わないので、定数の定義は必須ではありません。kernel_cfg.c
からincludeされるので、IDの他にアプリケーションとkernel_cfg.c
との間で共有する定義を記述する目的にも使えます。
注釈
タスクやセマフォなどのIDで管理される資源のうち、静的に生成されるものについては kernel_cfg.c
で定義した初期化ブロック内の順序でIDが割り当てられます。(最初の要素が ID 1
となり、残りは順番にIDが割り振られます。)
警告
ネットワーク機能を利用する場合、kernel_cfg.c
の中にある下記の定義を削除しないでください。
__SOLID_RESERVED_TASKS__
__SOLID_RESERVED_TASK_ORDER__
__SOLID_RESERVED_SEMS__
__SOLID_RESERVED_DTQS__
__SOLID_SYS_INTRTN
__SOLID_SYS_TERRTN
ネットワークを利用する場合の設定にてついてはネットワークの項の カーネル資源設定について も参照してください。
タスク初期化ブロック
-
typedef struct task_initialization_block TINIB
-
struct task_initialization_block
説明
タスク生成時の初期化情報を設定します。
定義
typedef struct task_initialization_block { ATR tskatr; intptr_t exinf; TASK task; uint_t ipriority; size_t stksz; void *stk; } TINIB; const TINIB _kernel_tinib_table[];
メンバー
-
ATR tskatr
タスク属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_ACT
タスクの生成時にタスクを起動する
TA_NOACTQUE
タスクに対する起動要求をキューイングしない
TA_RSTR
生成するタスクを制約タスクとする
-
intptr_t exinf
タスクの拡張情報
タスクが起動されるときの引数を指定します。(任意)
-
TASK task
タスクの起動番地
タスクの起動番地をC言語の関数アドレスで指定します。 関数型は以下の通りです。
typedef void (*TASK)(intptr_t exinf);
-
uint_t ipriority
タスクの起動時優先度(内部表現)
カーネル内部表現で指定する必要があるため、マクロ
INT_PRIORITY
を使用してください。INT_PRIORITY(1)
が最高優先度、INT_PRIORITY(16)
(優先度拡張なし) またはINT_PRIORITY(256)
(優先度拡張あり) が最低優先度です。
-
size_t stksz
スタック領域のサイズ(丸めた値)
-
void *stk
スタック領域の先頭番地
注釈
このテーブル内に記述された順序に沿ってタスクIDが
1
(TMIN_TSKID
) から割り振られます。stk
がNULLの場合、カーネルは自動的にstksz
で指定された領域を確保してタスクに割り当てます。ユーザが確保した領域(変数)をスタックとして使用したい場合にはその領域のアドレスをstk
に指定しますがその場合は以下の点に注意してくださいコード例
#define STACK_SIZE 2048 extern void task1(void *); extern void task2(void *); static STK_T _stack_TASK1[COUNT_STK_T(STACK_SIZE)]; const TINIB _kernel_tinib_table[] = { // 生成時に起動(TA_ACT), スタック領域のアドレスを指定 (スタックフェンス機能 無効) { TA_ACT, 0, task1, INT_PRIORITY(MID_PRIORITY), ROUND_STK_T(STACK_SIZE), _stack_TASK1 }, // 生成時には起動しない, スタックをカーネル内で確保(スタックフェンス機能 有効) { TA_NULL, 0, task2, INT_PRIORITY(HIGH_PRIORITY), ROUND_STK_T(STACK_SIZE), NULL}, }; };
-
ATR tskatr
タスク生成順序テーブル
-
const ID _kernel_torder_table[]
説明
タスク生成の順序を設定します。
定義
const ID _kernel_torder_table[];
注釈
タスクを生成する順序をIDで指定します。指定する数はタスク初期化ブロックに記述された数と必ず一致する必要があります。 一致しない場合のカーネルの動作は保証されません。 このテーブルでの指定の順序に関わらず各タスクのIDはタスク初期化テーブルでの並びで決まります。
コード例
/* * タスクIDの定数定義 */ #define TASK1 1 #define TASK2 2 #define TASK3 3 const ID _kernel_torder_table[] = { TASK3, TASK1, TASK2 };
この例の場合、
TASK3
→TASK1
→TASK2
の順序でタスク生成処理が行われます。
セマフォ初期化ブロック
-
typedef struct semaphore_initialization_block SEMINIB
-
struct semaphore_initialization_block
説明
使用するセマフォの属性を定義します。
定義
typedef struct semaphore_initialization_block { ATR sematr; // セマフォ属性 uint_t isemcnt; // セマフォの資源数の初期値 uint_t maxsem; // セマフォの最大資源数 } SEMINIB; const SEMINIB _kernel_seminib_table[];
メンバー
-
ATR sematr
セマフォ属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
-
uint_t isemcnt
セマフォの資源数の初期値
-
uint_t maxsem
セマフォの最大資源数
コード例
const SEMINIB _kernel_seminib_table[] = { { TA_NULL, 1, 1 }, // 待ち行列=FIFO順, 最大数=1, 初期値=1でセマフォを生成 { TA_TPRI, 0, 1 }, // 待ち行列=タスク優先度順, 最大数=1, 初期値=0でセマフォを生成 };
-
ATR sematr
イベントフラグ初期化ブロック
-
typedef struct eventflag_initialization_block FLGINIB
-
struct eventflag_initialization_block
説明
使用するイベントフラグの属性を定義します。
定義
typedef struct eventflag_initialization_block { ATR flgatr; // イベントフラグ属性 FLGPTN iflgptn; // イベントフラグのビットパターンの初期値 } FLGINIB; const FLGINIB _kernel_flginib_table[];
メンバー
-
ATR flgatr
イベントフラグ属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_WMUL
複数のタスクが待つのを許す
TA_CLR
タスクの待ち解除時にイベントフラグの全てのビットをクリアする
TA_BITCLR
タスクの待ち解除時にイベントフラグの待ち対象ビットのみをクリアする
-
FLGPTN iflgptn
イベントフラグのビットパターンの初期値
注釈
TA_CLR
/TA_BITCLR
によるビットクリア動作についてはTOPPERSリリースとの相違点の項の イベントフラグ待ち解除時のクリア方法指定 を参照してください。コード例
const FLGINIB _kernel_flginib_table[] = { { TA_NULL, 0x00 }, // 複数タスク待ち不可, 待ち行列=FIFO順, フラグ初期値=0 { TA_CLR, 0x01 }, // 複数タスク待ち不可, 待ち行列=FIFO順, 待ち解除時にフラグクリア, フラグ初期値=1 { TA_WMUL|TA_CLR, 0x00 }, // 複数タスク待ち許可, 待ち行列=FIFO順, 待ち解除時にフラグクリア, フラグ初期値=0 { TA_WMUL|TA_TPRI, 0x00 }, // 複数タスク待ち許可, 待ち行列=タスク優先度順, フラグ初期値=0 };
-
ATR flgatr
データキュー初期化ブロック
-
typedef struct dataqueue_initialization_block DTQINIB
-
struct dataqueue_initialization_block
説明
使用するデータキューの属性を定義します。
定義
typedef struct dataqueue_initialization_block { ATR dtqatr; // データキュー属性 uint_t dtqcnt; // データキューの容量 DTQMB *p_dtqmb; // データキュー管理領域の先頭番地 } DTQINIB; const DTQINIB _kernel_dtqinib_table[];
メンバー
-
ATR dtqatr
データキュー属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
送信 待ち行列をタスクの優先度順にする (受信待ち行列は常にFIFO順)
-
uint_t dtqcnt
データキューの容量
-
DTQMB *p_dtqmb
データキュー管理領域の先頭番地
注釈
p_dtqmb
がNULLの場合、カーネルは自動的にdtqcnt
で指定された容量に対して必要な管理領域を確保してデータキューに割り当てます。 ユーザが確保した領域をデータキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、p_dtqmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
-
TSZ_DTQMB(dtqcnt)
dtqcntで指定した数のデータを格納できるデータキュー管理領域のサイズ(バイト数)
コード例
static MB_T _kernel_dtqmb_DTQ3[TCNT_DTQMB(2)]; const DTQINIB _kernel_dtqinib_table[] = { { TA_NULL, 2, NULL }, // 送信待ち行列=FIFO順, 容量=2 { TA_NULL, 0, NULL }, // 送信待ち行列=FIFO順, 容量=0 { TA_TPRI, 2, _kernel_dtqmb_DTQ3 }, // 送信待ち行列=タスク優先度順, 容量=2, 管理領域を指定 };
-
ATR dtqatr
優先度データキュー初期化ブロック
-
typedef struct pridataq_initialization_block PDQINIB
-
struct pridataq_initialization_block
説明
使用する優先度データキューの属性を定義します。
定義
typedef struct pridataq_initialization_block { ATR pdqatr; // 優先度データキュー属性 uint_t pdqcnt; // 優先度データキューの容量 PRI maxdpri; // データ優先度の最大値 PDQMB *p_pdqmb; // 優先度データキュー管理領域の先頭番地 } PDQINIB; const PDQINIB _kernel_pdqinib_table[];
メンバー
-
ATR pdqatr
優先度データキュー属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
送信 待ち行列をタスクの優先度順にする (受信待ち行列は常にFIFO順)
-
uint_t pdqcnt
優先度データキューの容量
-
PRI maxdpri
データ優先度の最大値
TMIN_DPRI
(1, 最高優先度) からTMAX_DPRI
(16) の範囲で指定可能です
-
PDQMB *p_pdqmb
優先度データキュー管理領域の先頭番地
注釈
TA_TPRI
を指定した場合のデータ優先度とタスク優先度の関係、動作についてはTOPPERS第3世代カーネル(ITRON系)統合仕様書の4.4.4 優先度データキューの「使用上の注意」を参照してください。p_pdqmb
がNULLの場合、カーネルは自動的にpdqcnt
で指定された容量に対して必要な管理領域を確保して優先度データキューに割り当てます。 ユーザが確保した領域を優先度データキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、p_pdqmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
コード例
static MB_T _kernel_pdqmb_PDQ3[TCNT_PDQMB(2)]; const PDQINIB _kernel_pdqinib_table[] = { { TA_NULL, 2, TMAX_DPRI, NULL }, // 送信待ち行列=FIFO順, データ優先度=最大(最低) { TA_NULL, 0, 8, NULL }, // 送信待ち行列=FIFO順、容量=0 { TA_TPRI, 2, TMAX_DPRI, _kernel_pdqmb_PDQ3 }, // 送信待ち行列=タスク優先度順, 管理領域を指定 };
-
ATR pdqatr
ミューテックス初期化ブロック
-
typedef struct mutex_initialization_block MTXINIB
-
struct mutex_initialization_block
説明
使用するミューテックスの属性を定義します。
定義
typedef struct mutex_initialization_block { ATR mtxatr; // ミューテックス属性 uint_t ceilpri; // ミューテックスの上限優先度(内部表現) } MTXINIB; const MTXINIB _kernel_mtxinib_table[];
メンバー
-
ATR mtxatr
ミューテックス属性
以下の属性を指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_CEILING
優先度上限ミューテックスとする。待ち行列をタスクの優先度順にする
TA_INHERIT
優先度継承ミューテックス (SOLID-OS拡張) とする。待ち行列をタスクの優先度順にする
-
uint_t ceilpri
ミューテックスの上限優先度(内部表現)
カーネル内部表現で指定する必要があるため、マクロ
INT_PRIORITY
を使用してください。INT_PRIORITY(1)
が最高優先度、INT_PRIORITY(16)
(優先度拡張なし) またはINT_PRIORITY(256)
(優先度拡張あり) が最低優先度です。TA_CEILING
が指定された場合のみ有効です。
注釈
優先度上限ミューテックスの動作についてはTOPPERS第3世代カーネル(ITRON系)統合仕様書の4.4.5 ミューテックスの「使用上の注意」を参照してください。
コード例
const MTXINIB _kernel_mtxinib_table[] = { { TA_NULL, INT_PRIORITY(1) }, //待ち行列=FIFO順 (優先度は無効) { TA_CEILING, INT_PRIORITY(9) }, //優先度上限ミューテックス, 上限優先度有効 { TA_TPRI, INT_PRIORITY(1) }, //待ち行列=タスク優先度順、優先度上限なし };
-
ATR mtxatr
メッセージバッファ初期化ブロック
-
typedef struct messagebuf_initialization_block MBFINIB
-
struct messagebuf_initialization_block
説明
使用するメッセージバッファの属性を定義します。
定義
typedef struct messagebuf_initialization_block { ATR mbfatr; // メッセージバッファ属性 uint_t maxmsz; // メッセージの最大長(バイト数) size_t mbfsz; // メッセージバッファ管理領域のサイズ(バイト数) void *mbfmb; // メッセージバッファ管理領域の先頭番地 } MBFINIB; const MBFINIB _kernel_mbfinib_table[];
メンバー
-
ATR mbfatr
メッセージバッファ属性
メッセージバッファで指定可能な属性はないため、
TA_NULL
をセットします。
-
uint_t maxmsz
メッセージの最大長
メッセージ最大長をバイト数で指定します
-
size_t mbfsz
メッセージバッファ管理領域のサイズ
メッセージバッファ管理領域のサイズをバイト数で指定します
-
void *mbfmb
メッセージバッファ管理領域の先頭番地
注釈
mbfmb
がNULLの場合、カーネルは自動的にmbfsz
で指定された容量に対して必要な管理領域を確保してデータキューに割り当てます。 ユーザが確保した領域をデータキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、mbfmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
-
TSZ_MBFMB(msgcnt, msgsz)
msgszで指定したサイズのメッセージを,msgcntで指定した数だけ格納できるメッセージバッファ管理領域のサイズ(バイト数)
-
TCNT_MBFMB(msgcnt, msgsz)
msgszで指定したサイズのメッセージを,msgcntで指定した数だけ格納できるメッセージバッファ管理領域を確保するために必要なMB_T型の配列の要素数
コード例
#define MBF3_MSGSZ 50 #define MBF3_MSGCNT 100 static MB_T _kernel_mbfmb_MBF3[TCNT_MBFMB(MBF3_MSGCNT, MBF3_MSGSZ)]; const MBFINIB _kernel_mbfinib_table[] = { // 最大メッセージサイズ=16, 管理領域 =32バイト { TA_NULL, 16, 32, NULL }, // 最大メッセージサイズ=8, 管理領域=maxmsz * 16個分 { TA_NULL, 8, TSZ_MBFMB(16, 8), NULL }, // 最大メッセージサイズ=50, 管理領域=maxmsz * 100個分 { TA_NULL, MBF3_MSGSZ, TSZ_MBFMB(MBF3_MSGCNT, MBF3_MSGSZ), _kernel_mbfmb_MBF3 }, };
-
ATR mbfatr
固定長メモリプール初期化ブロック
-
typedef struct fixed_memorypool_initialization_block MPFINIB
-
struct fixed_memorypool_initialization_block
説明
使用する固定長メモリプール初期化ブロックの属性を定義します。
定義
typedef struct fixed_memorypool_initialization_block { ATR mpfatr; // 固定長メモリプール属性 uint_t blkcnt; // メモリブロック数 uint_t blksz; // メモリブロックのサイズ(丸めた値) void *mpf; // 固定長メモリプール領域の先頭番地 MPFMB *p_mpfmb; // 固定長メモリプール管理領域の先頭番地 } MPFINIB; const MPFINIB _kernel_mpfinib_table[];
メンバー
-
ATR mpfatr
固定長メモリプール属性
TA_TPRI
待ち行列をタスクの優先度順にする
-
uint_t blkcnt
メモリブロック数
-
uint_t blksz
メモリブロックのサイズ(丸めた値)
-
void *mpf
固定長メモリプール領域の先頭番地
-
MPFMB *p_mpfmb
固定長メモリプール管理領域の先頭番地
注釈
mpf
及びp_mpfmb
にNULLを指定した場合はカーネル内部で必要なメモリ領域の確保が行われます。固定長メモリプール領域、固定長メモリプール管理領域として使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるためそれぞれ以下のマクロを使用して宣言してください。
コード例
#define MPF_BLOCK_SIZE 64 #define NUM_BLOCKS_MPF1 1 #define NUM_BLOCKS_MPF2 2 #define NUM_BLOCKS_MPF3 1 #define NUM_BLOCKS_MPF4 1 static MPF_T _pool1[ NUM_BLOCKS_MPF1 * COUNT_MPF_T(MPF_BLOCK_SIZE) ]; static MPF_T _pool4[ NUM_BLOCKS_MPF2 * COUNT_MPF_T(MPF_BLOCK_SIZE) ]; static MB_T _mpfmb2[TCNT_MPFMB(NUM_BLOCKS_MPF2)]; static MB_T _mpfmb4[TCNT_MPFMB(NUM_BLOCKS_MPF4)]; const MPFINIB _kernel_mpfinib_table[] = { { TA_NULL, NUM_BLOCKS_MPF1, ROUND_MPF_T(MPF_BLOCK_SIZE), _pool1, NULL }, // データ領域を静的変数で確保 { TA_NULL, NUM_BLOCKS_MPF2, ROUND_MPF_T(MPF_BLOCK_SIZE), NULL, (MPFMB*)_mpfmb2 }, // 管理領域を静的変数で確保 { TA_TPRI, NUM_BLOCKS_MPF3, ROUND_MPF_T(1), NULL, NULL }, // 待ち行列=タスク優先度順 { TA_NULL, NUM_BLOCKS_MPF4, ROUND_MPF_T(MPF_BLOCK_SIZE), _pool4, (MPFMB*)_mpfmb4 }, // すべての領域を静的変数で確保 };
-
ATR mpfatr
周期通知初期化ブロック
-
typedef struct cyclic_handler_initialization_block CYCINIB
-
struct cyclic_handler_initialization_block
説明
使用する周期通知の属性と処理を定義します。
定義
typedef struct cyclic_handler_initialization_block { ATR cycatr; // 周期通知属性 intptr_t exinf; // 通知ハンドラの拡張情報 NFYHDR nfyhdr; // 通知ハンドラの起動番地 RELTIM cyctim; // 周期通知の起動周期 RELTIM cycphs; // 周期通知の起動位相 } CYCINIB; const CYCINIB _kernel_cycinib_table[];
メンバー
-
ATR cycatr
周期通知属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_STA
周期通知の生成時に周期通知を動作開始する
-
intptr_t exinf
通知ハンドラの拡張情報
通知ハンドラが起動されるときの引数を指定します。(任意)
-
NFYHDR nfyhdr
通知ハンドラの起動番地
通知ハンドラの起動番地をC言語の関数アドレスで指定します。 関数型は以下の通りです。
typedef void (*NFYHDR)(intptr_t exinf);
-
RELTIM cyctim
周期通知の起動周期(単位:μsec)
-
RELTIM cycphs
周期通知の起動位相(単位:μsec)
コード例
#define CYC1_CYCLE 100U // 100μsec extern void cyc_func(intptr_t exinf); const CYCINIB _kernel_cycinib_table[] = { { TA_STA, 0, cyc_func, CYC1_CYCLE, CYC1_CYCLE }, // 生成と同時に100μsec間隔でcyc_funcを呼び出す };
-
ATR cycatr
アラーム通知初期化ブロック
-
typedef struct alarm_handler_initialization_block ALMINIB
-
struct alarm_handler_initialization_block
説明
使用するアラーム通知の属性と処理を定義します。
定義
typedef struct alarm_handler_initialization_block { ATR almatr; // アラーム通知属性 T_NFYINFO nfyinfo; //通知パラメータ構造体 } ALMINIB; const ALMINIB _kernel_alminib_table[];
メンバー
-
ATR almatr
アラーム通知属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
T_NFYINFO nfyinfo
通知パラメータ構造体
アラーム通知が発生した場合の通知方法やエラーが起きた場合の処理方法を構造体に設定します。 詳細については 通知パラメータ構造体の設定方法 を参照してください。
コード例
(通知パラメータ構造体の設定方法 を参照してください。)
-
ATR almatr
通知パラメータ構造体の設定方法
-
struct T_NFYINFO
説明
アラーム通知などにおいてカーネルからの通知方法を定義・指定します。
定義
typedef struct { MODE nfymode; // 通知処理モード union { // タイムイベントの通知に関する付随情報 T_NFY_COMMON initializer; T_NFY_HDR handler; T_NFY_VAR setvar; T_NFY_IVAR incvar; T_NFY_TSK acttsk; T_NFY_TSK wuptsk; T_NFY_SEM sigsem; T_NFY_FLG setflg; T_NFY_DTQ snddtq; } nfy; union { // エラーの通知に関する付随情報 T_NFY_COMMON initializer; T_ENFY_VAR setvar; T_NFY_IVAR incvar; T_NFY_TSK acttsk; T_NFY_TSK wuptsk; T_NFY_SEM sigsem; T_NFY_FLG setflg; T_ENFY_DTQ snddtq; } enfy; } T_NFYINFO;
メンバー
-
MODE nfymode
通知処理モード
以下の通知種類をエラー通知方法を論理和(or)で指定します。
通知の種類
TNFY_HANDLER
タイムイベントハンドラの呼出しによる通知
TNFY_SETVAR
変数の設定による通知
TNFY_INCVAR
変数のインクリメントによる通知
TNFY_ACTTSK
タスクの起動による通知
TNFY_WUPTSK
タスクの起床による通知
TNFY_SIGSEM
セマフォの返却による通知
TNFY_SETFLG
イベントフラグのセットによる通知
TNFY_SNDDTQ
データキューへの送信による通知
エラー通知の種類
TENFY_SETVAR
変数の設定による通知
TENFY_INCVAR
変数のインクリメントによる通知
TENFY_ACTTSK
タスクの起動による通知
TENFY_WUPTSK
タスクの起床による通知
TENFY_SIGSEM
セマフォの返却による通知
TENFY_SETFLG
イベントフラグのセットによる通知
TENFY_SNDDTQ
データキューへの送信による通知
エラー通知が必要無い場合には上記定数を指定する必要はありません。
-
union nfy
タイムイベントの通知に関する付随情報
nfymode
に指定した通知の種類に応じて通知に付随するパラメータを指定します。 本メンバーの設定には以下のマクロを使用してください。nfymode
マクロ名
TNFY_HANDLER
NFY_PARAM_HANDLER
TNFY_SETVAR
NFY_PARAM_SETVAR
TNFY_INCVAR
NFY_PARAM_INCVAR
TNFY_ACTTSK
NFY_PARAM_ACT_TSK
TNFY_WUPTSK
NFY_PARAM_WUP_TSK
TNFY_SIGSEM
NFY_PARAM_SIG_SEM
TNFY_SETFLG
NFY_PARAM_SET_FLG
TNFY_SNDDTQ
NFY_PARAM_SND_DTQ
各マクロのパラメータは以下の通りです。
-
NFY_PARAM_HANDLER(exinf, handler)
- パラメータ:
exinf (intptr_t) -- ハンドラ関数に渡されるパラメータ
handler (TMEHDR) -- ハンドラ関数アドレス (void (*)(intptr_t))
-
NFY_PARAM_SETVAR(p_var, value)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
value (intptr_t) -- 変数に設定するアドレス
-
NFY_PARAM_INCVAR(p_var)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
-
NFY_PARAM_ACT_TSK(tskid)
- パラメータ:
tskid (ID) -- 起動するタスクID
-
NFY_PARAM_WUP_TSK(tskid)
- パラメータ:
tskid (ID) -- 起床させるタスクID
-
NFY_PARAM_SIG_SEM(semid)
- パラメータ:
semid (ID) -- セマフォID
-
NFY_PARAM_SET_FLG(flgid, flgptn)
- パラメータ:
flgid (ID) -- イベントフラグID
flgptn (FLGPTN) -- セットするビットパターン
-
NFY_PARAM_SND_DTQ(dtqid, data)
- パラメータ:
dtqid (ID) -- データキューID
-
NFY_PARAM_HANDLER(exinf, handler)
-
union enfy
エラーの通知に関する付随情報
nfymode
に指定した通知の種類に応じて通知に付随するパラメータを指定します。 本メンバーの設定には以下のマクロを使用してください。nfymode
マクロ名
TENFY_SETVAR
ERRNFY_PARAM_SETVAR
TENFY_INCVAR
ERRNFY_PARAM_INCVAR
TENFY_ACTTSK
ERRNFY_PARAM_ACT_TSK
TENFY_WUPTSK
ERRNFY_PARAM_WUP_TSK
TENFY_SIGSEM
ERRNFY_PARAM_SIG_SEM
TENFY_SETFLG
ERRNFY_PARAM_SET_FLG
TENFY_SNDDTQ
ERRNFY_PARAM_SND_DTQ
各マクロのパラメータは以下の通りです。
-
ERRNFY_PARAM_SETVAR(p_var)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
value (intptr_t) -- 変数に設定するアドレス
-
ERRNFY_PARAM_INCVAR(p_var)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
-
ERRNFY_PARAM_ACT_TSK(tskid)
- パラメータ:
tskid (ID) -- 起動するタスクID
-
ERRNFY_PARAM_WUP_TSK(tskid)
- パラメータ:
tskid (ID) -- 起床させるタスクID
-
ERRNFY_PARAM_SIG_SEM(semid)
- パラメータ:
semid (ID) -- セマフォID
-
ERRNFY_PARAM_SET_FLG(flgid, flgptn)
- パラメータ:
flgid (ID) -- イベントフラグID
flgptn (FLGPTN) -- セットするビットパターン
-
ERRNFY_PARAM_SND_DTQ(dtqid)
- パラメータ:
dtqid (ID) -- データキューID
-
ERRNFY_PARAM_SETVAR(p_var)
コード例
#define TASK1 1 #define TASK2 2 #define SEM1 1 #define FLG1 1 #define DTQ1 1 extern bool_t event_variable; extern int_t count_variable; extern ER error_variable; const ALMINIB _kernel_alminib_table[] = { // 通知時に変数event_variableにtrueを設定、エラー通知なし { TA_NULL, { TNFY_SETVAR, {NFY_PARAM_SETVAR(&event_variable, true)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー通知なし { TA_NULL, { TNFY_ACTTSK, {NFY_PARAM_ACT_TSK(TASK2)} }}, // 通知時にタスク(ID=TASK2)を起床、エラー通知発生時には変数error_variableにエラーを格納する { TA_NULL, { TNFY_WUPTSK|TENFY_SETVAR, {NFY_PARAM_WUP_TSK(TASK2)}, {ERRNFY_PARAM_SETVAR(&error_variable)} }}, // 通知時にセマフォに返却(sig_sem)、エラー通知発生時にはタスク(ID=TASK2)を起床 { TA_NULL, { TNFY_SIGSEM|TENFY_ACTTSK, {NFY_PARAM_SIG_SEM(SEM1)}, {ERRNFY_PARAM_ACT_TSK(TASK2)} }}, // 通知時にイベントフラグをセット(ID FLG1に対し 0x01) { TA_NULL, { TNFY_SETFLG, {NFY_PARAM_SET_FLG(FLG1, 0x01)} }}, // 通知時にデータキューに対しデータ(0x01)を送信、エラーが発生した場合はTASK2を起床させる { TA_NULL, { TNFY_SNDDTQ|TENFY_WUPTSK, {NFY_PARAM_SND_DTQ(DTQ1, 0x01)}, {ERRNFY_PARAM_WUP_TSK(TASK2)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時にはSEM1に対しsig_semを実行する { TA_NULL, { TNFY_ACTTSK|TENFY_SIGSEM, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_SIG_SEM(SEM1)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時にはイベントフラグ FLG1に対し0x02をセット { TA_NULL, { TNFY_ACTTSK|TENFY_SETFLG, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_SET_FLG(FLG1, 0x02)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時にはデータキューに対しエラーコードを送信 { TA_NULL, { TNFY_ACTTSK|TENFY_SNDDTQ, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_SND_DTQ(DTQ1)} }}, // 通知時に変数count_variableをインクリメント、エラー通知なし { TA_NULL, { TNFY_INCVAR, {NFY_PARAM_INCVAR(&count_variable)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時には通知時に変数count_variableをインクリメント { TA_NULL, { TNFY_ACTTSK|TENFY_INCVAR, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_INCVAR(&count_variable)} }}, };
-
MODE nfymode
割込み初期化設定ブロック
-
typedef struct interrupt_handler_initialization_block INTINIB
-
struct interrupt_handler_initialization_block
説明
カーネルで扱う割込みについて定義します。 カーネルは起動時にこのテーブルに記述された内容を読込み、Core Serviceに対して必要な設定を行います。 このテーブルに定義されていない割込みはカーネル管理外となり、アプリケーションから扱う事はできなくなります。
割込みの処理を行う関数を登録する方法には以下の二種類があります。
- 割込みサービスルーチン(ISR)
カーネル内部のハンドラを経由します。同一の割込みに対して複数のISRを登録することができ、割込み発生時には設定されて優先度に従ってすべてのISRが呼び出されます。
動的生成機能拡張カーネルの場合は
acre_isr()
の呼び出しによりISRを登録することもできます。 (その場合でも割込み初期化設定ブロックであらかじめ使用する割込みについて定義しておく必要はあります)- 割込みハンドラ
割込み初期化設定ブロックに登録された関数のみが呼び出されます。 カーネルの動的生成機能拡張対応の有無に関わらず動的に登録することはできません。
同一の割込みに対して割込みサービスルーチンと割込みハンドラの両方を同時に使用することはできません。
定義
typedef struct interrupt_handler_initialization_block { INTNO intno; // 割込み番号 ATR inhatr; // 割込みハンドラ属性 FP inthdr; // 割込みハンドラの出入口処理の番地 (ISR使用時はINTINI_USE_ISRを指定)->関数型 :void (foo)(void); ATR intatr; // 割込み属性 (TA_ENAINT, TA_EDGEのみサポート) PRI intpri; // 割込み優先度 [-1:最低優先度 ... -31:最高優先度] } INTINIB; const INTINIB _kernel_intinib_table[];
メンバー
-
INTNO intno
割込み番号
SOLID-OSにおいては割込み番号はBSPにおけるIRQ番号に一致します。
-
ATR inhatr
割込みハンドラ属性
指定可能な属性はありません。常に
TA_NULL
をセットしてください。
-
FP inthdr
割込みハンドラの出入口処理の番地
- 割込みサービスルーチン(ISR)を使用する場合
マクロ
INTINI_USE_ISR
を指定します。- 割込みハンドラを使用する場合
ハンドラ関数のアドレスを指定します。関数型は以下の通りです。
void interrupt_handler(void);
注釈
割込みサービスルーチンと割込みハンドラでは関数型が異なります。
-
ATR intatr
割込み属性
以下の属性を論理和で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_ENAINT
割込み要求禁止フラグをクリア
TA_EDGE
エッジトリガ
TA_EDGE
を指定しない場合(bit1が0)はレベルトリガ設定として扱われます。
-
PRI intpri
割込み優先度
-1 (
TMAX_INTPRI
, 最低優先度) から-31 (TNIN_INTPRI
, 最高優先度)の範囲で優先度を指定します。 ここで指定された値はCore Serviceを介して割込みコントローラの優先度に反映されます。 割込み優先度はTIPM_ENALL
(0) を含めた32段階固定となっており、TMAX_INTPRI
(-1) が割込みコントローラのサポートする最も低い優先度に 一致する様に定義されます。(以降、TOPPERS優先度が-1するごとに優先度が高くなります)割込みコントローラがサポートする割り込み優先度レベル数が32に満たない場合に
intpri
でコントローラの上限を超える優先度を指定した場合には カーネル内部でコントローラがサポートする最高優先度に置き換えて 割込みハンドラの登録を行います。(エラーとはなりません)
注釈
使用する割込み番号が重複した場合は先着優先(先に記述された定義が優先)となり無視されます。また、タイマ割込みなどカーネルやCore Serviceで使用する割込みを指定した場合も同様です。予約されている割込みはボード毎に異なりますので 予約されている割込み で確認してください。
動的生成機能拡張カーネルを使用して
acre_isr()
を利用する場合でも割込み初期化設定ブロックにおいて対象となる割込み番号が割込みサービスルーチンを使用するための設定で登録されている必要があります。コード例
(割込みサービスルーチン(ISR)初期化ブロック を参照してください。)
割込みサービスルーチン(ISR)初期化ブロック
-
struct t_cisr
説明
割込みサービスルーチンの登録を行います。 使用する割込みについては割込み初期化設定ブロックにおいて割込みサービスルーチンを使用するための設定で登録されている必要があります。
定義
typedef struct t_cisr { ATR isratr; // 割込みサービスルーチン属性 intptr_t exinf; // 割込みサービスルーチンの拡張情報 INTNO intno; // 割込みサービスルーチンを登録する割込み番号 ISR isr; // 割込みサービスルーチンの先頭番地->関数型:void (foo)(intptr_t); PRI isrpri; // 割込みサービスルーチン優先度 [1:最高優先度 ... 16:最低優先度] } T_CISR; const T_CISR _kernel_isrini_cfg_table[];
メンバー
-
ATR isratr
割込みサービスルーチン属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
intptr_t exinf
割込みサービスルーチンの拡張情報
割込み発生時にisrで指定された関数に引数として渡される値を指定します。
-
INTNO intno
割込みサービスルーチンを登録する割込み番号
割込み初期化設定ブロックで登録した割込み番号を設定します。該当する割込みについて割込み初期化設定ブロックのメンバ
inthdr
にINTINI_USE_ISR
が指定されている必要があります。
-
ISR isr
割込みサービスルーチンの先頭番地
typedef void (*ISR)(intptr_t exinf);
注釈
割込みサービスルーチンと割込みハンドラでは関数型が異なります。
-
PRI isrpri
割込みサービスルーチン優先度
1(最高優先度)から16(最低優先度)の範囲で優先度を指定します。 ここで指定された値はカーネル内で割込みサービスルーチン間の優先順位を判定するためにのみ使用されます。 (割込みコントローラの設定には反映されません)
コード例
#define INTNO_SGI1 1 // 割込み番号1(レベルトリガ) #define INTNO_SGI2 2 // 割込み番号2(レベルトリガ) #define INTNO_EDGE3 3 // 割込み番号3(エッジトリガ) #define INTNO_EDGE4 4 // 割込み番号4(エッジトリガ) extern void int_handler_sgi2(void); extern void int_handler_edge_triggered(void); // // 割込み初期化ブロック // const INTINIB _kernel_intinib_table[] = { {INTNO_SGI1, TA_NULL, INTINI_USE_ISR, TA_NULL, (-1)}, // IRQ1 <- 最低優先度、レベルトリガ, ISRを使用 {INTNO_SGI2, TA_NULL, int_handler_sgi2, TA_ENAINT, (-31)}, // IRQ2 <- 最高優先度、レベルトリガ, 直接割込みハンドラ関数を登録, 登録時から割り込み許可 {INTNO_EDGE3, TA_NULL, int_handler_edge_triggered, TA_EDGE, (-1)}, // IRQ3 <- 最低優先度、エッジトリガ {INTNO_EDGE4, TA_NULL, int_handler_edge_triggered, (TA_EDGE|TA_ENAINT), (-31)}, // IRQ4 <- 最高優先度, エッジトリガ, 登録時から割り込み許可 }; #define ISRPRI_HIGH_PRIORITY 1 // 高優先度 #define ISRPRI_MID_PRIORITY 10 // 中優先度 #define ISRPRI_LOW_PRIORITY 16 // 低優先度 extern void isr_high_handler(intptr_t exinf); extern void isr_mid_handler(intptr_t exinf); extern void isr_low_handler(intptr_t exinf); // // 割込みサービルルーチン初期化ブロック // const T_CISR _kernel_isrini_cfg_table[] = { {TA_NULL, (intptr_t)1, INTNO_SGI1, isr_mid_handler, ISRPRI_MID_PRIORITY}, // 中優先度のISRを登録 {TA_NULL, (intptr_t)2, INTNO_SGI1, isr_low_handler, ISRPRI_LOW_PRIORITY}, // 低優先度のISRを登録 {TA_NULL, (intptr_t)3, INTNO_SGI1, isr_high_handler, ISRPRI_TOP_PRIORITY}, // 高優先度のISRを登録 };
-
ATR isratr
ISR生成順序テーブル
-
const ID _kernel_isrorder_table[]
説明
割込みサービスルーチン生成の順序を設定します。 割込みサービスルーチン(ISR)初期化ブロックに登録したISRに対応するIDを指定してください。
定義
const ID _kernel_isrorder_table[];
メンバー
注釈
割込みサービスルーチンを生成する順序をIDで指定します。指定する数は割込みサービスルーチン初期化ブロックに記述された数と必ず一致する必要があります。 一致しない場合のカーネルの動作は保証されません。 このテーブルでの指定の順序に関わらず各割込みサービスルーチンのIDは割込みサービスルーチン初期化テーブルでの並びで決まります。
コード例
/* * 割込みサービスルーチンIDの定数定義 */ #define ISR1 1 #define ISR2 2 #define ISR3 3 const ID _kernel_isrorder_table[] = { ISR3, ISR1, ISR2 };
この例の場合、
ISR3
→ISR1
→ISR2
の順序で割込みサービスルーチン生成処理が行われます。
ユーザ初期化関数の呼出し
-
void _kernel_call_inirtn(void)
説明
カーネル起動時にタスクの起動、ディスパッチを開始する前に呼び出されます。 タスクが動作する前に行っておく処理がある場合に必要な処理があれば記述してください。 この関数から復帰するまでタスクは開始されません。
定義
void _kernel_call_inirtn(void) { /* ... ここにユーザ実装の初期化処理を記述 */ __SOLID_SYS_INTRTN(); /* このマクロは削除しないでください */ }
初期化ルーチンブロックテーブル (カーネル3.4.0以降のみサポート)
警告
初期化ルーチンブロック及び終了処理ルーチンブロックを使用する場合には以下の定義を kernel_cfg.c
内に記述してください。(ASP3.4.0対応のSOLID-IDEの新規プロジェクト作成Wizardにより生成されたプロジェクトでは自動的に追加されています)
#define USE_INITER_RTN_BLOCK // 初期化ルーチンブロック/終了処理ルーチンブロックの使用を宣言
-
typedef struct initialization_routine_block INIRTNB
-
struct initialization_routine_block
説明
カーネル起動時に呼び出されるユーザ実装の初期化関数の登録を行います。
_kernel_call_inirtn()
とは異なり、各関数へのintptr_t
型のパラメータを記述することができます。定義
typedef struct initialization_routine_block { INIRTN inirtn; // 初期化ルーチンの先頭番地->関数型:void (foo)(intptr_t); intptr_t exinf; // 初期化ルーチンの拡張情報 } INIRTNB; const INIRTNB _kernel_inirtnb_table[];
メンバー
-
INIRTN inirtn
初期化ルーチンの先頭番地
typedef void (*INIRTN)(intptr_t exinf);
注釈
登録された関数はカーネル起動時にタスクの起動、ディスパッチを開始する前、 ユーザ初期化関数 (
_kernel_call_inirtn()
) の後に呼び出されます。 登録された初期化ルーチンはテーブル内で記述された順序に従って出されます。コード例
// ユーザー定義の初期化関数(疑似コード) extern void psueudo_open_port(int portno); // 指定デバイスをオープンする疑似関数 extern void psueudo_enable_port(int portno); // 指定デバイスを有効にする疑似関数 // ユーザー定義の初期化関数(疑似コード) void my_inirtn_func(intptr_t exinf) { psueudo_open_port((int)exinf); // パラメータで指定されたポートをオープン psueudo_enable_port((int)exinf); // パラメータで指定されたポートを有効にする } // // 初期化ルーチンブロックテーブル // const T_CISR _kernel_inirtnb_table[] = { // ポート1-3をオープン {my_initrtn_func, 1}, {my_initrtn_func, 2}, {my_initrtn_func, 3}, };
-
INIRTN inirtn
ユーザ終了処理関数の呼出し
-
void _kernel_call_terrtn(void)
説明
カーネルが終了したタイミングで呼び出されます。 必要な処理があれば記述してください。 この関数が呼び出された時点ではすべてのタスク及びカーネルの動作は 終了しているため、終了処理の中でサービスコールなどのカーネルの機能を使うことはできません。
定義
void _kernel_call_terrtn(void) { /* ... ここにユーザ実装の終了処理を記述 */ __SOLID_SYS_TERRTN(); /* このマクロは削除しないでください */ }
終了処理ルーチンブロックテーブル (カーネル3.4.0以降のみサポート)
-
typedef struct termination_routine_block TERRTNB
-
struct termination_routine_block
説明
カーネル終了時に呼び出されるユーザ実装の終了処理関数の登録を行います。 終了ルーチンブロックテーブルに登録された終了処理関数の呼出が行われます。
_kernel_call_terrtn()
とは異なり、各関数へのintptr_t
型のパラメータを記述することができます。定義
typedef struct termination_routine_block { TERRTN terrtn; // 終了処理ルーチンの先頭番地->関数型:void (foo)(intptr_t); intptr_t exinf; // 終了処理ルーチンの拡張情報 } TERRTNB; const TERRTNB _kernel_terrtnb_table[];
メンバー
-
TERRTN terrtn
終了処理ルーチンの先頭番地
typedef void (*TERRTN)(intptr_t exinf);
注釈
登録された関数はカーネル終了時にユーザ終了処理関数 (
_kernel_call_terrtn()
) の前のタイミングで呼び出されます。 テーブルに登録された関数が呼び出される時点ではすべてのタスク及びカーネルの動作は終了しているため、終了処理の中でサービスコールなどのカーネルの機能を使うことはできません。 登録された終了処理ルーチンはテーブル内で記述された順序に従って出されます。コード例
// ユーザー定義の終了処理関数(疑似コード) extern void psueudo_close_port(int portno); // 指定デバイスをクローズする疑似関数 extern void psueudo_disable_port(int portno); // 指定デバイスを無効にする疑似関数 // ユーザー定義の終了処理関数(疑似コード) void my_terrtn_func(intptr_t exinf) { psueudo_disable_port((int)exinf); // 指定デバイスを無効にする psueudo_open_port((int)exinf); // ポートをクローズ } // // 終了処理ルーチンブロックテーブル // const T_CISR _kernel_terrtnb_table[] = { // ポート1-3をオープン時と逆順でクローズ {my_tertrtn_func, 3}, {my_tertrtn_func, 2}, {my_tertrtn_func, 1}, };
-
TERRTN terrtn
動的生成される資源の上限数設定(動的資源生成カーネルのみ)
/*
* 動的に生成するカーネル資源の数を定義
* (静的なテーブルで定義される資源に追加して動的に
* 生成できる資源数を定義
*/
#define TNUM_AID_TSK 0
#define TNUM_AID_SEM 0
#define TNUM_AID_FLG 0
#define TNUM_AID_DTQ 0
#define TNUM_AID_PDQ 0
#define TNUM_AID_MTX 0
#define TNUM_AID_MPF 0
#define TNUM_AID_CYC 0
#define TNUM_AID_ALM 0
#define TNUM_AID_ISR 0
各資源ごとに動的生成可能な上限数を定義します。
ここで定義した数を超えて資源を生成するAPI(acre_*)を呼び出した場合、E_NOID
(ID番号不足) が返されます。
定義を省略した場合の値は0となります。
ここで定義される資源数には静的に生成される資源は含まれません。 例えば、テーブル定義で3つのタスクを定義し、さらにTNUM_AID(3)を定義した場合には合計で最大6つのタスクが生成できることになります。
各定数と資源の対応は以下の通りです。
定数名 |
資源名称 |
---|---|
TNUM_AID_TSK |
タスク |
TNUM_AID_SEM |
セマフォ |
TNUM_AID_FLG |
イベントフラグ |
TNUM_AID_DTQ |
データキュー |
TNUM_AID_PDQ |
優先度データキュー |
TNUM_AID_MTX |
ミューテックス |
TNUM_AID_MPF |
固定長メモリプール |
TNUM_AID_CYC |
周期通知 |
TNUM_AID_ALM |
アラーム通知 |
TNUM_AID_ISR |
ISR(割込みサービスルーチン) |
注釈
動的生成カーネルでない場合にはこれらの定義は無視されます。
起動要求キューイング数/起床要求キューイング数の設定(optional)
/*
* タスクの起動要求キューと起床要求キューの最大数を定義
* (optional)
*
* TMAX_ACT_QUEUE/TMAX_WUP_QUEUEを定義すると起動要求(act_tsk)
* 起床要求(wup_tsk)がキューイングされる数を設定できます。
* 未定義の場合のでデフォルト値はいずれもUINT32_MAXです。
*/
#define TMAX_ACT_QUEUE 50 /* 設定例 */
#define TMAX_WUP_QUEUE 50 /* 設定例 */
act_tsk()
によるタスク起動要求と wup_tsk()
による起床要求がキューイングされる数を定義します。
(通常はコメントアウトされています)
各定数とキューの対応は以下の通りです。
定数名 |
キュー名称 |
未定義の場合のデフォルト値 |
---|---|---|
TMAX_ACT_QUEUE |
起動要求キューイング数 (0~ |
|
TMAX_WUP_QUEUE |
起床要求キューイング数 (0~ |
|
注釈
TOPPERSリリースの実装ではキューイング数はそれぞれ1固定ですが、SOLIDでは上記の通り拡張しています。
設定ファイルの編集 (FMP)
SOLID-IDEを使用してアプリケーションの新規作成を行うとアプリケーションのスケルトンコードの他に以下の二つのファイルがアプリケーションと同じフォルダに生成されます。以下のファイルを編集し、ビルドすることでカーネル資源の設定を行います。
kernel_cfg.c
カーネルが起動時に生成する各資源の数や属性等のパラメータを記述したテーブルを定義します。ビルド時にアプリケーションと同時にビルドされ、カーネルとリンクされます。
kernel_cfg.h
静的生成される各資源のID (数値) をC言語の定数 (
enum
列挙子) として定義し、アプリケーションコードから資源を参照するための名前を対応付けます。カーネル内部では各資源のIDしか扱わないので、定数の定義は必須ではありません。kernel_cfg.c
からincludeされるので、IDの他にアプリケーションとkernel_cfg.c
との間で共有する定義を記述する目的にも使えます。
注釈
タスクやセマフォなどのIDで管理される資源のうち、静的に生成されるものについては kernel_cfg.c
で定義した初期化ブロック内の順序でIDが割り当てられます。(最初の要素が ID 1
となり、残りは順番にIDが割り振られます。)
警告
ネットワーク機能を利用する場合、kernel_cfg.c
の中にある下記の定義を削除しないでください。
__SOLID_RESERVED_TASKS__
__SOLID_RESERVED_TASK_ORDER__
__SOLID_RESERVED_SEMS__
__SOLID_RESERVED_DTQS__
__SOLID_SYS_INTRTN
__SOLID_SYS_TERRTN
ネットワークを利用する場合の設定にてついてはネットワークの項の カーネル資源設定について も参照してください。
タスク初期化ブロック
-
typedef struct task_initialization_block TINIB
-
struct task_initialization_block
説明
タスク生成時の初期化情報を設定します。
定義
typedef struct task_initialization_block { ATR tskatr; // タスク属性 intptr_t exinf; // タスクの拡張情報 TASK task; // タスクの起動番地 uint_t ipriority; // タスクの起動時優先度(内部表現) size_t stksz; // スタック領域のサイズ(丸めた値) void *stk; // スタック領域の先頭番地 ATR texatr; // タスク例外処理ルーチン属性 TEXRTN texrtn; // タスク例外処理ルーチンの起動番地 ID iaffinity; // タスクの初期割付けプロセッサ(1...) uint_t affinity_mask; // タスクの割付け可能プロセッサ(bitmask) } TINIB; const TINIB _kernel_tinib_table[];
メンバー
-
ATR tskatr
タスク属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_ACT
タスクの生成時にタスクを起動する
TA_NOACTQUE
タスクに対する起動要求をキューイングしない
TA_RSTR
生成するタスクを制約タスクとする
-
intptr_t exinf
タスクの拡張情報
タスクが起動されるときの引数を指定します。(任意)
-
TASK task
タスクの起動番地
タスクの起動番地をC言語の関数アドレスで指定します。 関数型は以下の通りです。
typedef void (*TASK)(intptr_t exinf);
-
uint_t ipriority
タスクの起動時優先度(内部表現)
カーネル内部表現で指定する必要があるため、マクロ
INT_PRIORITY
を使用してください。INT_PRIORITY(1)
が最高優先度、INT_PRIORITY(16)
(優先度拡張なし) またはINT_PRIORITY(256)
(優先度拡張あり) が最低優先度です。
-
size_t stksz
スタック領域のサイズ(丸めた値)
-
void *stk
スタック領域の先頭番地
-
ATR texatr
タスク例外処理ルーチン属性
TA_NULLのみ指定可能です
-
TEXRTN texrtn
タスク例外処理ルーチンの起動番地
関数型は以下の通りです。
typedef void (*TEXRTN)(TEXPTN texptn, intptr_t exinf);
-
ID iaffinity
タスクの初期割り付けプロセッサ
-
uint_t affinity_mask
タスクの割り付け可能プロセッサ
タスクを割り付け可能なプロセッサをビットマスクで指定します。 最下位ビット (プロセッサID 1) を起点とし、各ビット位置がプロセッサに対応します。 プロセッサIDに対応するビット (
1 << プロセッサID - 1
) をセットすることで割り付け可能となります。例: プロセッサID1, 3, 4で割り付け可能とする場合
.affinity_mask = 0xd, // (= 0b1101)
符号なし整数 (
uint_t
型) で直接値を指定するか、以下のマクロを使用して設定してください。CFG_PROC_MASK
(プロセッサID)
CFG_PROC_MASK_ANY
iaffinity
,affinity_mask
の両方を初期化するマクロ:CFG_TASK_AFFINITY
(初期割付けプロセッサID, 割付け可能プロセッサビットマスク)
注釈
このテーブル内に記述された順序に沿ってタスクIDが
1
(TMIN_TSKID
) から割り振られます。stk
がNULLの場合、カーネルは自動的にstksz
で指定された領域を確保してタスクに割り当てます。ユーザが確保した領域(変数)をスタックとして使用したい場合にはその領域のアドレスをstk
に指定しますがその場合は以下の点に注意してくださいコード例
#define STACK_SIZE 2048 extern void task1(void *); extern void task2(void *); static STK_T _stack_TASK1[COUNT_STK_T(STACK_SIZE)]; const TINIB _kernel_tinib_table[] = { // 生成時に起動(TA_ACT), スタック領域のアドレスを指定 (スタックフェンス機能 有効) // 初期時にプロセッサID 1(core 0)で起動し、プロセッサID 1または2で動作可能 <マクロを使わずに直値で記述例> { TA_ACT, 0, task1, INT_PRIORITY(MID_PRIORITY), ROUND_STK_T(STACK_SIZE), _stack_TASK1, (TA_NULL), (tex_routine), 1, 3 }, // 生成時には起動しない, スタックをカーネル内で確保(スタックフェンス機能 有効) // 初期時にプロセッサID 1(core 0)で起動し、全てのプロセッサコアでで動作可能 <マクロを使った記述例> { TA_NULL, 0, task2, INT_PRIORITY(HIGH_PRIORITY), ROUND_STK_T(STACK_SIZE), NULL, CFG_TASK_AFFINITY(1, CFG_PROC_MASK_ANY) }, // 生成時には起動しない, スタックをカーネル内で確保(スタックフェンス機能 有効) // 初期時にプロセッサID 3(core 2)で起動し、プロセッサID 1または3で動作可能 <マクロを使った記述例> { TA_NULL, 0, task2, INT_PRIORITY(HIGH_PRIORITY), ROUND_STK_T(STACK_SIZE), NULL, 3, CFG_PROC_MASK(1)|CFG_PROC_MASK(3) }, };
-
ATR tskatr
ロック付きオブジェクト属性初期化
-
CFG_OBJ_ATTR(atr, prcid)
ロック付きオブジェクト属性を初期化し、プロセッサロック方式の場合には該当するカーネル内部のテーブルとのリンクを設定します。
- パラメータ:
atr -- 属性値(各オブジェクトの仕様を参照)
prcid -- カーネルのロック方式がプロセッサロック (
P_KLOCK
) の場合に紐づけるプロセッサID(1...)
注釈
カーネルのロック方式がプロセッサロック方式以外の場合には
prcid
の値は無視されます。
スピンロックオブジェクト属性初期化
-
CFG_SPN_ATTR(atr, prcid)
スピンロックオブジェクト属性を初期化し、スピンロック方式がエミュレーション方式(soft)かつ、カーネルの排他方式がプロセッサロック方式の場合に該当するカーネル内部のテーブルとのリンクを設定します。
- パラメータ:
atr -- 属性値(各オブジェクトの仕様を参照)
prcid -- カーネルのロック方式がプロセッサロック (
P_KLOCK
) の場合に紐づけるプロセッサID(1...)
タスク生成順序テーブル
-
const ID _kernel_torder_table[]
説明
タスク生成の順序を設定します。
定義
const ID _kernel_torder_table[];
注釈
タスクを生成する順序をIDで指定します。指定する数はタスク初期化ブロックに記述された数と必ず一致する必要があります。 一致しない場合のカーネルの動作は保証されません。 このテーブルでの指定の順序に関わらず各タスクのIDはタスク初期化テーブルでの並びで決まります。
コード例
/* * タスクIDの定数定義 */ #define TASK1 1 #define TASK2 2 #define TASK3 3 const ID _kernel_torder_table[] = { TASK3, TASK1, TASK2 };
この例の場合、
TASK3
→TASK1
→TASK2
の順序でタスク生成処理が行われます。
セマフォ初期化ブロック
-
typedef struct semaphore_initialization_block SEMINIB
-
struct semaphore_initialization_block
説明
使用するセマフォの属性を定義します。
定義
typedef struct semaphore_initialization_block { ATR sematr; // セマフォ属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) uint_t isemcnt; // セマフォの資源数の初期値 uint_t maxsem; // セマフォの最大資源数 } SEMINIB; const SEMINIB _kernel_seminib_table[];
メンバー
-
ATR sematr
セマフォ属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
uint_t isemcnt
セマフォの資源数の初期値
-
uint_t maxsem
セマフォの最大資源数
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
sematr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。コード例
const SEMINIB _kernel_seminib_table[] = { { CFG_OBJ_ATTR(TA_NULL, 1), 1, 1 }, // 待ち行列=FIFO順, 最大数=1, 初期値=1でセマフォを生成 { CFG_OBJ_ATTR(TA_TPRI, 1), 0, 1 }, // 待ち行列=タスク優先度順, 最大数=1, 初期値=0でセマフォを生成 };
-
ATR sematr
イベントフラグ初期化ブロック
-
typedef struct eventflag_initialization_block FLGINIB
-
struct eventflag_initialization_block
説明
使用するイベントフラグの属性を定義します。
定義
typedef struct eventflag_initialization_block { ATR flgatr; // イベントフラグ属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) FLGPTN iflgptn; // イベントフラグのビットパターンの初期値 } FLGINIB; const FLGINIB _kernel_flginib_table[];
メンバー
-
ATR flgatr
イベントフラグ属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_WMUL
複数のタスクが待つのを許す
TA_CLR
タスクの待ち解除時にイベントフラグの全てのビットをクリアする
TA_BITCLR
タスクの待ち解除時にイベントフラグの待ち対象ビットのみをクリアする
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
FLGPTN iflgptn
イベントフラグのビットパターンの初期値
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
flgatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。注釈
カーネルのロック方式がプロセッサロック方式以外となっている場合には
prcid
の値は無視されます。注釈
TA_CLR
/TA_BITCLR
によるビットクリア動作についてはTOPPERSリリースとの相違点の項の イベントフラグ待ち解除時のクリア方法指定 を参照してください。コード例
const FLGINIB _kernel_flginib_table[] = { { CFG_OBJ_ATTR(TA_NULL, 1), 0x00 }, // 複数タスク待ち不可, 待ち行列=FIFO順, フラグ初期値=0 // プロセッサID 1にロックを関連付け { CFG_OBJ_ATTR(TA_CLR, 1), 0x01 }, // 複数タスク待ち不可, 待ち行列=FIFO順, 待ち解除時にフラグクリア, フラグ初期値=1 { CFG_OBJ_ATTR(TA_WMUL|TA_CLR, 1), 0x00 }, // 複数タスク待ち許可, 待ち行列=FIFO順, 待ち解除時にフラグクリア, フラグ初期値=0 { CFG_OBJ_ATTR(TA_WMUL|TA_TPRI, 2), 0x00 }, // 複数タスク待ち許可, 待ち行列=タスク優先度順, フラグ初期値=0 };
-
ATR flgatr
データキュー初期化ブロック
-
typedef struct dataqueue_initialization_block DTQINIB
-
struct dataqueue_initialization_block
説明
使用するデータキューの属性を定義します。
定義
typedef struct dataqueue_initialization_block { ATR dtqatr; // データキュー属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) uint_t dtqcnt; // データキューの容量 DTQMB *p_dtqmb; // データキュー管理領域の先頭番地 } DTQINIB; const DTQINIB _kernel_dtqinib_table[];
メンバー
-
ATR dtqatr
データキュー属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
送信 待ち行列をタスクの優先度順にする (受信待ち行列は常にFIFO順)
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
uint_t dtqcnt
データキューの容量
-
DTQMB *p_dtqmb
データキュー管理領域の先頭番地
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
dtqatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。注釈
p_dtqmb
がNULLの場合、カーネルは自動的にdtqcnt
で指定された容量に対して必要な管理領域を確保してデータキューに割り当てます。 ユーザが確保した領域をデータキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、p_dtqmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
コード例
static MB_T _kernel_dtqmb_DTQ3[TCNT_DTQMB(2)]; const DTQINIB _kernel_dtqinib_table[] = { { CFG_OBJ_ATTR(TA_NULL, 1), 2, NULL }, // 待ち行列=FIFO順, 容量=2 プロセッサID 1にロックを関連付け { CFG_OBJ_ATTR(TA_NULL, 2), 0, NULL }, // 待ち行列=FIFO順, 容量=0 プロセッサID 1にロックを関連付け { CFG_OBJ_ATTR(TA_TPRI, 1), 2, _kernel_dtqmb_DTQ3 }, // 待ち行列=タスク優先度順, 容量=2, 管理領域を指定 };
-
ATR dtqatr
優先度データキュー初期化ブロック
-
typedef struct pridataq_initialization_block PDQINIB
-
struct pridataq_initialization_block
説明
使用する優先度データキューの属性を定義します。
定義
typedef struct pridataq_initialization_block { ATR pdqatr; // 優先度データキュー属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) uint_t pdqcnt; // 優先度データキューの容量 PRI maxdpri; // データ優先度の最大値 PDQMB *p_pdqmb; // 優先度データキュー管理領域の先頭番地 } PDQINIB; const PDQINIB _kernel_pdqinib_table[];
メンバー
-
ATR pdqatr
優先度データキュー属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
送信 待ち行列をタスクの優先度順にする (受信待ち行列は常にFIFO順)
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
uint_t pdqcnt
優先度データキューの容量
-
PRI maxdpri
データ優先度の最大値
TMIN_DPRI
(1, 最高優先度) からTMAX_DPRI
(16)の範囲で指定可能です
-
PDQMB *p_pdqmb
優先度データキュー管理領域の先頭番地
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
pdqatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。注釈
TA_TPRI
を指定した場合のデータ優先度とタスク優先度の関係、動作についてはTOPPERS新世代カーネル統合仕様書の4.4.4 優先度データキューの「使用上の注意」を参照してください。p_pdqmb
がNULLの場合、カーネルは自動的にpdqcnt
で指定された容量に対して必要な管理領域を確保して優先度データキューに割り当てます。 ユーザが確保した領域を優先度データキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、p_pdqmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
コード例
static MB_T _kernel_pdqmb_PDQ3[TCNT_PDQMB(2)]; const PDQINIB _kernel_pdqinib_table[] = { { CFG_OBJ_ATTR(TA_NULL, 1), 2, TMAX_DPRI, NULL }, // 送信待ち行列=FIFO順, データ優先度=最大(最低) { CFG_OBJ_ATTR(TA_NULL, 4), 0, 8, NULL }, // 送信待ち行列=FIFO順、容量=0 プロセッサID 4にロックを関連付け { CFG_OBJ_ATTR(TA_TPRI, 1), 2, TMAX_DPRI, _kernel_pdqmb_PDQ3 }, // 送信待ち行列=タスク優先度順, 管理領域を指定 };
-
ATR pdqatr
メールボックス初期化ブロック
-
typedef struct mailbox_initialization_block MBXINIB
-
struct mailbox_initialization_block
説明
使用するメールボックスの属性を定義します。
定義
typedef struct mailbox_initialization_block { ATR mbxatr; // メールボックス属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) PRI maxmpri; // メッセージ優先度の最大値 } MBXINIB; const MBXINIB _kernel_mbxinib_table[];
メンバー
-
ATR mbxatr
メールボックス属性
以下の属性を指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_MPRI
待ち行列をメッセージの優先度順にする
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
PRI maxmpri
メールボックス優先度の最大値
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
mbxatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。コード例
const MBXINIB _kernel_mbxinib_table[] = { { CFG_OBJ_ATTR(TA_TPRI, 1), 8}, // 受信待ち行列=タスク優先度順, プロセッサID 1に関連付け { CFG_OBJ_ATTR(TA_MPRI, 1), TMAX_MPRI}, // 受信待ち行列=メッセージ優先度順, プロセッサID 2に関連付け };
-
ATR mbxatr
ミューテックス初期化ブロック
-
typedef struct mutex_initialization_block MTXINIB
-
struct mutex_initialization_block
説明
使用するミューテックスの属性を定義します。
定義
typedef struct mutex_initialization_block { ATR mtxatr; // ミューテックス属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) uint_t ceilpri; // ミューテックスの上限優先度(内部表現) } MTXINIB; const MTXINIB _kernel_mtxinib_table[];
メンバー
-
ATR mtxatr
ミューテックス属性
以下の属性を指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_CEILING
優先度上限ミューテックスとする。待ち行列をタスクの優先度順にする
TA_INHERIT
優先度継承ミューテックス (SOLID-OS拡張) とする。待ち行列をタスクの優先度順にする
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
uint_t ceilpri
ミューテックスの上限優先度(内部表現)
カーネル内部表現で指定する必要があるため、マクロ
INT_PRIORITY
を使用してください。INT_PRIORITY(1)
が最高優先度、INT_PRIORITY(16)
(優先度拡張なし) またはINT_PRIORITY(256)
(優先度拡張あり) が最低優先度です。TA_CEILING
が指定された場合のみ有効です。
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
mbxatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。注釈
優先度上限ミューテックスの動作についてはTOPPERS新世代カーネル統合仕様書の4.4.6 ミューテックスの「使用上の注意」を参照してください。
コード例
const MTXINIB _kernel_mtxinib_table[] = { { CFG_OBJ_ATTR(TA_TPRI, 1), INT_PRIORITY(0)}, // ロック待ち行列=タスク優先度順, プロセッサID 1に関連付け(ceilpriは無効) { CFG_OBJ_ATTR(TA_CEILING, 2), INT_PRIORITY(8)}, // 優先度上限ミューテックス(待ち行列=タスク優先度順), // プロセッサID 2に関連付け, 上限優先度 = 8 { CFG_OBJ_ATTR(TA_INHERIT, 3), 0}, // 優先度上限ミューテックス(待ち行列=タスク優先度順), // プロセッサID 3に関連付け(ceilpriは無効) };
-
ATR mtxatr
メッセージバッファ初期化ブロック
-
typedef struct messagebuf_initialization_block MBFINIB
-
struct messagebuf_initialization_block
説明
使用するメッセージバッファの属性を定義します。
定義
typedef struct messagebuf_initialization_block { ATR mbfatr; // メッセージバッファ属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) uint_t maxmsz; // メッセージの最大長(バイト数) size_t mbfsz; // メッセージバッファ管理領域のサイズ(バイト数) void *mbfmb; // メッセージバッファ管理領域の先頭番地 } MBFINIB; const MBFINIB _kernel_mbfinib_table[];
メンバー
-
ATR mbfatr
メッセージバッファ属性
メッセージバッファで指定可能な属性はないため、
TA_NULL
をセットします。
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
uint_t maxmsz
メッセージの最大長
メッセージ最大長をバイト数で指定します
-
size_t mbfsz
メッセージバッファ管理領域のサイズ
メッセージバッファ管理領域のサイズをバイト数で指定します
-
void *mbfmb
メッセージバッファ管理領域の先頭番地
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
mbfatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。注釈
mbfmb
がNULLの場合、カーネルは自動的にmbfsz
で指定された容量に対して必要な管理領域を確保してデータキューに割り当てます。 ユーザが確保した領域をデータキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、mbfmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
-
TSZ_MBFMB(msgcnt, msgsz)
msgszで指定したサイズのメッセージを,msgcntで指定した数だけ格納できるメッセージバッファ管理領域のサイズ(バイト数)
-
TCNT_MBFMB(msgcnt, msgsz)
msgszで指定したサイズのメッセージを,msgcntで指定した数だけ格納できるメッセージバッファ管理領域を確保するために必要なMB_T型の配列の要素数
コード例
#define MBF3_MSGSZ 50 #define MBF3_MSGCNT 100 static MB_T _kernel_mbfmb_MBF3[TCNT_MBFMB(MBF3_MSGCNT, MBF3_MSGSZ)]; const MBFINIB _kernel_mbfinib_table[] = { // 最大メッセージサイズ=16, 管理領域 =32バイト プロセッサID 1にロックを関連付け { CFG_OBJ_ATTR(TA_NULL, 1), 16, 32, NULL }, // 最大メッセージサイズ=8, 管理領域=maxmsz * 16個分 プロセッサID 2にロックを関連付け { CFG_OBJ_ATTR(TA_NULL, 2), 8, TSZ_MBFMB(16, 8), NULL }, // 最大メッセージサイズ=50, 管理領域=maxmsz * 100個分 プロセッサID 1にロックを関連付け { CFG_OBJ_ATTR(TA_NULL, 1), MBF3_MSGSZ, TSZ_MBFMB(MBF3_MSGCNT, MBF3_MSGSZ), _kernel_mbfmb_MBF3 }, };
-
ATR mbfatr
固定長メモリプール初期化ブロック
-
typedef struct fixed_memorypool_initialization_block MPFINIB
-
struct fixed_memorypool_initialization_block
説明
使用する固定長メモリプール初期化ブロックの属性を定義します。
定義
typedef struct fixed_memorypool_initialization_block { ATR mpfatr; // 固定長メモリプール属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ(プロセッサロック方式の場合のみ) uint_t blkcnt; // メモリブロック数 uint_t blksz; // メモリブロックのサイズ(丸めた値) void *mpf; // 固定長メモリプール領域の先頭番地 MPFMB *p_mpfmb; // 固定長メモリプール管理領域の先頭番地 } MPFINIB; const MPFINIB _kernel_mpfinib_table[];
メンバー
-
ATR mpfatr
固定長メモリプール属性
TA_TPRI
待ち行列をタスクの優先度順にする
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
-
uint_t blkcnt
メモリブロック数
-
uint_t blksz
メモリブロックのサイズ(丸めた値)
-
void *mpf
固定長メモリプール領域の先頭番地
-
MPFMB *p_mpfmb
固定長メモリプール管理領域の先頭番地
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
mpfatr
と メンバp_obj_lock
はマクロCFG_OBJ_ATTR
を使用して記述してください。注釈
mpf
及びp_mpfmb
にNULLを指定した場合はカーネル内部で必要なメモリ領域の確保が行われます。固定長メモリプール領域、固定長メモリプール管理領域として使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるためそれぞれ以下のマクロを使用して宣言してください。
固定長メモリプール領域を確保するためのマクロとデータ型
-
type MPF_T
固定長メモリプール領域用のデータ型
-
COUNT_MPF_T(blksz)
固定長メモリブロックのサイズがblkszの固定長メモリプール領域を確保するために,固定長メモリブロック1つあたりに必要な:c:type:MPF_T 型の配列の要素数
-
type MPF_T
固定長メモリプール管理領域を確保するためのマクロ
-
TSZ_MPFMB(blkcnt)
blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域のサイズ(バイト数)
-
TCNT_MPFMB(blkcnt)
blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域を確保するために必要なMB_T型の配列の要素数
-
TSZ_MPFMB(blkcnt)
コード例
#define MPF_BLOCK_SIZE 64 #define NUM_BLOCKS_MPF1 1 #define NUM_BLOCKS_MPF2 2 #define NUM_BLOCKS_MPF3 1 #define NUM_BLOCKS_MPF4 1 static MPF_T _pool1[ NUM_BLOCKS_MPF1 * COUNT_MPF_T(MPF_BLOCK_SIZE) ]; static MPF_T _pool4[ NUM_BLOCKS_MPF2 * COUNT_MPF_T(MPF_BLOCK_SIZE) ]; static MB_T _mpfmb2[TCNT_MPFMB(NUM_BLOCKS_MPF2)]; static MB_T _mpfmb4[TCNT_MPFMB(NUM_BLOCKS_MPF4)]; const MPFINIB _kernel_mpfinib_table[] = { { CFG_OBJ_ATTR(TA_NULL, 1), NUM_BLOCKS_MPF1, ROUND_MPF_T(MPF_BLOCK_SIZE), _pool1, NULL }, // データ領域を静的変数で確保 { CFG_OBJ_ATTR(TA_NULL, 1), NUM_BLOCKS_MPF2, ROUND_MPF_T(MPF_BLOCK_SIZE), NULL, (MPFMB*)_mpfmb2 }, // 管理領域を静的変数で確保 { CFG_OBJ_ATTR(TA_TPRI, 1), NUM_BLOCKS_MPF3, ROUND_MPF_T(1), NULL, NULL }, // 待ち行列=タスク優先度順 { CFG_OBJ_ATTR(TA_NULL, 1), NUM_BLOCKS_MPF4, ROUND_MPF_T(MPF_BLOCK_SIZE), _pool4, (MPFMB*)_mpfmb4 }, // すべての領域を静的変数で確保 };
-
ATR mpfatr
周期通知/アラーム通知初期化ブロック中のプロセッサ情報を初期化するためのマクロ
-
CFG_SYSTIM_AFFINITY(prcid, affinity_mask)
周期通知/アラーム通知初期化ブロック中のプロセッサ情報 (
iaffinity
,affinity_mask
)を初期化します- パラメータ:
prcid -- 初期状態で通知処理が動作するプロセッサID(1...)
affinity_mask --
通知処理が動作可能なプロセッサをビットマスクで指定 符号なし整数 (
uint_t
型)で直接値を指定するか、 以下のマクロを使用して設定してください [複数の場合は論理和で指定]CFG_PROC_MASK
(プロセッサID)
CFG_PROC_MASK_ANY
注釈
コンパイル時にプリプロセッサ定数
TOPPERS_SYSTIM_LOCAL
が定義されていない場合は本マクロの定義は空になります。この場合、
prcid
の値に関わらず通知ハンドラは、すべて一つのプロセッサ(タイマ管理プロセッサ)上で動作することになります。
周期通知初期化ブロック
-
typedef struct cyclic_handler_initialization_block CYCINIB
-
struct cyclic_handler_initialization_block
説明
使用する周期通知の属性と処理を定義します。
定義
typedef struct cyclic_handler_initialization_block { ATR cycatr; // 周期通知属性 intptr_t exinf; // 通知ハンドラの拡張情報 NFYHDR nfyhdr; // 通知ハンドラの起動番地 RELTIM cyctim; // 周期通知の起動周期 RELTIM cycphs; // 周期通知の起動位相 ID iaffinity; // 周期ハンドラの初期割付けプロセッサ(ローカルタイマ方式の場合のみ) uint_t affinity_mask; // 周期ハンドラの割付け可能プロセッサ(ローカルタイマ方式の場合のみ) } CYCINIB; const CYCINIB _kernel_cycinib_table[];
メンバー
-
ATR cycatr
周期通知属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_STA
周期通知の生成時に周期通知を動作開始する
-
intptr_t exinf
通知ハンドラの拡張情報
通知ハンドラが起動されるときの引数を指定します。(任意)
-
NFYHDR nfyhdr
通知ハンドラの起動番地
通知ハンドラの起動番地をC言語の関数アドレスで指定します。 関数型は以下の通りです。
typedef void (*NFYHDR)(intptr_t exinf);
-
RELTIM cyctim
周期通知の起動周期(単位:μsec)
-
RELTIM cycphs
周期通知の起動位相(単位:μsec)
-
ID iaffinity
周期ハンドラの初期割付けプロセッサ
-
uint_t affinity_mask
周期ハンドラの割付可能プロセッサ
注釈
メンバ
iaffinity
と メンバaffinity_mask
はマクロCFG_SYSTIM_AFFINITY
を使用して記述してください。コード例
#define CYC1_CYCLE 100U // 100μsec #define CYC2_CYCLE 1000U // 1msec extern void cyc_func(intptr_t exinf); const CYCINIB _kernel_cycinib_table[] = { // // 生成と同時に100μsec間隔でcyc_funcを呼び出す(プロセッサID 1で動作開始、すべてのプロセッサに移動可能) // { TA_STA, 0, cyc_func, CYC1_CYCLE, CYC1_CYCLE, CFG_SYSTIM_AFFINITY(1, CFG_PROC_MASK_ANY) }, // // 停止状態で生成、基準時刻を生成時の時刻に設定と同時に1msec間隔でcyc_funcを呼び出す // プロセッサID 2のみで動作 // { TA_PHS, 0, cyc_func, CYC2_CYCLE, CYC2_CYCLE, CFG_SYSTIM_AFFINITY(2, CFG_PROC_MASK(2)) }, };
-
ATR cycatr
アラーム通知初期化ブロック
-
typedef struct alarm_handler_initialization_block ALMINIB
-
struct alarm_handler_initialization_block
説明
使用するアラーム通知の属性と処理を定義します。
定義
typedef struct alarm_handler_initialization_block { ATR almatr; // アラームハンドラ属性 intptr_t exinf; // アラームハンドラの拡張情報 ALMHDR almhdr; // アラームハンドラの起動番地 ID iaffinity; // アラームハンドラの初期割付けプロセッサ(ローカルタイマ方式の場合のみ) uint_t affinity_mask; // アラームハンドラの割付け可能プロセッサ(ローカルタイマ方式の場合のみ) } ALMINIB; const ALMINIB _kernel_alminib_table[];
メンバー
-
ATR almatr
アラーム通知属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
intptr_t exinf
アラームハンドラの拡張情報
アラームハンドラが起動されるときの引数を指定します。(任意)
-
ALMHDR almhdr
アラームハンドラの起動番地
-
ID iaffinity
アラームハンドラの初期割付けプロセッサ
-
uint_t affinity_mask
アラームハンドラの割付け可能プロセッサ
注釈
メンバ
iaffinity
と メンバaffinity_mask
はマクロCFG_SYSTIM_AFFINITY
を使用して記述してください。コード例
extern void alarmHandler(intptr_t exinf); const ALMINIB _kernel_alminib_table[] = { // 通知時に関数 alarmHandler が引数0で呼び出される。プロセッサIDは1に固定 { TA_NULL, (intptr_t)0, alarmHandler, CFG_SYSTIM_AFFINITY(1, CFG_PROC_MASK(1)) }, // 通知時に関数 alarmHandler が引数0で呼び出される。 // 実行されるプロセッサIDは初期状態では2, その他のすべてのプロセッサに移動可能 { TA_NULL, (intptr_t)4, alarmHandler, CFG_SYSTIM_AFFINITY(2, CFG_PROC_MASK_ANY) }, };
-
ATR almatr
スピンロック初期化設定ブロック
-
typedef struct spin_lock_initialization_block SPNINIB
-
struct spin_lock_initialization_block
説明
スピンロック初期化ブロックの属性を定義します。
定義
typedef struct spin_lock_initialization_block { ATR spnatr; // スピンロック属性 LOCK *p_obj_lock; // オブジェクトロックへのポインタ // スピンロックがエミュレーション(soft)でプロセッサロック方式の場合のみ } SPNINIB;
メンバー
-
ATR spnatr
スピンロック属性
常に
TA_NULL
を設定してください
-
LOCK *p_obj_lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
spnatr
と メンバp_obj_lock
はマクロCFG_SPN_ATTR
を使用して記述してください。注釈
カーネルのビルド条件において以下の両方の条件が同時に成立しない場合にはprcidの値は無視されます。
スピンロック方式: エミュレーション方式 (soft,
TTYPE_SPN
==
EMULATE_SPN
)カーネルロック方式: プロセッサロック方式 (proc,
TTYPE_KLOCK
==
P_KLOCK
)
コード例
const SPNINIB _kernel_spninib_table[] = { {CFG_SPN_ATTR(TA_NULL, 1)}, // 属性なし, プロセッサID 1にロックを関連付け };
-
ATR spnatr
割込み初期化設定ブロック
-
typedef struct interrupt_handler_initialization_block INTINIB
-
struct interrupt_handler_initialization_block
説明
カーネルで扱う割込みについて定義します。 カーネルは起動時にこのテーブルに記述された内容を読込み、Core Serviceに対して必要な設定を行います。 このテーブルに定義されていない割込みはカーネル管理外となり、アプリケーションから扱う事はできなくなります。
割込みの処理を行う関数を登録する方法には以下の二種類があります。
- 割込みサービスルーチン(ISR)
カーネル内部のハンドラを経由します。同一の割込みに対して複数のISRを登録することができ、割込み発生時には設定されて優先度に従ってすべてのISRが呼び出されます。
動的生成機能拡張カーネルの場合は
acre_isr()
の呼び出しによりISRを登録することもできます。 (その場合でも割込み初期化設定ブロックであらかじめ使用する割込みについて定義しておく必要はあります)- 割込みハンドラ
割込み初期化設定ブロックに登録された関数のみが呼び出されます。 カーネルの動的生成機能拡張対応の有無に関わらず動的に登録することはできません。
同一の割込みに対して割込みサービスルーチンと割込みハンドラの両方を同時に使用することはできません。
定義
typedef struct interrupt_handler_initialization_block { INTNO intno; // 割込み番号 ATR inhatr; // 割込みハンドラ属性 FP inthdr; // 割込みハンドラの出入口処理の番地 (ISR使用時はINTINI_USE_ISRを指定)->関数型:void (foo)(void); ATR intatr; // 割込み属性 (TA_ENAINT, TA_EDGEのみサポート) PRI intpri; // 割込み優先度 [-1:最低優先度 ... -31:最高優先度] ID iaffinity; // 割込みハンドラの初期割付けプロセッサ uint_t affinity_mask; // 割込みハンドラの割付け可能プロセッサ } INTINIB; const INTINIB _kernel_intinib_table[];
メンバー
-
INTNO intno
割込み番号
SOLID-OSにおいては割込み番号はBSPにおけるIRQ番号に一致します。
-
ATR inhatr
割込みハンドラ属性
指定可能な属性はありません。常に
TA_NULL
をセットしてください。
-
FP inthdr
割込みハンドラの出入口処理の番地
- 割込みサービスルーチン(ISR)を使用する場合
マクロ
INTINI_USE_ISR
を指定します。- 割込みハンドラを使用する場合
ハンドラ関数のアドレスを指定します。関数型は以下の通りです。
void interrupt_handler(void);
注釈
割込みサービスルーチンと割込みハンドラでは関数型が異なります。
-
ATR intatr
割込み属性
以下の属性を論理和で指定できます。何も指定がない場合にはTA_NULLをセットします。
TA_ENAINT
割込み要求禁止フラグをクリア
TA_EDGE
エッジトリガ
TA_EDGEを指定しない場合(bit1が0)はレベルトリガ設定として扱われます。
-
PRI intpri
割込み優先度
-1 (
TMAX_INTPRI
, 最低優先度) から-31 (TNIN_INTPRI
, 最高優先度) の範囲で優先度を指定します。 ここで指定された値はCore Serviceを介して割込みコントローラの優先度に反映されます。 割込み優先度はTIPM_ENALL
(0) を含めた32段階固定となっており、TMAX_INTPRI
(-1) が割込みコントローラのサポートする最も低い優先度に 一致する様に定義されます。(以降、TOPPERS優先度が-1するごとに優先度が高くなります)割込みコントローラがサポートする割り込み優先度レベル数が32に満たない場合に
intpri
でコントローラの上限を超える優先度を指定した場合には カーネル内部でコントローラがサポートする最高優先度に置き換えて 割込みハンドラの登録を行います。(エラーとはなりません)
-
ID iaffinity
割込みハンドラの初期割付けプロセッサID(1...)
-
uint_t affinity_mask
割込みハンドラの割付け可能プロセッサ
割込みハンドラを割り付け可能なプロセッサをビットマスクで指定します。 最下位ビット (プロセッサID 1) を起点とし、各ビット位置がプロセッサに対応します。 プロセッサIDに対応するビット (
1 << プロセッサID - 1
) をセットすることで割り付け可能となります。メンバ
affnitiy_mask
の設定には以下のマクロが使用可能です。 (直接値を記述しても問題はありません)-
CFG_PROC_MASK(prcid)
指定プロセッサの対応ビットを返す
- パラメータ:
prcid (ID) -- プロセッサID(1...)
-
CFG_PROC_MASK_ANY
指定可能なすべてのプロセッサの対応ビットを返す
iaffinity
,affinity_mask
の両方を初期化するマクロも使用可能です。-
CFG_TASK_AFFINITY(prcid, affinity_mask)
タスク初期化ブロック中のプロセッサ情報 (
iaffinity
,affinity_mask
) を 初期化するためのマクロ- パラメータ:
prcid -- 初期状態でタスクが動作するプロセッサID(1...)
affinity_mask --
タスクが動作可能なプロセッサをビットマスクで指定 符号なし整数 (
uint_t
型) で直接値を指定するか、 以下のマクロを使用して設定してください [複数の場合は論理和で指定]CFG_PROC_MASK
(プロセッサID)
-
CFG_PROC_MASK(prcid)
注釈
使用する割込み番号が重複した場合は先着優先(先に記述された定義が優先)となり無視されます。また、タイマ割込みなどカーネルやCore Serviceで使用する割込みを指定した場合も同様です。予約されている割込みはボード毎に異なりますので 予約されている割込み で確認してください。
動的生成機能拡張カーネルを使用してacre_isrを利用する場合でも割込み初期化設定ブロックにおいて対象となる割込み番号が割込みサービスルーチンを使用するための設定で登録されている必要があります。
コード例
#define INTNO_SGI1 1 // 割込み番号1(レベルトリガ) #define INTNO_SGI2 2 // 割込み番号2(レベルトリガ) #define INTNO_EDGE3 3 // 割込み番号3(エッジトリガ) #define INTNO_EDGE4 4 // 割込み番号4(エッジトリガ) #define INTNO_17_2 17 // 割込み番号17 extern void int_handler_sgi2(void); extern void int_handler_int17(void); extern void int_handler_edge_triggered(void); const INTINIB _kernel_intinib_table[] = { // IRQ1 <- 最低優先度、レベルトリガ, ISRを使用, プロセッサ1のみ {INTNO_SGI1, TA_NULL, INTINI_USE_ISR, TA_NULL, (-1), 1, 1}, // IRQ2 <- 最高優先度、レベルトリガ, 直接割込みハンドラ関数を登録, 登録時から割り込み許可 {INTNO_SGI2, TA_NULL, int_handler_sgi2, TA_ENAINT, (-31), 1, 1}, // IRQ3 <- 最低優先度、エッジトリガ {INTNO_EDGE3, TA_NULL, int_handler_edge_triggered, TA_EDGE, (-1), 1, 1}, // IRQ4 <- 最高優先度, エッジトリガ, 登録時から割り込み許可 {INTNO_EDGE4, TA_NULL, int_handler_edge_triggered, (TA_EDGE|TA_ENAINT), (-31), 1, 1}, // IRQ17 <- 最高優先度、直接割込みハンドラ関数を登録, 初期時はプロセッサ2に割り当て、 // 他のすべてのプロセッサに割り付け可能 {INTNO_17_2, TA_NULL, int_handler_int17, TA_NULL, (-31), 2, CFG_PROC_MASK_ANY}, };
割込みサービスルーチン(ISR)初期化ブロック
-
struct t_cisr
説明
割込みサービスルーチンの登録を行います。 使用する割込みについては割込み初期化設定ブロックにおいて割込みサービスルーチンを使用するための設定で登録されている必要があります。
定義
typedef struct t_cisr { ATR isratr; // 割込みサービスルーチン属性 intptr_t exinf; // 割込みサービスルーチンの拡張情報 INTNO intno; // 割込みサービスルーチンを登録する割込み番号 ISR isr; // 割込みサービスルーチンの先頭番地->関数型:void (foo)(intptr_t); PRI isrpri; // 割込みサービスルーチン優先度 [1:最高優先度 ... 16:最低優先度] } T_CISR; const T_CISR _kernel_isrini_cfg_table[];
メンバー
-
ATR isratr
割込みサービスルーチン属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
INTNO intno
割込みサービスルーチンを登録する割込み番号
割込み初期化設定ブロックで登録した割込み番号を設定します。該当する割込みについて割込み初期化設定ブロックのメンバ
inthdr
にINTINI_USE_ISR
が指定されている必要があります。
-
ISR isr
割込みサービスルーチンの先頭番地
typedef void (*ISR)(intptr_t exinf);
注釈
割込みサービスルーチンと割込みハンドラでは関数型が異なります。
-
PRI isrpri
割込みサービスルーチン優先度
1(最高優先度)から16(最低優先度)の範囲で優先度を指定します。 ここで指定された値はカーネル内で割込みサービスルーチン間の優先順位を判定するためにのみ使用されます。 (割込みコントローラの設定には反映されません)
コード例
#define INTNO_SGI1 1 // 割込み番号1 // // 割込み初期化ブロック // const INTINIB _kernel_intinib_table[] = { {INTNO_SGI1, TA_NULL, INTINI_USE_ISR, TA_NULL, (-1), 1, 1}, // IRQ1 <- 最低優先度、ISRを使用 ... }; #define ISRPRI_HIGH_PRIORITY 1 // 高優先度 #define ISRPRI_MID_PRIORITY 10 // 中優先度 #define ISRPRI_LOW_PRIORITY 16 // 低優先度 extern void isr_high_handler(intptr_t exinf); extern void isr_mid_handler(intptr_t exinf); extern void isr_low_handler(intptr_t exinf); // // 割込みサービルルーチン初期化ブロック // const T_CISR _kernel_isrini_cfg_table[] = { {TA_NULL, (intptr_t)1, INTNO_SGI1, isr_mid_handler, ISRPRI_MID_PRIORITY}, // 中優先度のISRを登録 {TA_NULL, (intptr_t)2, INTNO_SGI1, isr_low_handler, ISRPRI_LOW_PRIORITY}, // 低優先度のISRを登録 {TA_NULL, (intptr_t)3, INTNO_SGI1, isr_high_handler, ISRPRI_TOP_PRIORITY}, // 高優先度のISRを登録 };
-
ATR isratr
ISR生成順序テーブル
-
const ID _kernel_isrorder_table[]
説明
割込みサービスルーチン生成の順序を設定します。 割込みサービスルーチン(ISR)初期化ブロックに登録したISRに対応するIDを指定してください。
定義
const ID _kernel_isrorder_table[];
注釈
割込みサービスルーチンを生成する順序をIDで指定します。指定する数は割込みサービスルーチン初期化ブロックに記述された数と必ず一致する必要があります。 一致しない場合のカーネルの動作は保証されません。 このテーブルでの指定の順序に関わらず各割込みサービスルーチンのIDは割込みサービスルーチン初期化テーブルでの並びで決まります。
コード例
/* * 割込みサービスルーチンIDの定数定義 */ #define ISR1 1 #define ISR2 2 #define ISR3 3 const ID _kernel_isrorder_table[] = { ISR3, ISR1, ISR2 };
この例の場合、
ISR3
→ISR1
→ISR2
の順序で割込みサービスルーチン生成処理が行われます。
ユーザ初期化関数の呼出し
-
void _kernel_call_inirtn(void)
説明
カーネル起動時にタスクの起動、ディスパッチを開始する前に呼び出されます。 タスクが動作する前に行っておく処理がある場合に必要な処理があれば記述してください。 この関数から復帰するまでタスクは開始されません。
定義
void _kernel_call_inirtn(void) { /* ... ここにユーザ実装の初期化処理を記述 */ __SOLID_SYS_INTRTN(); /* このマクロは削除しないでください */ }
ユーザ終了処理関数の呼出し
-
void _kernel_call_terrtn(void)
説明
カーネルが終了したタイミングで呼び出されます。 必要な処理があれば記述してください。 この関数が呼び出された時点ではすべてのタスク及びカーネルの動作は 終了しているため、終了処理の中でサービスコールなどのカーネルの機能を使うことはできません。
定義
void _kernel_call_terrtn(void) { /* ... ここにユーザ実装の終了処理を記述 */ __SOLID_SYS_TERRTN(); /* このマクロは削除しないでください */ }
動的生成される資源の上限数設定(動的資源生成カーネルのみ)
/*
* 動的に生成するカーネル資源の数を定義
* (静的なテーブルで定義される資源に追加して動的に
* 生成できる資源数を定義
*/
#define TNUM_AID_TSK 0
#define TNUM_AID_SEM 0
#define TNUM_AID_FLG 0
#define TNUM_AID_DTQ 0
#define TNUM_AID_PDQ 0
#define TNUM_AID_MTX 0
#define TNUM_AID_MPF 0
#define TNUM_AID_CYC 0
#define TNUM_AID_ALM 0
#define TNUM_AID_ISR 0
各資源ごとに動的生成可能な上限数を定義します。
ここで定義した数を超えて資源を生成するAPI(acre_*)を呼び出した場合、E_NOID
(ID番号不足) が返されます。
定義を省略した場合の値は0となります。
ここで定義される資源数には静的に生成される資源は含まれません。 例えば、テーブル定義で3つのタスクを定義し、さらにTNUM_AID(3)を定義した場合には合計で最大6つのタスクが生成できることになります。
各定数と資源の対応は以下の通りです。
定数名 |
資源名称 |
---|---|
TNUM_AID_TSK |
タスク |
TNUM_AID_SEM |
セマフォ |
TNUM_AID_FLG |
イベントフラグ |
TNUM_AID_DTQ |
データキュー |
TNUM_AID_PDQ |
優先度データキュー |
TNUM_AID_MTX |
ミューテックス |
TNUM_AID_MPF |
固定長メモリプール |
TNUM_AID_CYC |
周期通知 |
TNUM_AID_ALM |
アラーム通知 |
TNUM_AID_ISR |
ISR(割込みサービスルーチン) |
注釈
動的生成カーネルでない場合にはこれらの定義は無視されます。
起動要求キューイング数/起床要求キューイング数の設定(optional)
/*
* タスクの起動要求キューと起床要求キューの最大数を定義
* (optional)
*
* TMAX_ACT_QUEUE/TMAX_WUP_QUEUEを定義すると起動要求(act_tsk)
* 起床要求(wup_tsk)がキューイングされる数を設定できます。
* 未定義の場合のでデフォルト値はいずれもUINT32_MAXです。
*/
#define TMAX_ACT_QUEUE 50 /* 設定例 */
#define TMAX_WUP_QUEUE 50 /* 設定例 */
act_tsk()
によるタスク起動要求と wup_tsk()
による起床要求がキューイングされる数を定義します。
(通常はコメントアウトされています)
各定数とキューの対応は以下の通りです。
定数名 |
キュー名称 |
未定義の場合のデフォルト値 |
---|---|---|
TMAX_ACT_QUEUE |
起動要求キューイング数 (0~ |
|
TMAX_WUP_QUEUE |
起床要求キューイング数 (0~ |
|
注釈
TOPPERSリリースの実装ではキューイング数はそれぞれ1固定ですが、SOLIDでは上記の通り拡張しています。
設定ファイルの編集 (FMP3)
SOLID-IDEを使用してアプリケーションの新規作成を行うとアプリケーションのスケルトンコードの他に以下の二つのファイルがアプリケーションと同じフォルダに生成されます。以下のファイルを編集し、ビルドすることでカーネル資源の設定を行います。
kernel_cfg.c
カーネルが起動時に生成する各資源の数や属性等のパラメータを記述したテーブルを定義します。ビルド時にアプリケーションと同時にビルドされ、カーネルとリンクされます。
kernel_cfg.h
静的生成される各資源のID (数値) をC言語の定数 (
enum
列挙子) として定義し、アプリケーションコードから資源を参照するための名前を対応付けます。カーネル内部では各資源のIDしか扱わないので、定数の定義は必須ではありません。kernel_cfg.c
からincludeされるので、IDの他にアプリケーションとkernel_cfg.c
との間で共有する定義を記述する目的にも使えます。
注釈
タスクやセマフォなどのIDで管理される資源のうち、静的に生成されるものについては kernel_cfg.c
で定義した初期化ブロック内の順序でIDが割り当てられます。(最初の要素が ID 1
となり、残りは順番にIDが割り振られます。)
警告
ネットワーク機能を利用する場合、kernel_cfg.c
の中にある下記の定義を削除しないでください。
__SOLID_RESERVED_TASKS__
__SOLID_RESERVED_TASK_ORDER__
__SOLID_RESERVED_SEMS__
__SOLID_RESERVED_DTQS__
__SOLID_SYS_INTRTN
__SOLID_SYS_TERRTN
ネットワークを利用する場合の設定にてついてはネットワークの項の カーネル資源設定について も参照してください。
タスク初期化ブロック
-
typedef struct task_initialization_block TINIB
-
struct task_initialization_block
説明
タスク生成時の初期化情報を設定します。
定義
typedef struct task_initialization_block { ATR tskatr; // タスク属性 intptr_t exinf; // タスクの拡張情報 TASK task; // タスクの起動番地 uint_t ipriority; // タスクの起動時優先度(内部表現) size_t stksz; // スタック領域のサイズ(丸めた値) void *stk; // スタック領域の先頭番地 ID iprcid; // タスクの初期割付けプロセッサ (1...) uint_t affinity; // タスクの割付け可能プロセッサ (bitmask) } TINIB; const TINIB _kernel_tinib_table[];
メンバー
-
ATR tskatr
タスク属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_ACT
タスクの生成時にタスクを起動する
TA_NOACTQUE
タスクに対する起動要求をキューイングしない
TA_RSTR
生成するタスクを制約タスクとする
-
intptr_t exinf
タスクの拡張情報
タスクが起動されるときの引数を指定します。(任意)
-
TASK task
タスクの起動番地
タスクの起動番地をC言語の関数アドレスで指定します。 関数型は以下の通りです。
typedef void (*TASK)(intptr_t exinf);
-
uint_t ipriority
タスクの起動時優先度(内部表現)
カーネル内部表現で指定する必要があるため、マクロ
INT_PRIORITY
を使用してください。INT_PRIORITY(1)
が最高優先度、INT_PRIORITY(16)
(優先度拡張なし) またはINT_PRIORITY(256)
(優先度拡張あり) が最低優先度です。
-
size_t stksz
スタック領域のサイズ(丸めた値)
-
void *stk
スタック領域の先頭番地
-
ID iprcid
タスクの初期割り付けプロセッサ
-
uint_t affinity
タスクの割り付け可能プロセッサ
タスクを割り付け可能なプロセッサをビットマスクで指定します。 最下位ビット (プロセッサID 1) を起点とし、各ビット位置がプロセッサに対応します。 プロセッサIDに対応するビット (
1 << プロセッサID - 1
) をセットすることで割り付け可能となります。例: プロセッサID1, 3, 4で割り付け可能とする場合
.affinity = 0xd, // (= 0b1101)
符号なし整数 (
uint_t
型) で直接値を指定するか、以下のマクロを使用して設定してください。CFG_PROC_MASK
(プロセッサID)
CFG_PROC_MASK_ANY
iprcid
,affinity
の両方を初期化するマクロ:CFG_TASK_AFFINITY
(初期割付けプロセッサID, 割付け可能プロセッサビットマスク)
注釈
このテーブル内に記述された順序に沿ってタスクIDが
1
(TMIN_TSKID
) から割り振られます。stk
がNULLの場合、カーネルは自動的にstksz
で指定された領域を確保してタスクに割り当てます。ユーザが確保した領域(変数)をスタックとして使用したい場合にはその領域のアドレスをstk
に指定しますがその場合は以下の点に注意してくださいコード例
#define STACK_SIZE 2048 extern void task1(void *); extern void task2(void *); static STK_T _stack_TASK1[COUNT_STK_T(STACK_SIZE)]; const TINIB _kernel_tinib_table[] = { // 生成時に起動(TA_ACT), スタック領域のアドレスを指定 (スタックフェンス機能 有効) // 初期時にプロセッサID 1(core 0)で起動し、プロセッサID 1または2で動作可能 <マクロを使わずに直値で記述例> { (TA_ACT), 0, ((TASK)(root_task)), INT_PRIORITY(MID_PRIORITY), ROUND_STK_T(STACK_SIZE), _kernel_stack_ROOT_TASK, CFG_TASK_AFFINITY(1, CFG_PROC_MASK_ANY) }, // 生成時には起動しない, スタックをカーネル内で確保(スタックフェンス機能 有効) // 初期時にプロセッサID 1(core 0)で起動し、全てのプロセッサコアでで動作可能 <マクロを使った記述例> { TA_NULL, 0, task2, INT_PRIORITY(HIGH_PRIORITY), ROUND_STK_T(STACK_SIZE), NULL, CFG_TASK_AFFINITY(1, CFG_PROC_MASK_ANY) }, // 生成時には起動しない, スタックをカーネル内で確保(スタックフェンス機能 有効) // 初期時にプロセッサID 3(core 2)で起動し、プロセッサID 1または3で動作可能 <マクロを使った記述例> { TA_NULL, 0, task2, INT_PRIORITY(HIGH_PRIORITY), ROUND_STK_T(STACK_SIZE), NULL, 3, CFG_PROC_MASK(1)|CFG_PROC_MASK(3) }, };
-
ATR tskatr
タスク生成順序テーブル
-
const ID _kernel_torder_table[]
説明
タスク生成の順序を設定します。
定義
const ID _kernel_torder_table[];
注釈
タスクを生成する順序をIDで指定します。指定する数はタスク初期化ブロックに記述された数と必ず一致する必要があります。 一致しない場合のカーネルの動作は保証されません。 このテーブルでの指定の順序に関わらず各タスクのIDはタスク初期化テーブルでの並びで決まります。
コード例
/* * タスクIDの定数定義 */ #define TASK1 1 #define TASK2 2 #define TASK3 3 const ID _kernel_torder_table[] = { TASK3, TASK1, TASK2 };
この例の場合、
TASK3
→TASK1
→TASK2
の順序でタスク生成処理が行われます。
セマフォ初期化ブロック
-
typedef struct semaphore_initialization_block SEMINIB
-
struct semaphore_initialization_block
説明
使用するセマフォの属性を定義します。
定義
typedef struct semaphore_initialization_block { ATR sematr; // セマフォ属性 uint_t isemcnt; // セマフォの資源数の初期値 uint_t maxsem; // セマフォの最大資源数 } SEMINIB; const SEMINIB _kernel_seminib_table[];
メンバー
-
ATR sematr
セマフォ属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
-
uint_t isemcnt
セマフォの資源数の初期値
-
uint_t maxsem
セマフォの最大資源数
コード例
const SEMINIB _kernel_seminib_table[] = { { TA_NULL, 1, 1 }, // 待ち行列=FIFO順, 最大数=1, 初期値=1でセマフォを生成 { TA_TPRI, 0, 1 }, // 待ち行列=タスク優先度順, 最大数=1, 初期値=0でセマフォを生成 };
-
ATR sematr
イベントフラグ初期化ブロック
-
typedef struct eventflag_initialization_block FLGINIB
-
struct eventflag_initialization_block
説明
使用するイベントフラグの属性を定義します。
定義
typedef struct eventflag_initialization_block { ATR flgatr; // イベントフラグ属性 FLGPTN iflgptn; // イベントフラグのビットパターンの初期値 } FLGINIB; const FLGINIB _kernel_flginib_table[];
メンバー
-
ATR flgatr
イベントフラグ属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_WMUL
複数のタスクが待つのを許す
TA_CLR
タスクの待ち解除時にイベントフラグの全てのビットをクリアする
TA_BITCLR
タスクの待ち解除時にイベントフラグの待ち対象ビットのみをクリアする
-
FLGPTN iflgptn
イベントフラグのビットパターンの初期値
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。注釈
TA_CLR
/TA_BITCLR
によるビットクリア動作についてはTOPPERSリリースとの相違点の項の イベントフラグ待ち解除時のクリア方法指定 を参照してください。コード例
const FLGINIB _kernel_flginib_table[] = { { TA_NULL, 0x00 }, // 複数タスク待ち不可, 待ち行列=FIFO順, フラグ初期値=0 { TA_CLR, 0x01 }, // 複数タスク待ち不可, 待ち行列=FIFO順, 待ち解除時にフラグクリア, フラグ初期値=1 { (TA_WMUL|TA_CLR), 0x00 }, // 複数タスク待ち許可, 待ち行列=FIFO順, 待ち解除時にフラグクリア, フラグ初期値=0 { (TA_WMUL|TA_TPRI), 0x00 }, // 複数タスク待ち許可, 待ち行列=タスク優先度順, フラグ初期値=0 };
-
ATR flgatr
データキュー初期化ブロック
-
typedef struct dataqueue_initialization_block DTQINIB
-
struct dataqueue_initialization_block
説明
使用するデータキューの属性を定義します。
定義
typedef struct dataqueue_initialization_block { ATR dtqatr; // データキュー属性 uint_t dtqcnt; // データキューの容量 DTQMB *p_dtqmb; // データキュー管理領域の先頭番地 } DTQINIB; const DTQINIB _kernel_dtqinib_table[];
メンバー
-
ATR dtqatr
データキュー属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
送信 待ち行列をタスクの優先度順にする (受信待ち行列は常にFIFO順)
-
uint_t dtqcnt
データキューの容量
-
DTQMB *p_dtqmb
データキュー管理領域の先頭番地
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。注釈
p_dtqmb
がNULLの場合、カーネルは自動的にdtqcnt
で指定された容量に対して必要な管理領域を確保してデータキューに割り当てます。 ユーザが確保した領域をデータキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、p_dtqmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
-
TSZ_DTQMB(dtqcnt)
dtqcntで指定した数のデータを格納できるデータキュー管理領域のサイズ(バイト数)
コード例
static MB_T _kernel_dtqmb_DTQ3[TCNT_DTQMB(2)]; const DTQINIB _kernel_dtqinib_table[] = { { TA_NULL, 2, NULL }, // 待ち行列=FIFO順, 容量=2 { TA_NULL, 0, NULL }, // 待ち行列=FIFO順, 容量=0 { TA_TPRI, 2, _kernel_dtqmb_DTQ3 }, // 待ち行列=タスク優先度順, 容量=2, 管理領域を指定 };
-
ATR dtqatr
優先度データキュー初期化ブロック
-
typedef struct pridataq_initialization_block PDQINIB
-
struct pridataq_initialization_block
説明
使用する優先度データキューの属性を定義します。
定義
typedef struct pridataq_initialization_block { ATR pdqatr; // 優先度データキュー属性 uint_t pdqcnt; // 優先度データキューの容量 PRI maxdpri; // データ優先度の最大値 PDQMB *p_pdqmb; // 優先度データキュー管理領域の先頭番地 } PDQINIB; const PDQINIB _kernel_pdqinib_table[];
メンバー
-
ATR pdqatr
優先度データキュー属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
送信 待ち行列をタスクの優先度順にする (受信待ち行列は常にFIFO順)
-
uint_t pdqcnt
優先度データキューの容量
-
PRI maxdpri
データ優先度の最大値
TMIN_DPRI
(1, 最高優先度) からTMAX_DPRI
(16)の範囲で指定可能です
-
PDQMB *p_pdqmb
優先度データキュー管理領域の先頭番地
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。注釈
TA_TPRIを指定した場合のデータ優先度とタスク優先度の関係、動作についてはTOPPERS第3世代カーネル(ITRON系)統合仕様書の4.4.4 優先度データキューの「使用上の注意」を参照してください。
p_pdqmb
がNULLの場合、カーネルは自動的にpdqcnt
で指定された容量に対して必要な管理領域を確保して優先度データキューに割り当てます。 ユーザが確保した領域を優先度データキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、p_pdqmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
-
TSZ_PDQMB(pdqcnt)
pdqcntで指定した数のデータを格納できる優先度データキュー管理領域のサイズ(バイト数)
コード例
static MB_T _kernel_pdqmb_PDQ3[TCNT_PDQMB(2)]; const PDQINIB _kernel_pdqinib_table[] = { { TA_NULL, 2, TMAX_DPRI, NULL }, // 送信待ち行列=FIFO順, データ優先度=最大(最低) { TA_NULL, 0, 8, NULL }, // 送信待ち行列=FIFO順、容量=0 { TA_TPRI, 2, TMAX_DPRI, _kernel_pdqmb_PDQ3 }, // 送信待ち行列=タスク優先度順, 管理領域を指定 };
-
ATR pdqatr
メールボックス初期化ブロック
-
typedef struct mailbox_initialization_block MBXINIB
-
struct mailbox_initialization_block
説明
使用するメールボックスの属性を定義します。
定義
typedef struct mailbox_initialization_block { ATR mbxatr; // メールボックス属性 PRI maxmpri; // メッセージ優先度の最大値 } MBXINIB; const MBXINIB _kernel_mbxinib_table[];
メンバー
-
ATR mbxatr
メールボックス属性
以下の属性を指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_MPRI
待ち行列をメッセージの優先度順にする
-
PRI maxmpri
メールボックス優先度の最大値
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。コード例
const MBXINIB _kernel_mbxinib_table[] = { { TA_TPRI, 8}, // 受信待ち行列=タスク優先度順 { TA_MPRI, TMAX_MPRI}, // 受信待ち行列=メッセージ優先度順 };
-
ATR mbxatr
ミューテックス初期化ブロック
-
typedef struct mutex_initialization_block MTXINIB
-
struct mutex_initialization_block
説明
使用するミューテックスの属性を定義します。
定義
typedef struct mutex_initialization_block { ATR mtxatr; // ミューテックス属性 uint_t ceilpri; // ミューテックスの上限優先度(内部表現) } MTXINIB; const MTXINIB _kernel_mtxinib_table[];
メンバー
-
ATR mtxatr
ミューテックス属性
以下の属性を指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_TPRI
待ち行列をタスクの優先度順にする
TA_CEILING
優先度上限ミューテックスとする。待ち行列をタスクの優先度順にする
TA_INHERIT
優先度継承ミューテックス (SOLID-OS拡張) とする。待ち行列をタスクの優先度順にする
-
uint_t ceilpri
ミューテックスの上限優先度(内部表現)
カーネル内部表現で指定する必要があるため、マクロ
INT_PRIORITY
を使用してください。INT_PRIORITY(1)
が最高優先度、INT_PRIORITY(16)
(優先度拡張なし) またはINT_PRIORITY(256)
(優先度拡張あり) が最低優先度です。TA_CEILING
が指定された場合のみ有効です。
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。注釈
優先度上限ミューテックスの動作についてはTOPPERS第3世代カーネル(ITRON系)統合仕様書の4.4.5 ミューテックスの「使用上の注意」を参照してください。
コード例
const MTXINIB _kernel_mtxinib_table[] = { { TA_TPRI, INT_PRIORITY(0) }, // ロック待ち行列=タスク優先度順, (ceilpriは無効) { TA_CEILING, INT_PRIORITY(8) }, // 優先度上限ミューテックス(待ち行列=タスク優先度順), 上限優先度 = 8 { TA_INHERIT, 0 }, // 優先度上限ミューテックス(待ち行列=タスク優先度順), (ceilpriは無効) };
-
ATR mtxatr
メッセージバッファ初期化ブロック
-
typedef struct messagebuf_initialization_block MBFINIB
-
struct messagebuf_initialization_block
説明
使用するメッセージバッファの属性を定義します。
定義
typedef struct messagebuf_initialization_block { ATR mbfatr; // メッセージバッファ属性 uint_t maxmsz; // メッセージの最大長(バイト数) size_t mbfsz; // メッセージバッファ管理領域のサイズ(バイト数) void *mbfmb; // メッセージバッファ管理領域の先頭番地 } MBFINIB; const MBFINIB _kernel_mbfinib_table[];
メンバー
-
ATR mbfatr
メッセージバッファ属性
メッセージバッファで指定可能な属性はないため、
TA_NULL
をセットします。
-
uint_t maxmsz
メッセージの最大長
メッセージ最大長をバイト数で指定します
-
size_t mbfsz
メッセージバッファ管理領域のサイズ
メッセージバッファ管理領域のサイズをバイト数で指定します
-
void *mbfmb
メッセージバッファ管理領域の先頭番地
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。注釈
mbfmb
がNULLの場合、カーネルは自動的にmbfsz
で指定された容量に対して必要な管理領域を確保してデータキューに割り当てます。 ユーザが確保した領域をデータキュー管理領域として使用する場合、管理領域して使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制約があるため、mbfmb
が指す領域(変数)については以下のデータ型とマクロを使用して宣言してください。-
type MB_T
管理領域のデータ型
-
TSZ_MBFMB(msgcnt, msgsz)
msgszで指定したサイズのメッセージを,msgcntで指定した数だけ格納できるメッセージバッファ管理領域のサイズ(バイト数)
-
TCNT_MBFMB(msgcnt, msgsz)
msgszで指定したサイズのメッセージを,msgcntで指定した数だけ格納できるメッセージバッファ管理領域を確保するために必要なMB_T型の配列の要素数
コード例
#define MBF3_MSGSZ 50 #define MBF3_MSGCNT 100 static MB_T _kernel_mbfmb_MBF3[TCNT_MBFMB(MBF3_MSGCNT, MBF3_MSGSZ)]; const MBFINIB _kernel_mbfinib_table[] = { // 最大メッセージサイズ=16, 管理領域 =32バイト { TA_NULL, 16, 32, NULL }, // 最大メッセージサイズ=8, 管理領域=maxmsz * 16個分 { TA_NULL, 8, TSZ_MBFMB(16, 8), NULL }, // 最大メッセージサイズ=50, 管理領域=maxmsz * 100個分 { TA_NULL, MBF3_MSGSZ, TSZ_MBFMB(MBF3_MSGCNT, MBF3_MSGSZ), _kernel_mbfmb_MBF3 }, };
-
ATR mbfatr
固定長メモリプール初期化ブロック
-
typedef struct fixed_memorypool_initialization_block MPFINIB
-
struct fixed_memorypool_initialization_block
説明
使用する固定長メモリプール初期化ブロックの属性を定義します。
定義
typedef struct fixed_memorypool_initialization_block { ATR mpfatr; // 固定長メモリプール属性 uint_t blkcnt; // メモリブロック数 uint_t blksz; // メモリブロックのサイズ(丸めた値) void *mpf; // 固定長メモリプール領域の先頭番地 MPFMB *p_mpfmb; // 固定長メモリプール管理領域の先頭番地 } MPFINIB; const MPFINIB _kernel_mpfinib_table[];
メンバー
-
ATR mpfatr
固定長メモリプール属性
TA_TPRI
待ち行列をタスクの優先度順にする
-
uint_t blkcnt
メモリブロック数
-
uint_t blksz
メモリブロックのサイズ(丸めた値)
-
void *mpf
固定長メモリプール領域の先頭番地
-
MPFMB *p_mpfmb
固定長メモリプール管理領域の先頭番地
注釈
FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では
CFG_OBJ_ATTR
マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c
の中で使用されていても修正の必要はありません。注釈
mpf
及びp_mpfmb
にNULLを指定した場合はカーネル内部で必要なメモリ領域の確保が行われます。固定長メモリプール領域、固定長メモリプール管理領域として使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるためそれぞれ以下のマクロを使用して宣言してください。
コード例
#define MPF_BLOCK_SIZE 64 #define NUM_BLOCKS_MPF1 1 #define NUM_BLOCKS_MPF2 2 #define NUM_BLOCKS_MPF3 1 #define NUM_BLOCKS_MPF4 1 static MPF_T _pool1[ NUM_BLOCKS_MPF1 * COUNT_MPF_T(MPF_BLOCK_SIZE) ]; static MPF_T _pool4[ NUM_BLOCKS_MPF2 * COUNT_MPF_T(MPF_BLOCK_SIZE) ]; static MB_T _mpfmb2[TCNT_MPFMB(NUM_BLOCKS_MPF2)]; static MB_T _mpfmb4[TCNT_MPFMB(NUM_BLOCKS_MPF4)]; const MPFINIB _kernel_mpfinib_table[] = { { TA_NULL, NUM_BLOCKS_MPF1, ROUND_MPF_T(MPF_BLOCK_SIZE), _pool1, NULL }, // データ領域を静的変数で確保 { TA_NULL, NUM_BLOCKS_MPF2, ROUND_MPF_T(MPF_BLOCK_SIZE), NULL, (MPFMB*)_mpfmb2 }, // 管理領域を静的変数で確保 { TA_TPRI, NUM_BLOCKS_MPF3, ROUND_MPF_T(1), NULL, NULL }, // 待ち行列=タスク優先度順 { TA_NULL, NUM_BLOCKS_MPF4, ROUND_MPF_T(MPF_BLOCK_SIZE), _pool4, (MPFMB*)_mpfmb4 }, // すべての領域を静的変数で確保 };
-
ATR mpfatr
周期通知/アラーム通知初期化ブロック中のプロセッサ情報を初期化するためのマクロ
-
CFG_SYSTIM_AFFINITY(prcid, affinity_mask)
周期通知/アラーム通知初期化ブロック中のプロセッサ情報 (
iprcid
,affinity
) を初期化します- パラメータ:
prcid -- 初期状態で通知処理が動作するプロセッサID(1...)
affinity_mask --
通知処理が動作可能なプロセッサをビットマスクで指定 符号なし整数 (
uint_t
型)で直接値を指定するか、 以下のマクロを使用して設定してください [複数の場合は論理和で指定]CFG_PROC_MASK
(プロセッサID)
CFG_PROC_MASK_ANY
注釈
コンパイル時にプリプロセッサ定数 TOPPERS_SYSTIM_LOCALが定義されていない場合は本マクロの定義は空になります。
この場合、
prcid
の値に関わらず通知ハンドラは、すべて一つのプロセッサ(タイマ管理プロセッサ)上で動作することになります。
周期通知初期化ブロック
-
typedef struct cyclic_handler_initialization_block CYCINIB
-
struct cyclic_handler_initialization_block
説明
使用する周期通知の属性と処理を定義します。
定義
typedef struct cyclic_handler_initialization_block { ATR cycatr; // 周期通知属性 intptr_t exinf; // 通知ハンドラの拡張情報 NFYHDR nfyhdr; // 通知ハンドラの起動番地 RELTIM cyctim; // 周期通知の起動周期 RELTIM cycphs; // 周期通知の起動位相 ID iprcid; // 周期ハンドラの初期割付けプロセッサ(ローカルタイマ方式の場合のみ) uint_t affinity; // 周期ハンドラの割付け可能プロセッサ(ローカルタイマ方式の場合のみ) } CYCINIB; const CYCINIB _kernel_cycinib_table[];
メンバー
-
ATR cycatr
周期通知属性
以下の属性を論理和(or)で指定できます。何も指定がない場合には
TA_NULL
をセットします。TA_STA
周期通知の生成時に周期通知を動作開始する
-
intptr_t exinf
通知ハンドラの拡張情報
通知ハンドラが起動されるときの引数を指定します。(任意)
-
NFYHDR nfyhdr
通知ハンドラの起動番地
通知ハンドラの起動番地をC言語の関数アドレスで指定します。 関数型は以下の通りです。
typedef void (*NFYHDR)(intptr_t exinf);
-
RELTIM cyctim
周期通知の起動周期(単位:μsec)
-
RELTIM cycphs
周期通知の起動位相(単位:μsec)
-
ID iprcid
周期ハンドラの初期割付けプロセッサ
-
uint_t affinity
周期ハンドラの割付可能プロセッサ
注釈
メンバ
iprcid
と メンバaffinity
はマクロCFG_SYSTIM_AFFINITY
を使用して記述してください。コード例
#define CYC1_CYCLE 100U // 100μsec #define CYC2_CYCLE 1000U // 1msec extern void cyc_func(intptr_t exinf); const CYCINIB _kernel_cycinib_table[] = { // // 生成と同時に100μsec間隔でcyc_funcを呼び出す(プロセッサID 1で動作開始、すべてのプロセッサに移動可能) // { TA_STA, 0, cyc_func, CYC1_CYCLE, CYC1_CYCLE, CFG_SYSTIM_AFFINITY(1, CFG_PROC_MASK_ANY) }, // // 停止状態で生成、基準時刻を生成時の時刻に設定と同時に1msec間隔でcyc_funcを呼び出す // プロセッサID 2のみで動作 // { TA_PHS, 0, cyc_func, CYC2_CYCLE, CYC2_CYCLE, CFG_SYSTIM_AFFINITY(2, CFG_PROC_MASK(2)) }, };
-
ATR cycatr
アラーム通知初期化ブロック(FMP互換)
-
typedef struct alarm_handler_initialization_block ALMINIB
-
struct alarm_handler_initialization_block
説明
使用するアラーム通知の属性と処理を定義します。
定義
typedef struct alarm_handler_initialization_block { ATR almatr; // アラームハンドラ属性 intptr_t exinf; // アラームハンドラの拡張情報 NFYHDR nfyhdr; // アラームハンドラの起動番地 ID iprcid; // アラームハンドラの初期割付けプロセッサ uint_t affinity; // アラームハンドラの割付け可能プロセッサ } ALMINIB; const ALMINIB _kernel_alminib_table[];
メンバー
-
ATR almatr
アラーム通知属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
intptr_t exinf
アラームハンドラの拡張情報
アラームハンドラが起動されるときの引数を指定します。(任意)
-
NFYHDR nfyhdr
アラームハンドラの起動番地
-
ID iprcid
アラームハンドラの初期割付けプロセッサ
-
uint_t affinity
アラームハンドラの割付け可能プロセッサ
注釈
メンバ
iprcid
と メンバaffinity
はマクロCFG_SYSTIM_AFFINITY
を使用して記述してください。コード例
extern void alarmHandler(intptr_t exinf); const ALMINIB _kernel_alminib_table[] = { // 通知時に関数 alarmHandler が引数0で呼び出される。プロセッサIDは1に固定 { TA_NULL, (intptr_t)0, alarmHandler, CFG_SYSTIM_AFFINITY(1, CFG_PROC_MASK(1)) }, // 通知時に関数 alarmHandler が引数0で呼び出される。 // 実行されるプロセッサIDは初期状態では2, その他のすべてのプロセッサに移動可能 { TA_NULL, (intptr_t)4, alarmHandler, CFG_SYSTIM_AFFINITY(2, CFG_PROC_MASK_ANY) }, };
-
ATR almatr
アラーム通知初期化ブロック(FMP3仕様)
-
typedef struct alarm_handler_nfy_initialization_block ALMINIB_NFY
-
struct alarm_handler_nfy_initialization_block
説明
使用するアラーム通知の属性と処理を定義します。
定義
typedef struct alarm_handler_nfy_initialization_block { ATR almatr; // アラームハンドラ属性 T_NFYINFO nfyinfo; // イベント通知パラメータ構造体 ID iprcid; // 通知ハンドラの初期割付けプロセッサ uint_t affinity; // 通知ハンドラの割付け可能プロセッサ } ALMINIB_NFY; const ALMINIB_NFY _kernel_alminib_nfy_table[];
メンバー
-
ATR almatr
アラーム通知属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
T_NFYINFO nfyinfo
通知パラメータ構造体
アラーム通知が発生した場合の通知方法やエラーが起きた場合の処理方法を構造体に設定します。 詳細については 通知パラメータ構造体の設定方法 を参照してください。
-
ID iprcid
通知ハンドラの初期割付けプロセッサ
-
uint_t affinity
通知ハンドラの割付け可能プロセッサ
注釈
メンバ
iprcid
と メンバaffinity
はマクロCFG_SYSTIM_AFFINITY
を使用して記述してください。コード例
(通知パラメータ構造体の設定方法 を参照してください。)
-
ATR almatr
通知パラメータ構造体の設定方法
-
struct T_NFYINFO
説明
アラーム通知などにおいてカーネルからの通知方法を定義・指定します。
定義
typedef struct { MODE nfymode; // 通知処理モード union { // タイムイベントの通知に関する付随情報 T_NFY_COMMON initializer; T_NFY_HDR handler; T_NFY_VAR setvar; T_NFY_IVAR incvar; T_NFY_TSK acttsk; T_NFY_TSK wuptsk; T_NFY_SEM sigsem; T_NFY_FLG setflg; T_NFY_DTQ snddtq; } nfy; union { // エラーの通知に関する付随情報 T_NFY_COMMON initializer; T_ENFY_VAR setvar; T_NFY_IVAR incvar; T_NFY_TSK acttsk; T_NFY_TSK wuptsk; T_NFY_SEM sigsem; T_NFY_FLG setflg; T_ENFY_DTQ snddtq; } enfy; } T_NFYINFO;
メンバー
-
MODE nfymode
通知処理モード
以下の通知種類をエラー通知方法を論理和(or)で指定します。
通知の種類
TNFY_HANDLER
タイムイベントハンドラの呼出しによる通知
TNFY_SETVAR
変数の設定による通知
TNFY_INCVAR
変数のインクリメントによる通知
TNFY_ACTTSK
タスクの起動による通知
TNFY_WUPTSK
タスクの起床による通知
TNFY_SIGSEM
セマフォの返却による通知
TNFY_SETFLG
イベントフラグのセットによる通知
TNFY_SNDDTQ
データキューへの送信による通知
エラー通知の種類
TENFY_SETVAR
変数の設定による通知
TENFY_INCVAR
変数のインクリメントによる通知
TENFY_ACTTSK
タスクの起動による通知
TENFY_WUPTSK
タスクの起床による通知
TENFY_SIGSEM
セマフォの返却による通知
TENFY_SETFLG
イベントフラグのセットによる通知
TENFY_SNDDTQ
データキューへの送信による通知
エラー通知が必要無い場合には上記定数を指定する必要はありません。
-
union nfy
タイムイベントの通知に関する付随情報
nfymode
に指定した通知の種類に応じて通知に付随するパラメータを指定します。 本メンバーの設定には以下のマクロを使用してください。nfymode
マクロ名
TNFY_HANDLER
NFY_PARAM_HANDLER
TNFY_SETVAR
NFY_PARAM_SETVAR
TNFY_INCVAR
NFY_PARAM_INCVAR
TNFY_ACTTSK
NFY_PARAM_ACT_TSK
TNFY_WUPTSK
NFY_PARAM_WUP_TSK
TNFY_SIGSEM
NFY_PARAM_SIG_SEM
TNFY_SETFLG
NFY_PARAM_SET_FLG
TNFY_SNDDTQ
NFY_PARAM_SND_DTQ
各マクロのパラメータは以下の通りです。
-
NFY_PARAM_HANDLER(exinf, handler)
- パラメータ:
exinf (intptr_t) -- ハンドラ関数に渡されるパラメータ
handler (TMEHDR) -- ハンドラ関数アドレス (void (*)(intptr_t))
-
NFY_PARAM_SETVAR(p_var, value)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
value (intptr_t) -- 変数に設定するアドレス
-
NFY_PARAM_INCVAR(p_var)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
-
NFY_PARAM_ACT_TSK(tskid)
- パラメータ:
tskid (ID) -- 起動するタスクID
-
NFY_PARAM_WUP_TSK(tskid)
- パラメータ:
tskid (ID) -- 起床させるタスクID
-
NFY_PARAM_SIG_SEM(semid)
- パラメータ:
semid (ID) -- セマフォID
-
NFY_PARAM_SET_FLG(flgid, flgptn)
- パラメータ:
flgid (ID) -- イベントフラグID
flgptn (FLGPTN) -- セットするビットパターン
-
NFY_PARAM_SND_DTQ(dtqid, data)
- パラメータ:
dtqid (ID) -- データキューID
-
NFY_PARAM_HANDLER(exinf, handler)
-
union enfy
エラーの通知に関する付随情報
nfymodeに指定した通知の種類に応じて通知に付随するパラメータを指定します。 本メンバーの設定には以下のマクロを使用してください。
nfymode
マクロ名
TENFY_SETVAR
ERRNFY_PARAM_SETVAR
TENFY_INCVAR
ERRNFY_PARAM_INCVAR
TENFY_ACTTSK
ERRNFY_PARAM_ACT_TSK
TENFY_WUPTSK
ERRNFY_PARAM_WUP_TSK
TENFY_SIGSEM
ERRNFY_PARAM_SIG_SEM
TENFY_SETFLG
ERRNFY_PARAM_SET_FLG
TENFY_SNDDTQ
ERRNFY_PARAM_SND_DTQ
各マクロのパラメータは以下の通りです。
-
ERRNFY_PARAM_SETVAR(p_var)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
value (intptr_t) -- 変数に設定するアドレス
-
ERRNFY_PARAM_INCVAR(p_var)
- パラメータ:
p_var (intptr_t) -- 変数アドレス
-
ERRNFY_PARAM_ACT_TSK(tskid)
- パラメータ:
tskid (ID) -- 起動するタスクID
-
ERRNFY_PARAM_WUP_TSK(tskid)
- パラメータ:
tskid (ID) -- 起床させるタスクID
-
ERRNFY_PARAM_SIG_SEM(semid)
- パラメータ:
semid (ID) -- セマフォID
-
ERRNFY_PARAM_SET_FLG(flgid, flgptn)
- パラメータ:
flgid (ID) -- イベントフラグID
flgptn (FLGPTN) -- セットするビットパターン
-
ERRNFY_PARAM_SND_DTQ(dtqid)
- パラメータ:
dtqid (ID) -- データキューID
-
ERRNFY_PARAM_SETVAR(p_var)
コード例
#define TASK1 1 #define TASK2 2 #define SEM1 1 #define FLG1 1 #define DTQ1 1 extern bool_t event_variable; extern int_t count_variable; extern ER error_variable; const ALMINIB_NFY _kernel_alminib_nfy_table[] = { // 通知時に変数event_variableにtrueを設定、エラー通知なし { TA_NULL, { TNFY_SETVAR, {NFY_PARAM_SETVAR(&event_variable, true)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー通知なし { TA_NULL, { TNFY_ACTTSK, {NFY_PARAM_ACT_TSK(TASK2)} }}, // 通知時にタスク(ID=TASK2)を起床、エラー通知発生時には変数error_variableにエラーを格納する { TA_NULL, { TNFY_WUPTSK|TENFY_SETVAR, {NFY_PARAM_WUP_TSK(TASK2)}, {ERRNFY_PARAM_SETVAR(&error_variable)} }}, // 通知時にセマフォに返却(sig_sem)、エラー通知発生時にはタスク(ID=TASK2)を起床 { TA_NULL, { TNFY_SIGSEM|TENFY_ACTTSK, {NFY_PARAM_SIG_SEM(SEM1)}, {ERRNFY_PARAM_ACT_TSK(TASK2)} }}, // 通知時にイベントフラグをセット(ID FLG1に対し 0x01) { TA_NULL, { TNFY_SETFLG, {NFY_PARAM_SET_FLG(FLG1, 0x01)} }}, // 通知時にデータキューに対しデータ(0x01)を送信、エラーが発生した場合はTASK2を起床させる { TA_NULL, { TNFY_SNDDTQ|TENFY_WUPTSK, {NFY_PARAM_SND_DTQ(DTQ1, 0x01)}, {ERRNFY_PARAM_WUP_TSK(TASK2)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時にはSEM1に対しsig_semを実行する { TA_NULL, { TNFY_ACTTSK|TENFY_SIGSEM, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_SIG_SEM(SEM1)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時にはイベントフラグ FLG1に対し0x02をセット { TA_NULL, { TNFY_ACTTSK|TENFY_SETFLG, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_SET_FLG(FLG1, 0x02)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時にはデータキューに対しエラーコードを送信 { TA_NULL, { TNFY_ACTTSK|TENFY_SNDDTQ, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_SND_DTQ(DTQ1)} }}, // 通知時に変数count_variableをインクリメント、エラー通知なし { TA_NULL, { TNFY_INCVAR, {NFY_PARAM_INCVAR(&count_variable)} }}, // 通知時にタスク(ID=TASK2)を起動、エラー発生時には通知時に変数count_variableをインクリメント { TA_NULL, { TNFY_ACTTSK|TENFY_INCVAR, {NFY_PARAM_ACT_TSK(TASK2)}, {ERRNFY_PARAM_INCVAR(&count_variable)} }}, };
-
MODE nfymode
スピンロック初期化設定ブロック
-
typedef struct spin_lock_initialization_block SPNINIB
-
struct spin_lock_initialization_block
説明
スピンロック初期化ブロックの属性を定義します。
定義
typedef struct spin_lock_initialization_block { ATR spnatr; // スピンロック属性 intptr_t lock; // ロック状態のためのデータ構造 } SPNINIB;
メンバー
-
ATR spnatr
スピンロック属性
常に
TA_NULL
を設定してください
-
intptr_t lock
オブジェクトロックへのポインタ
カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。
注釈
メンバ変数
p_obj_lock
はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。メンバ
spnatr
と メンバp_obj_lock
はマクロCFG_SPN_ATTR
を使用して記述してください。-
CFG_SPN_ATTR(atr, prcid)
スピンロックオブジェクト属性初期化マクロ (FMPカーネルとのソースレベル互換性のために残されています)
#define CFG_SPN_ATTR(atr, prcid) TA_NULL,NULL
-
CFG_SPN_DEFAULT
スピンロック初期化テーブルの記述の固定的なデフォルト値を定義するマクロ
ATR spnatr = TA_NULL; intptr_t lock = NULL;
として初期化テーブル1個分の配列要素を初期値付きで記述します。
注釈
FMP3カーネルではロック方式がジャイアントロック方式のみとなったため、FMPカーネルのプロセッサロック方式の場合にのみ必要なプロセッサIDの指定が不要となりました。このため、FMP3カーネルでは
CFG_SPN_ATTR
マクロのprcid
引数は使用されなくなりましたが、互換性のためにそのまま残されているため、FMP3カーネルへの移行にあたってkernel_cfg.c
の中でこのマクロが使用されていても修正の必要はありません。注釈
カーネルのビルド条件において以下の両方の条件が同時に成立しない場合にはprcidの値は無視されます。
スピンロック方式: エミュレーション方式 (soft,
TTYPE_SPN
==
EMULATE_SPN
)カーネルロック方式: プロセッサロック方式 (proc,
TTYPE_KLOCK
==
P_KLOCK
)
コード例
const SPNINIB _kernel_spninib_table[] = { {TA_NULL, NULL}, // 直接値を記述する場合 CFG_SPN_DEFAULT, // CFG_SPN_DEFAULTマクロを利用して記述 {CFG_SPN_ATTR(TA_NULL, 1)}, // 属性なし, プロセッサID(FMPの旧方式記述) };
-
ATR spnatr
割込み初期化設定ブロック
-
typedef struct interrupt_handler_initialization_block INTINIB
-
struct interrupt_handler_initialization_block
説明
カーネルで扱う割込みについて定義します。 カーネルは起動時にこのテーブルに記述された内容を読込み、Core Serviceに対して必要な設定を行います。 このテーブルに定義されていない割込みはカーネル管理外となり、アプリケーションから扱う事はできなくなります。
割込みの処理を行う関数を登録する方法には以下の二種類があります。
- 割込みサービスルーチン(ISR)
カーネル内部のハンドラを経由します。同一の割込みに対して複数のISRを登録することができ、割込み発生時には設定されて優先度に従ってすべてのISRが呼び出されます。
動的生成機能拡張カーネルの場合は
acre_isr()
の呼び出しによりISRを登録することもできます。 (その場合でも割込み初期化設定ブロックであらかじめ使用する割込みについて定義しておく必要はあります)- 割込みハンドラ
割込み初期化設定ブロックに登録された関数のみが呼び出されます。 カーネルの動的生成機能拡張対応の有無に関わらず動的に登録することはできません。
同一の割込みに対して割込みサービスルーチンと割込みハンドラの両方を同時に使用することはできません。
定義
typedef struct interrupt_handler_initialization_block { INTNO intno; /* 割込み番号 */ ATR inhatr; /* 割込みハンドラ属性 */ FP inthdr; /* 割込みハンドラの出入口処理の番地 (ISR使用時はINTINI_USE_ISRを指定) */ ATR intatr; /* 割込み属性 */ PRI intpri; /* 割込み優先度 [TMIN_INTPRI(最低) ... TMAX_INTPRI(最高)]*/ ID iprcid; /* 割込みの初期割付けプロセッサ */ uint_t affinity; /* 割込みの割付け可能プロセッサ */ } INTINIB; const INTINIB _kernel_intinib_table[];
メンバー
-
INTNO intno
割込み番号
SOLID-OSにおいては割込み番号はBSPにおけるIRQ番号に一致します。
-
ATR inhatr
割込みハンドラ属性
指定可能な属性はありません。常に
TA_NULL
をセットしてください。
-
FP inthdr
割込みハンドラの出入口処理の番地
- 割込みサービスルーチン(ISR)を使用する場合
マクロ
INTINI_USE_ISR
を指定します。- 割込みハンドラを使用する場合
ハンドラ関数のアドレスを指定します。関数型は以下の通りです。
void interrupt_handler(void);
注釈
割込みサービスルーチンと割込みハンドラでは関数型が異なります。
-
ATR intatr
割込み属性
以下の属性を論理和で指定できます。何も指定がない場合にはTA_NULLをセットします。
TA_ENAINT
割込み要求禁止フラグをクリア
TA_EDGE
エッジトリガ
TA_EDGEを指定しない場合(bit1が0)はレベルトリガ設定として扱われます。
-
PRI intpri
割込み優先度
-1 (
TMAX_INTPRI
, 最低優先度) から-31 (TNIN_INTPRI
, 最高優先度) の範囲で優先度を指定します。 ここで指定された値はCore Serviceを介して割込みコントローラの優先度に反映されます。 割込み優先度はTIPM_ENALL
(0) を含めた32段階固定となっており、TMAX_INTPRI
(-1) が割込みコントローラのサポートする最も低い優先度に 一致する様に定義されます。(以降、TOPPERS優先度が-1するごとに優先度が高くなります)割込みコントローラがサポートする割り込み優先度レベル数が32に満たない場合に
intpri
でコントローラの上限を超える優先度を指定した場合には カーネル内部でコントローラがサポートする最高優先度に置き換えて 割込みハンドラの登録を行います。(エラーとはなりません)
-
ID iprcid
割込みハンドラの初期割付けプロセッサID(1...)
-
uint_t affinity
割込みハンドラの割付け可能プロセッサ
割込みハンドラを割り付け可能なプロセッサをビットマスクで指定します。 最下位ビット (プロセッサID 1) を起点とし、各ビット位置がプロセッサに対応します。 プロセッサIDに対応するビット (
1 << プロセッサID - 1
) をセットすることで割り付け可能となります。メンバ
affinity
の設定には以下のマクロが使用可能です。 (直接値を記述しても問題はありません)-
CFG_PROC_MASK(prcid)
指定プロセッサの対応ビットを返す
- パラメータ:
prcid (ID) -- プロセッサID(1...)
-
CFG_PROC_MASK_ANY
指定可能なすべてのプロセッサの対応ビットを返す
iprcid
,affinity
の両方を初期化するマクロも使用可能です。-
CFG_TASK_AFFINITY(prcid, affinity)
- パラメータ:
prcid -- 初期状態でタスクが動作するプロセッサID(1...)
affinity --
タスクが動作可能なプロセッサをビットマスクで指定 符号なし整数 (
uint_t
型) で直接値を指定するか、 以下のマクロを使用して設定してください [複数の場合は論理和で指定]CFG_PROC_MASK
(プロセッサID)
-
CFG_PROC_MASK(prcid)
注釈
使用する割込み番号が重複した場合は先着優先(先に記述された定義が優先)となり無視されます。また、タイマ割込みなどカーネルやCore Serviceで使用する割込みを指定した場合も同様です。予約されている割込みはボード毎に異なりますので 予約されている割込み で確認してください。
動的生成機能拡張カーネルを使用してacre_isrを利用する場合でも割込み初期化設定ブロックにおいて対象となる割込み番号が割込みサービスルーチンを使用するための設定で登録されている必要があります。
コード例
#define INTNO_SGI1 1 // 割込み番号1(レベルトリガ) #define INTNO_SGI2 2 // 割込み番号2(レベルトリガ) #define INTNO_EDGE3 3 // 割込み番号3(エッジトリガ) #define INTNO_EDGE4 4 // 割込み番号4(エッジトリガ) #define INTNO_17_2 17 // 割込み番号17 extern void int_handler_sgi2(void); extern void int_handler_int17(void); extern void int_handler_edge_triggered(void); const INTINIB _kernel_intinib_table[] = { // IRQ1 <- 最低優先度、レベルトリガ, ISRを使用, プロセッサ1のみ {INTNO_SGI1, TA_NULL, INTINI_USE_ISR, TA_NULL, (-1), 1, 1}, // IRQ2 <- 最高優先度、レベルトリガ, 直接割込みハンドラ関数を登録, 登録時から割り込み許可 {INTNO_SGI2, TA_NULL, int_handler_sgi2, TA_ENAINT, (-31), 1, 1}, // IRQ3 <- 最低優先度、エッジトリガ {INTNO_EDGE3, TA_NULL, int_handler_edge_triggered, TA_EDGE, (-1), 1, 1}, // IRQ4 <- 最高優先度, エッジトリガ, 登録時から割り込み許可 {INTNO_EDGE4, TA_NULL, int_handler_edge_triggered, (TA_EDGE|TA_ENAINT), (-31), 1, 1}, // IRQ17 <- 最高優先度、直接割込みハンドラ関数を登録, 初期時はプロセッサ2に割り当て、 // 他のすべてのプロセッサに割り付け可能 {INTNO_17_2, TA_NULL, int_handler_int17, TA_NULL, (-31), 2, CFG_PROC_MASK_ANY}, };
割込みサービスルーチン(ISR)初期化ブロック
-
struct t_cisr
説明
割込みサービスルーチンの登録を行います。 使用する割込みについては割込み初期化設定ブロックにおいて割込みサービスルーチンを使用するための設定で登録されている必要があります。
定義
typedef struct t_cisr { ATR isratr; // 割込みサービスルーチン属性 intptr_t exinf; // 割込みサービスルーチンの拡張情報 INTNO intno; // 割込みサービスルーチンを登録する割込み番号 ISR isr; // 割込みサービスルーチンの先頭番地->関数型:void (foo)(intptr_t); PRI isrpri; // 割込みサービスルーチン優先度 [1:最高優先度 ... 16:最低優先度] } T_CISR; const T_CISR _kernel_isrini_cfg_table[];
メンバー
-
ATR isratr
割込みサービスルーチン属性
指定可能な属性をありません。常に
TA_NULL
をセットしてください。
-
INTNO intno
割込みサービスルーチンを登録する割込み番号
割込み初期化設定ブロックで登録した割込み番号を設定します。該当する割込みについて割込み初期化設定ブロックのメンバ
inthdr
にINTINI_USE_ISR
が指定されている必要があります。
-
ISR isr
割込みサービスルーチンの先頭番地
typedef void (*ISR)(intptr_t exinf);
注釈
割込みサービスルーチンと割込みハンドラでは関数型が異なります。
-
PRI isrpri
割込みサービスルーチン優先度
1(最高優先度)から16(最低優先度)の範囲で優先度を指定します。 ここで指定された値はカーネル内で割込みサービスルーチン間の優先順位を判定するためにのみ使用されます。 (割込みコントローラの設定には反映されません)
コード例
#define INTNO_SGI1 1 // 割込み番号1 // // 割込み初期化ブロック // const INTINIB _kernel_intinib_table[] = { {INTNO_SGI1, TA_NULL, INTINI_USE_ISR, TA_NULL, (-1), 1, 1}, // IRQ1 <- 最低優先度、ISRを使用 ... }; #define ISRPRI_HIGH_PRIORITY 1 // 高優先度 #define ISRPRI_MID_PRIORITY 10 // 中優先度 #define ISRPRI_LOW_PRIORITY 16 // 低優先度 extern void isr_high_handler(intptr_t exinf); extern void isr_mid_handler(intptr_t exinf); extern void isr_low_handler(intptr_t exinf); // // 割込みサービルルーチン初期化ブロック // const T_CISR _kernel_isrini_cfg_table[] = { {TA_NULL, (intptr_t)1, INTNO_SGI1, isr_mid_handler, ISRPRI_MID_PRIORITY}, // 中優先度のISRを登録 {TA_NULL, (intptr_t)2, INTNO_SGI1, isr_low_handler, ISRPRI_LOW_PRIORITY}, // 低優先度のISRを登録 {TA_NULL, (intptr_t)3, INTNO_SGI1, isr_high_handler, ISRPRI_TOP_PRIORITY}, // 高優先度のISRを登録 };
-
ATR isratr
ISR生成順序テーブル
-
const ID _kernel_isrorder_table[]
説明
割込みサービスルーチン生成の順序を設定します。 割込みサービスルーチン(ISR)初期化ブロックに登録したISRに対応するIDを指定してください。
定義
const ID _kernel_isrorder_table[];
注釈
割込みサービスルーチンを生成する順序をIDで指定します。指定する数は割込みサービスルーチン初期化ブロックに記述された数と必ず一致する必要があります。 一致しない場合のカーネルの動作は保証されません。 このテーブルでの指定の順序に関わらず各割込みサービスルーチンのIDは割込みサービスルーチン初期化テーブルでの並びで決まります。
コード例
/* * 割込みサービスルーチンIDの定数定義 */ #define ISR1 1 #define ISR2 2 #define ISR3 3 const ID _kernel_isrorder_table[] = { ISR3, ISR1, ISR2 };
この例の場合、
ISR3
→ISR1
→ISR2
の順序で割込みサービスルーチン生成処理が行われます。
ユーザ初期化関数の呼出し
-
void _kernel_call_inirtn(void)
説明
カーネル起動時にタスクの起動、ディスパッチを開始する前に呼び出されます。 タスクが動作する前に行っておく処理がある場合に必要な処理があれば記述してください。 この関数から復帰するまでタスクは開始されません。
定義
void _kernel_call_inirtn(void) { /* ... ここにユーザ実装の初期化処理を記述 */ __SOLID_SYS_INTRTN(); /* このマクロは削除しないでください */ }
ユーザ終了処理関数の呼出し
-
void _kernel_call_terrtn(void)
説明
カーネルが終了したタイミングで呼び出されます。 必要な処理があれば記述してください。 この関数が呼び出された時点ではすべてのタスク及びカーネルの動作は 終了しているため、終了処理の中でサービスコールなどのカーネルの機能を使うことはできません。
定義
void _kernel_call_terrtn(void) { /* ... ここにユーザ実装の終了処理を記述 */ __SOLID_SYS_TERRTN(); /* このマクロは削除しないでください */ }
動的生成される資源の上限数設定(動的資源生成カーネルのみ)
/*
* 動的に生成するカーネル資源の数を定義
* (静的なテーブルで定義される資源に追加して動的に
* 生成できる資源数を定義
*/
#define TNUM_AID_TSK 0
#define TNUM_AID_SEM 0
#define TNUM_AID_FLG 0
#define TNUM_AID_DTQ 0
#define TNUM_AID_PDQ 0
#define TNUM_AID_MTX 0
#define TNUM_AID_MPF 0
#define TNUM_AID_CYC 0
#define TNUM_AID_ALM 0
#define TNUM_AID_ISR 0
各資源ごとに動的生成可能な上限数を定義します。
ここで定義した数を超えて資源を生成するAPI(acre_*)を呼び出した場合、 E_NOID
(ID番号不足) が返されます。
定義を省略した場合の値は0となります。
ここで定義される資源数には静的に生成される資源は含まれません。 例えば、テーブル定義で3つのタスクを定義し、さらにTNUM_AID(3)を定義した場合には合計で最大6つのタスクが生成できることになります。
各定数と資源の対応は以下の通りです。
定数名 |
資源名称 |
---|---|
TNUM_AID_TSK |
タスク |
TNUM_AID_SEM |
セマフォ |
TNUM_AID_FLG |
イベントフラグ |
TNUM_AID_DTQ |
データキュー |
TNUM_AID_PDQ |
優先度データキュー |
TNUM_AID_MTX |
ミューテックス |
TNUM_AID_MPF |
固定長メモリプール |
TNUM_AID_CYC |
周期通知 |
TNUM_AID_ALM |
アラーム通知 |
TNUM_AID_ISR |
ISR(割込みサービスルーチン) |
注釈
動的生成カーネルでない場合にはこれらの定義は無視されます。
起動要求キューイング数/起床要求キューイング数の設定(optional)
/*
* タスクの起動要求キューと起床要求キューの最大数を定義
* (optional)
*
* TMAX_ACT_QUEUE/TMAX_WUP_QUEUEを定義すると起動要求(act_tsk)
* 起床要求(wup_tsk)がキューイングされる数を設定できます。
* 未定義の場合のでデフォルト値はいずれもUINT32_MAXです。
*/
#define TMAX_ACT_QUEUE 50 /* 設定例 */
#define TMAX_WUP_QUEUE 50 /* 設定例 */
act_tsk()
によるタスク起動要求と wup_tsk()
による起床要求がキューイングされる数を定義します。
(通常はコメントアウトされています)
各定数とキューの対応は以下の通りです。
定数名 |
キュー名称 |
未定義の場合のデフォルト値 |
---|---|---|
TMAX_ACT_QUEUE |
起動要求キューイング数 (0~ |
|
TMAX_WUP_QUEUE |
起床要求キューイング数 (0~ |
|
注釈
TOPPERSリリースの実装ではキューイング数はそれぞれ1固定ですが、SOLIDでは上記の通り拡張しています。