セルタイプ記述

セルタイプ記述は、コンポーネントの型を定義するものです。 セル(コンポーネントインスタンス)は、いずれかのセルタイプ(複合セルタイプを含む)に属します。

【記述例】

[singleton]                           // セルタイプの指定子
celltype tCelltype {                  // celltype キーワードとセルタイプ名
  entry sSignature eEntry;            // entry キーワードと対応付けられたシグニチャと受け口名
  call  sSignature cCall;             // call キーワードと対応付けられたシグニチャと呼び口名
  attr {                              // 属性. '{', '};' で囲む
    int16_t len = 256;                // 初期値を指定した場合
    char  *bufName;                   // 初期値を指定しない場合
    int8_t   initialState = 0;
  };
  var {                               // 変数. '{', '};' で囲む
    [size_is( len )]                  // 変数の指定子
       int8_t *buf;
    int16_t  rdPoint;
    int16_t  wrPoint;
    int8_t   stateNo = initialState;  // 属性を参照して変数を初期化
  };
};

ここで celltype はキーワードであり、tCelltype はセルタイプ名です。’{‘, ‘}’ に囲まれた中に、受け口(entry), 呼び口(call), 属性(attr), 変数(var)を記述します。

この他に、ファクトリ (factory, FACTORY), リクワイア (require) を記述します。

慣習として、セルタイプ名は ’t’ で、受け口名は ‘e’ で、呼び口名は ‘c’ で始めます。属性、変数の名前は、小文字で始め、単語区切りでは大文字とします。

セルタイプ記述の指定子

アクティブ(active)指定子

アクティブ(active)指定子は、セルタイプがアクティブであることを表します。 すなわち、アクティブなセルタイプに属するセルは、受け口関数が呼び出されなくても動作することを表します。タスクやハンドラ、あるいはこれらを内部にもつセルタイプはアクティブです。

ジェネレート(generate)指定子

ジェネレート(generate)指定子は、セルタイププラグインの適用を指示するものです。セルタイププラグインの一般的な使い方としては、ファクトリでは実現できない特別なコードを生成するのに用います。

【記述例】

[generate(CelltypePluginName, "option..." )]
celltype tCelltype {
    /* 省略 */
};
ここで、それぞれのワードは、以下を意味します。
  • generate はキーワードである
  • CelltypePluginName はセルタイププラグイン名である
  • オプションは、プラグインごとに規定される。文字列リテラルを渡す

idx_is_id 指定子

idx_is_id 指定子は、セルの実行時識別として整数値を用いることを示します。 この指定がない場合、実行時識別としてポインタが用いられます。 実行時識別として整数値を用いることの利点は、指定値の有効性検査が行われることです。

以下の場合、idx_is_id 指定されていない場合でも、idx_is_id 指定されたものとして扱われます。

  • TECS ジェネレータのオプションで指定されている場合
  • セルタイプに属するセルが、異なるドメインに存在する場合

シングルトン(singleton)指定子

シングルトン(singleton)指定子は、セルタイプのセルがシステム中に一つだけ存在することを示します。

あるシングルトンセルタイプのセルは、それぞれのノードやリンク単位に最大1つだけ存在することができます。 つまり、あるコンポーネント記述において、あるシングルセルトンタイプのセルが複数存在することができます。

呼び口

呼び口は、受け口関数を呼び出すための口です。シグニチャに対応付けます。

呼び口配列

呼び口から受け口への結合を分流することはできませんが、呼び口配列により、呼び口を複数のセルに結合することができます。

添数を指定することも省略することもできます。 添数を省略した場合、任意個のセルを結合することができます。

呼び口の指定子

オプショナル(optional)指定子

呼び口を、未結合とすることができることを示します。

オプショナル(optional)指定されている場合、セルタイプコードにおいては、呼び口関数を呼び出す前に、呼び口が結合されているかどうか検査する必要があります。

オプショナル指定されていなく、添数指定されていない呼び口配列の場合、少なくとも1つの結合をもつ必要があります。

省略(omit)指定子

呼び口に関する情報を、出力コードに含めないことを示します。

