カーネル起動パラメータの設定

アプリケーションが使用するタスクやセマフォなどのカーネル資源の数や属性などを 設定ファイル (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);

タスクが起動するタイミングで exinf を引数に task で指定された関数が呼び出されます。

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 に指定しますがその場合は以下の点に注意してください

  • SOLID-OSの機能であるスタックフェンス機能はスタックが自動割り当ての場合 (stk == NULL)のみ動作します。ユーザが任意のスタック領域を割り当てている場合にはそのタスクにはスタックフェンス機能が働きません。

  • スタック領域と使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるため stk に指定する領域(変数)については以下のマクロを使用して宣言してください。

    type STK_T

    スタック用のデータ型

    COUNT_STK_T(sz)

    サイズszのスタック領域を確保するために必要な STK_T 型の配列の要素数

    ROUND_STK_T(sz)

    サイズszに必要なSTK_T型の数(配列の要素数)

コード例

#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}, };
};

タスク生成順序テーブル

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 };

この例の場合、TASK3TASK1TASK2 の順序でタスク生成処理が行われます。

セマフォ初期化ブロック

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でセマフォを生成
};

イベントフラグ初期化ブロック

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
};

データキュー初期化ブロック

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で指定した数のデータを格納できるデータキュー管理領域のサイズ(バイト数)

TCNT_DTQMB(dtqcnt)

dtqcntで指定した数のデータを格納できるデータキュー管理領域を確保するために必要な MB_T 型の配列の要素数

コード例

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, 管理領域を指定
};

優先度データキュー初期化ブロック

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

管理領域のデータ型

TSZ_PDQMB(pdqcnt)

pdqcnt で指定した数のデータを格納できる優先度データキュー管理領域のサイズ(バイト数)

TCNT_PDQMB(pdqcnt)

pdqcnt で指定した数のデータを格納できる優先度データキュー管理領域を確保するために必要な 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 },    // 送信待ち行列=タスク優先度順,  管理領域を指定
};

ミューテックス初期化ブロック

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) },    //待ち行列=タスク優先度順、優先度上限なし
};

固定長メモリプール初期化ブロック

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を指定した場合はカーネル内部で必要なメモリ領域の確保が行われます。

固定長メモリプール領域、固定長メモリプール管理領域として使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるためそれぞれ以下のマクロを使用して宣言してください。

  • 固定長メモリプール領域を確保するためのマクロとデータ型

    type MPF_T

    固定長メモリプール領域用のデータ型

    COUNT_MPF_T(blksz)

    固定長メモリブロックのサイズがblkszの固定長メモリプール領域を確保するために,固定長メモリブロック1つあたりに必要な MPF_T 型の配列の要素数

    ROUND_MPF_T(blksz)

    要素数COUNT_MPF_T(blksz)のMPF_T型の配列のサイズ (blkszを MPF_T 型のサイズの倍数になるように大きい方に丸めた値)

  • 固定長メモリプール管理領域を確保するためのマクロ

    TSZ_MPFMB(blkcnt)

    blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域のサイズ(バイト数)

    TCNT_MPFMB(blkcnt)

    blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域を確保するために必要な MB_T 型の配列の要素数

コード例

#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 }, // すべての領域を静的変数で確保
};

周期通知初期化ブロック

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

通知ハンドラが起動するタイミングで exinf を引数に nfyhdr で指定された関数が呼び出されます。

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を呼び出す
};

アラーム通知初期化ブロック

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

通知パラメータ構造体

アラーム通知が発生した場合の通知方法やエラーが起きた場合の処理方法を構造体に設定します。 詳細については 通知パラメータ構造体の設定方法 を参照してください。

コード例

(通知パラメータ構造体の設定方法 を参照してください。)

通知パラメータ構造体の設定方法

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

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

コード例

#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)} }},
};

割込み初期化設定ブロック

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)初期化ブロック

typedef struct t_cisr T_CISR
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

割込みサービスルーチンを登録する割込み番号

割込み初期化設定ブロックで登録した割込み番号を設定します。該当する割込みについて割込み初期化設定ブロックのメンバ inthdrINTINI_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を登録
};

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 };

この例の場合、ISR3ISR1ISR2 の順序で割込みサービスルーチン生成処理が行われます。

ユーザ初期化関数の呼出し

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);
intptr_t exinf

初期化ルーチンの拡張情報