セルタイプコードでは、この呼び口を通して、関数を呼び出すことはできません。 この呼び口を通した結合は、セルタイププラグインで参照することが想定されます。

受け口

受け口は、機能を提供するための口です。シグニチャに対応付けます。

受け口配列

受け口配列は、呼び元を区別するために用いられます。 呼び口から受け口への結合を合流することができますが、この場合、受け口において呼び元を区別するこができません。

添数を指定することも省略することもできます。 添数を省略した場合、任意個のセルを結合することができます。

受け口の指定子

アロケータ(allocator)指定子

アロケータ(allocator)指定子は、リレーアロケータを指定するのに用いられます。

【記述例】

celltype tRelayComponent {
    [allocator(                          // リレーアロケータの指定
        snd.buf <= cSR.snd.buf,  // 前方参照可能
        rcv.buf <= cSR.rcv.buf
    )]
    entry  sSendRecv eS;            // リレーする元の受け口
    call   sSendRecv cSR;               // リレーする先の呼び口

    attr {
         char_t       *name = C_EXP( "\"$id$\"" );
    };
};

【補足説明】TECS ジェネレータの実装で、受け口配列のリレーアロケータは未サポート。

T.B.W.

インライン(inline)指定子

受け口関数が、インライン関数として実装されることを示します

固定結合

固定結合は、セルタイプの受け口において、呼び元のセルを指定するものです。

【記述例】

// (1) 逆require をセルタイプで指定する場合
celltype tCelltype {
    entry sInit eInit <= tInitializer.cInit;  // シングルトンセルタイプ
};

// (2) 逆require をセルで指定する場合
celltype tCelltype2 {
    entry sInit eInit <= Initializer.cInit;
};

【補足説明】初期化のための結合を、一々記述することなく、省略することを目的とした機能である。

固定結合は、以下の条件を満たす必要があります。

  • 固定結合先の呼び口は、添数なしの呼び口配列でなくてはならない
  • 固定結合先にセルタイプ (複合セルタイプを含む) を指定する場合、そのセルタイプは、シングルトンでなくてはならない
  • 固定結合先にセルを指定する場合、そのセルタイプはシングルトンでなくてもよい
  • 固定結合指定されている受け口は、非配列でなくてはならない
  • 複合セルタイプの内部セルが固定結合が指定されている受け口を持つ場合、複合セルタイプの外部のセルから直接結合される

複合セルタイプの内部セルが固定結合が指定されている受け口を持つ場合、複合セルタイプの外部のセルから直接結合されるため、複合セルタイプにおいて、外部結合のための受け口を持つ必要はありません。

固定結合の結合順序は、以下の通りです。

  • CDL ファイルのセルの出現順(構文解釈が行われた順)に、固定結合の結合がなされる
  • 複合セルタイプの内部セルにおいて、固定結合がなされている場合、複合セルタイプのセルの出現順番で結合がなされる
  • 複合セルタイプの内部セルに複数の固定結合が指定されたセルがある場合、複合セルタイプ定義で内部セルが出現した順番で結合がなされる
  • スループラグインで挿入されるセルは、すべてのソースプログラムの構文解釈が終わった後に構文解釈されるため、固定結合の順序としては後ろの方に置かれる

【補足説明】セルの id は、同じセルタイプに属するセルの間で順序付けするものである。固定結合では、複数のセルタイプが関わることを想定しており、CDL ファイルの出現順序で結合される。

属性

属性は、セルの持つ値を保持するものです。属性には、初期値を与えることができますが、実行時に書き換えることはできない、定数として扱われます。属性は ROM に置くことが想定されています。

属性の初期値は、セルタイプの定義時だけでなく、セルを定義する際にも与えることもできます。 両方に初期値が与えられた場合には、セルにおける初期値が優先されます。 属性の初期値は、セルタイプかセルの少なくとも一方の定義において、与えられる必要があります。

初期化子として C_EXP が用いられた場合、文字列リテラルは、名前置換が行われます。 この名前置換は、ファクトリににおける名前置換と同じ規則です。

集成型初期化子を、配列または構造体を初期化するのに用いることができます。 配列には、size_is 指定されたポインタ型を含みます。 size_is 指定されていないポインタ型の属性に、集成型初期化子を用いることはできません。

属性の指定子

選択肢(choice)指定子

選択肢(choice)指定子は、属性が取りうる値を指定します。

【記述例】

attr {
  [choice={"0", "1", "2"}]
     int8_t  initial_state = 0;
};

TECS ジェネレータは、選択肢(choice)指定子で指定された初期値以外が設定されたかどうかを検査しません。GUI エディタで選択肢を示すためのものです。

省略(omit)指定子

省略(omit)指定子は、属性をセルの CB に出力をしないことを示します。 属性を、セルタイプコードで参照しない場合、すなわちファクトリまたはセルタイププラグインでのみ参照する場合に指定します。

size_is 指定子

属性がポインタ型の場合に指定できます。 ポインタ型が配列を指していて、そのサイズが size_is の引数で示される大きさを持つことを示します。

size_is は式を引数にとります。式は定数式、または属性を含む式です。この属性は、前方参照が許されます。

変数

変数は、内部変数とも呼ばれます。

変数も、セルの持つ値を保持するものですが、属性とはいくつかの点で異なります。

  • 実行時に書き換えることができる
  • セルの定義時に初期値を与えることはできない
  • 初期値を指定するのに属性を参照する式とすることができる
  • 初期値をまったく与えないままとすることができる

内部変数は、セルの定義において直接的に初期値を与えることはできないが、属性を参照する式により間接的に初期値を与えることができます。

属性が ROM に置かれることが想定されているのに対し、変数は RAM に置かれることが想定されます。 つまりセルタイプコード (プログラム)により値が変更されることが想定されます。

変数には、セルの定義において直接的に初期値を与えることはできませんが、属性を参照することで間接的に初期値を与えることができます。

変数を定数式により初期化することはできますが、修正型の初期化子や C_EXP 初期化子により初期化することはできません。

変数の指定子

変数の size_is 指定子

変数がポインタ型の場合に指定できます。 ポインタ型が配列を指していて、そのサイズが size_is の引数で示される大きさを持つことを示します。

  • size_is は整数型の値を返す式を引数にとる。式は定数式、または属性を含む式である
  • size_is 指定されたポインタ型の変数は、配列を指す定数として扱われ、書換えることはできない
  • ポインタの指す先の配列の要素は書き換えることができる
  • size_is の引数で指定された大きさの領域が確保される
    (初期値の指定の有無に関係なく、size_is の引数で指定された大きさの領域が確保される)
  • 初期値として ‘{‘, ‘}’ で囲んだ定数式を要素とする初期化子リストを指定できる (初期化子リストの個数は size_is の引数で与えられる配列の大きさ以下の個数が指定できる)

リクワイア

リクワイアにより、セルタイプに属するすべてのセルを、特定のセルに結合できます。

【記述例】

/* require でセル名を指定 */
[active]
celltype tRequire{
    require Kernel.eSc;             // セル : Kernel
};

/* require でセルタイプ名を指定 */
[active]
celltype tRequire2{
    require tKernel.eSc;            // セルタイプ: tKernel (シングルトン)
};

/* 呼び口名を持つ require */
celltype tNamedRequire{
    require cReqCall = Kernel.eSc; // 呼び口名 cReqCall
};

ここで、セルタイプを指定する場合、そのセルタイプはシングルトンでなくてはなりません。また、受け口が、受け口配列であってはなりません。 セルを指定する場合、そのセルを前方参照できます。

リクワイアは、リクワイア呼び口の生成と、リクワイア呼び口の結合先の受け口を指定するものです。 リクワイア呼び口は、通常の呼び口とはいくつかの点で異なります。

  • 呼び口名を与えないでおくことができる
  • セルタイプにおいて、結合を定義する
  • 呼び先を指定するのに、セル名に代えてセルタイプ名で指定することもできる

【補足説明】TECS ジェネレータの実装では、リクワイア呼び口名が与えられたリクワイア呼び口への結合を、セルでオーバーライドすることがことがでますが、TECS ジェネレータは警告を発します。