inirtn で指定された関数に引数として渡される値を指定します。

注釈

登録された関数はカーネル起動時にタスクの起動、ディスパッチを開始する前、 ユーザ初期化関数 (_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},
};

ユーザ終了処理関数の呼出し

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);
intptr_t exinf

終了処理ルーチンの拡張情報

terrtn で指定された関数に引数として渡される値を指定します。

注釈

登録された関数はカーネル終了時にユーザ終了処理関数 (_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},
};

動的生成される資源の上限数設定(動的資源生成カーネルのみ)

/*
 *    動的に生成するカーネル資源の数を定義
 *    (静的なテーブルで定義される資源に追加して動的に
 *     生成できる資源数を定義
 */
#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~UINT32_MAX)

UINT32_MAX

TMAX_WUP_QUEUE

起床要求キューイング数 (0~UINT32_MAX)

UINT32_MAX

注釈

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

タスクが起動するタイミングで exinf を引数に task で指定された関数が呼び出されます。

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 に指定しますがその場合は以下の点に注意してください

  • SOLID-OSの機能であるスタックフェンス機能はスタックが自動割り当ての場合 (stk == NULL) のみ動作します。ユーザが任意のスタック領域を割り当てている場合にはそのタスクにはスタックフェンス機能が働きません。

  • スタック領域と使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるため stk に指定する領域(変数)については以下のマクロを使用して宣言してください。

    type STK_T

    スタック用のデータ型

    COUNT_STK_T(sz)

    サイズ sz のスタック領域を確保するために必要な STK_T 型の配列の要素数

    ROUND_STK_T(sz)

    サイズ sz に必要な STK_T 型の数(配列の要素数)

コード例

#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) },

};

ロック付きオブジェクト属性初期化

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 };

この例の場合、TASK3TASK1TASK2 の順序でタスク生成処理が行われます。

セマフォ初期化ブロック

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でセマフォを生成
};

イベントフラグ初期化ブロック

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
};

データキュー初期化ブロック

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

管理領域のデータ型

TSZ_DTQMB(dtqcnt)

dtqcnt で指定した数のデータを格納できるデータキュー管理領域のサイズ(バイト数)

TCNT_DTQMB(dtqcnt)

dtqcnt で指定した数のデータを格納できるデータキュー管理領域を確保するために必要な 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, 管理領域を指定
};

優先度データキュー初期化ブロック

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

管理領域のデータ型

TSZ_PDQMB(pdqcnt)

pdqcnt で指定した数のデータを格納できる優先度データキュー管理領域のサイズ(バイト数)

TCNT_PDQMB(pdqcnt)

pdqcnt で指定した数のデータを格納できる優先度データキュー管理領域を確保するために必要な 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 }, // 送信待ち行列=タスク優先度順,  管理領域を指定
};

メールボックス初期化ブロック

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に関連付け
};

ミューテックス初期化ブロック

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は無効)

};

メッセージバッファ初期化ブロック

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_TFIFO をセットします。

TA_TRPI

待ち行列をタスクの優先度順にする

LOCK *p_obj_lock

オブジェクトロックへのポインタ

カーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。

uint_t maxmsz

メッセージの最大長

メッセージ最大長をバイト数で指定します

size_t mbfsz

メッセージバッファ管理領域のサイズ

メッセージバッファ管理領域のサイズをバイト数で指定します

void *mbfmb

メッセージバッファ管理領域の先頭番地

注釈

メンバ変数 p_obj_lock はカーネルのロック(排他)方式がプロセッサロックの場合にのみ定義されます。

メンバ mbfatr と メンバ p_obj_lock はマクロ CFG_OBJ_ATTR を使用して記述してください。

注釈

優先度上限ミューテックスの動作についてはTOPPERS新世代カーネル統合仕様書の4.4.6 ミューテックスの「使用上の注意」を参照してください。

コード例

#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 },
};

固定長メモリプール初期化ブロック

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 型の配列の要素数

    ROUND_MPF_T(blksz)

    要素数COUNT_MPF_T(blksz)の MPF_T 型の配列のサイズ (blkszを MPF_T 型のサイズの倍数になるように大きい方に丸めた値)

  • 固定長メモリプール管理領域を確保するためのマクロ

    TSZ_MPFMB(blkcnt)

    blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域のサイズ(バイト数)

    TCNT_MPFMB(blkcnt)

    blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域を確保するために必要なMB_T型の配列の要素数