リクワイア呼び口に名前、すなわちリクワイア呼び口名を与えることができます。 リクワイアは、一つのセルタイプにおいて複数記述することができますが、リクワイア呼び口名が与えられていない場合、それぞれの受け口のシグニチャに属する関数の名前が重複することはできません。

リクワイアでセルタイプを指定する場合、シングルトンセルタイプのセルが複数存在する場合がありえます。 リンク単位が異なるリージョンごとにシングルトンセルタイプのセルが存在する場合です。 この場合、セルタイプ名を指定すると、同時に生成されるシングルトンセルタイプのセルを参照します。 同時に生成されるセルがない場合は、誤りとなります。

ファクトリ

ファクトリは、TOPPERS/ASP などのコンフィギュレーションファイルを作成するなどの目的で使用します。 ファクトリには、セルタイプのファクトリ、つまりセルタイプが指定されたことにより必要となる資源を生成する場合と、セルごとに必要となる資源を生成する場合があります。

【記述例】

celltype tEventflag {
    entry   siNotificationHandler   eiNotificationHandler;
    attr {
        int                     id = C_EXP("FLGID_$id$");
        [omit] int              attribute = C_EXP("TA_NULL");
    };
    factory {             // セルごとに適用されるファクトリ
         write("tecsgen.cfg",
               "CRE_FLG(FLGID_$id$, { %s, 0 });", // 名前置換
               attribute);                        // 属性参照
    };
    FACTORY {             // セルタイプに適用されるファクトリ
        write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
    };
};

ファクトリ関数 write

第一引数は、出力先のファイル名を指定する文字列です。 コンフィギュレーションファイルの場合、”tecsgen.cfg” を指定することを推奨します。

第二引数は、第一引数で指定されたファイルに出力するフォーマット文字列を指定します。 この文字列は C の printf 文のフォーマット指定と同様に扱われます。 例えば、フォーマット文に %s が指定されている場合、第三引数以降の対応付けられる位置に文字列が指定されることを表します。

第三引数以降は、オプショナルであり、フォーマット文字列によって引数の有無が決定されます。 第三引数以降に現れる識別子は、以下の順にサーチされます。

  • 属性
  • 定数

識別子は、その右辺値に置き換えられて、write 関数の引数として渡されます。 属性の場合、右辺値は、セルに定義されていればその値を、セルに定義されていなければセルタイプで定義されたデフォルトの値を、それも定義されていなければ0または空文字列となります。

【補足説明】引数として式を与えることはできない。

【参照実装における制限】write 以外ファクトリ関数は定義されていない。

【参照実装における制限】参照実装において、フォーマットはコード生成段階において評価される。このため多少ファイル出力が行われる。

【参照実装における制限】整数値を出力する場合でも、C_EXP が指定された場合に備えて、フォーマットでは %s を指定した方がよい。整数値は、暗黙的に文字列に変換されるため %d と指定したのと同じになる。一方 %d が指定されていると整数値以外はエラーとなる。

名前置換

write 関数の引数の文字列定数に含まれる $id$ などの文字列は置換が行われる。以下に置換の行われる文字列の一覧を示す。

置換文字列 置換内容
$id$ セルタイプ名とセル名を ‘_’ で連結したものに置換
$cell$ セル名に置換
$cell_global$ セルのグローバル名に置換
$cb$ セルの CB の C 言語名に置換
$cbp$ セルの CB へのポインタ (CB が生成されない場合は NULL に置換)
$cb_proto$ セルの CB の C 言語名 (プロトタイプ宣言用) に置換
$ct$ セルタイプ名に置換
$ct_global$ セルタイプのグローバル名に置換
$idx$ セルの CB の IDX (idx_is_id の場合は整数、そうでない場合は CB へのポインタ)に置換
$ID$ セルの ID(idx_is_id の場合 IDX に一致)に置換
$$ $ に置換

最後の規則が優先され、例えば $$id$ は $id$ に、$$ct$ は $ct$ に置換される。 また、セルタイプファクトリ(FACTORY)の内側では $ct$, $$ の置換のみが行われる。