コード例

#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 }, // すべての領域を静的変数で確保
};

周期通知/アラーム通知初期化ブロック中のプロセッサ情報を初期化するためのマクロ

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

通知ハンドラが起動するタイミングで exinf を引数に nfyhdr で指定された関数が呼び出されます。

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)) },
};

アラーム通知初期化ブロック

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 を使用して記述してください。

コード例

(通知パラメータ構造体の設定方法 を参照してください。)

通知パラメータ構造体の設定方法

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

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

コード例

#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)} }},
};

スピンロック初期化設定ブロック

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にロックを関連付け
};

割込み初期化設定ブロック

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 型) で直接値を指定するか、 以下のマクロを使用して設定してください [複数の場合は論理和で指定]

注釈

使用する割込み番号が重複した場合は先着優先(先に記述された定義が優先)となり無視されます。また、タイマ割込みなどカーネルや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)初期化ブロック

typedef struct t_cisr T_CISR
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

割込みサービスルーチンを登録する割込み番号

割込み初期化設定ブロックで登録した割込み番号を設定します。該当する割込みについて割込み初期化設定ブロックのメンバ inthdrINTINI_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を登録
};

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 };

この例の場合、ISR3ISR1ISR2 の順序で割込みサービスルーチン生成処理が行われます。

ユーザ初期化関数の呼出し

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~UINT32_MAX)

UINT32_MAX

TMAX_WUP_QUEUE

起床要求キューイング数 (0~UINT32_MAX)

UINT32_MAX

注釈

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

タスクが起動するタイミングで exinf を引数に task で指定された関数が呼び出されます。

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 に指定しますがその場合は以下の点に注意してください

  • SOLID-OSの機能であるスタックフェンス機能はスタックが自動割り当ての場合 (stk == NULL)のみ動作します。ユーザが任意のスタック領域を割り当てている場合にはそのタスクにはスタックフェンス機能が働きません。

  • スタック領域と使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるため stk に指定する領域(変数)については以下のマクロを使用して宣言してください。

    type STK_T

    スタック用のデータ型

    COUNT_STK_T(sz)

    サイズszのスタック領域を確保するために必要な STK_T 型の配列の要素数

    ROUND_STK_T(sz)

    サイズszに必要な STK_T 型の数(配列の要素数)

コード例

#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) },

};

タスク生成順序テーブル

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 };

この例の場合、TASK3TASK1TASK2 の順序でタスク生成処理が行われます。

セマフォ初期化ブロック

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でセマフォを生成
};

イベントフラグ初期化ブロック

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
};

データキュー初期化ブロック

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で指定した数のデータを格納できるデータキュー管理領域のサイズ(バイト数)

TCNT_DTQMB(dtqcnt)

dtqcntで指定した数のデータを格納できるデータキュー管理領域を確保するために必要な MB_T 型の配列の要素数

コード例

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, 管理領域を指定
};

優先度データキュー初期化ブロック

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で指定した数のデータを格納できる優先度データキュー管理領域のサイズ(バイト数)

TCNT_PDQMB(pdqcnt)

pdqcntで指定した数のデータを格納できる優先度データキュー管理領域を確保するために必要な 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 }, // 送信待ち行列=タスク優先度順,  管理領域を指定
};

メールボックス初期化ブロック

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}, // 受信待ち行列=メッセージ優先度順
};

ミューテックス初期化ブロック

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は無効)
};

メッセージバッファ初期化ブロック

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_TFIFO をセットします。

TA_TRPI

待ち行列をタスクの優先度順にする

uint_t maxmsz

メッセージの最大長

メッセージ最大長をバイト数で指定します

size_t mbfsz

メッセージバッファ管理領域のサイズ

メッセージバッファ管理領域のサイズをバイト数で指定します

void *mbfmb

メッセージバッファ管理領域の先頭番地

注釈

FMP3ではロック方式がジャイアントロック方式のみとなったため、FMPのプロセッサロック方式のために各資源初期化ブロックに定義されていたロック用変数(p_obj_lock)が廃止となりました。 ただし、FMP3では CFG_OBJ_ATTR マクロは互換性のために各資源の属性のみを扱う様に定義されているため、kernel_cfg.c の中で使用されていても修正の必要はありません。

注釈

優先度上限ミューテックスの動作についてはTOPPERS第3世代カーネル(ITRON系)統合仕様書の4.4.5 ミューテックスの「使用上の注意」を参照してください。

コード例

#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 },
};

固定長メモリプール初期化ブロック

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を指定した場合はカーネル内部で必要なメモリ領域の確保が行われます。

固定長メモリプール領域、固定長メモリプール管理領域として使用するメモリ領域には配置(アドレスのアラインメント)、サイズに制限があるためそれぞれ以下のマクロを使用して宣言してください。

  • 固定長メモリプール領域を確保するためのマクロとデータ型

    type MPF_T

    固定長メモリプール領域用のデータ型

    COUNT_MPF_T(blksz)

    固定長メモリブロックのサイズがblkszの固定長メモリプール領域を確保するために,固定長メモリブロック1つあたりに必要な MPF_T 型の配列の要素数

    ROUND_MPF_T(blksz)

    要素数COUNT_MPF_T(blksz)の MPF_T 型の配列のサイズ (blkszを MPF_T 型のサイズの倍数になるように大きい方に丸めた値)

  • 固定長メモリプール管理領域を確保するためのマクロ

    TSZ_MPFMB(blkcnt)

    blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域のサイズ(バイト数)

    TCNT_MPFMB(blkcnt)

    blkcntで指定した数の固定長メモリブロックを管理することができる固定長メモリプール管理領域を確保するために必要な MB_T 型の配列の要素数

コード例

#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 }, // すべての領域を静的変数で確保
};

周期通知/アラーム通知初期化ブロック中のプロセッサ情報を初期化するためのマクロ

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

通知ハンドラが起動するタイミングで exinf を引数に nfyhdr で指定された関数が呼び出されます。

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)) },
};

アラーム通知初期化ブロック

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          iprcid;         // アラームハンドラの初期割付けプロセッサ(ローカルタイマ方式の場合のみ)
    uint_t      affinity;       // アラームハンドラの割付け可能プロセッサ(ローカルタイマ方式の場合のみ)
} ALMINIB;

const ALMINIB _kernel_alminib_table[];

メンバー

ATR almatr

アラーム通知属性

指定可能な属性をありません。常に TA_NULL をセットしてください。

intptr_t exinf

アラームハンドラの拡張情報

アラーム通知が発生した場合の通知方法やエラーが起きた場合の処理方法を構造体に設定します。 詳細については 通知パラメータ構造体の設定方法 を参照してください。

ALMHDR almhdr

アラームハンドラの起動番地

ID iprcid

アラームハンドラの初期割付けプロセッサ

uint_t affinity

アラームハンドラの割付け可能プロセッサ

注釈

メンバ iprcid と メンバ affinity はマクロ CFG_SYSTIM_AFFINITY を使用して記述してください。

コード例

(通知パラメータ構造体の設定方法 を参照してください。)

通知パラメータ構造体の設定方法

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

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

コード例

#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)} }},
};

スピンロック初期化設定ブロック

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の旧方式記述)
};

割込み初期化設定ブロック

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)

タスク初期化ブロック中のプロセッサ情報 (iprcid, affinity) を初期化するためのマクロ

パラメータ
  • prcid -- 初期状態でタスクが動作するプロセッサID(1...)

  • affinity --

    タスクが動作可能なプロセッサをビットマスクで指定 符号なし整数 (uint_t 型) で直接値を指定するか、 以下のマクロを使用して設定してください [複数の場合は論理和で指定]

注釈

使用する割込み番号が重複した場合は先着優先(先に記述された定義が優先)となり無視されます。また、タイマ割込みなどカーネルや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)初期化ブロック

typedef struct t_cisr T_CISR
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

割込みサービスルーチンを登録する割込み番号

割込み初期化設定ブロックで登録した割込み番号を設定します。該当する割込みについて割込み初期化設定ブロックのメンバ inthdrINTINI_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を登録
};

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 };

この例の場合、ISR3ISR1ISR2 の順序で割込みサービスルーチン生成処理が行われます。

ユーザ初期化関数の呼出し

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~UINT32_MAX)

UINT32_MAX

TMAX_WUP_QUEUE

起床要求キューイング数 (0~UINT32_MAX)

UINT32_MAX

注釈

TOPPERSリリースの実装ではキューイング数はそれぞれ1固定ですが、SOLIDでは上記の通り拡張しています。