TECS マニュアル

課題

to be filled in

目次:

TECS マニュアルのライセンス

Copyright (C) 2016-2019 by TOPPERS Projet TECS WG

上記著作権者は,以下の (1)〜(3) の条件を満たす場合に限り,本ドキュメ ント(本ドキュメントを改変したものを含む.以下同じ)を使用・複製・改 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.

(1)本ドキュメントを利用する場合には,上記の著作権表示,この利用条件 および下記の無保証規定が,そのままの形でドキュメント中に含まれて いること.

(2) 本ドキュメントを改変する場合には,ドキュメントを改変した旨の記述 を,改変後のドキュメント中に含めること.ただし,改変後のドキュメ ントが,TOPPERSプロジェクト指定の開発成果物である場合には,この限 りではない.

(3) 本ドキュメントの利用により直接的または間接的に生じるいかなる損害 からも,上記著作権者およびTOPPERSプロジェクトを免責すること.また, 本ドキュメントのユーザまたはエンドユーザからのいかなる理由に基づ く請求からも,上記著作権者およびTOPPERSプロジェクトを免責すること.

本ドキュメントは,無保証で提供されているものである.上記著作権者およ びTOPPERSプロジェクトは,本ドキュメントに関して,特定の使用目的に対す る適合性も含めて,いかなる保証も行わない.また,本ドキュメントの利用 により直接的または間接的に生じたいかなる損害に関しても,その責任を負 わない.

TECS WG --- TECS の開発母体

TECS は NPO 法人 TOPPERS プロジェクト TECS WG (ワーキンググループ) により開発されました。 本仕様の開発に関わったワーキンググループのメンバーを以下に記します。

  • 安積 卓也 (埼玉大学)

  • 石川 拓也 (名古屋大学)

  • 鵜飼 敬幸 (個人会員)

  • 大山 博司 (オークマ(株), TECS ワーキンググループ主査)

  • 河田 智明 (名古屋大学)

  • 小南 靖雄 (フリーエンジニア)

  • 白田 聖人 (大阪大学)

  • 高木 信尚 ((株)きじねこ)

  • 高田 広章 (名古屋大学,NPO 法人 TOPPERS プロジェクト会長)

  • 長原 裕希 (立命館大学)

  • 成瀬 有美 (名古屋大学)

  • 長谷川 涼 (大阪大学)

  • 原  拓 (名古屋大学)

  • 山内 克哉 (名古屋大学)

  • 山本 拓郎 (大阪大学)

  • 山本 将也 (名古屋大学)

あいうえお順、所属は関与した当時のもの。 一般公開した 2009年以降に関わったメンバーを掲載しています。

組込みコンポーネントシステム TECS 仕様

TECS 仕様は、以下の要素から構成されます。

本書は、TECS 仕様のリファレンスマニュアルとして作成したものです。

【補足】TECS 仕様書は別途まとめていますが、アップデートが中断しているため、リファレンスマニュアルとしてまとめなおしました。

【補足】TECS 仕様書の暫定版は、以下にあります。コンポーネントモデルや、TECS ジェネレータ生成コードに関する説明があります。 http://dev.toppers.jp/trac_user/contrib/wiki/TECS-DOCS#TECS%E4%BB%95%E6%A7%98%E6%9B%B8

TECS V1.4.0 ~ V1.7.0 の新機能

TECS V1.7.0 の新機能

TECS V1.7.0 では、以下の機能が追加されています。

TECS V1.6.1 の新機能

TECS V1.6.1 では、以下の機能が追加されています。

  • 実行時情報機能 TECSInfo

  • TOPPERS/HRP3 対応

リファレンスマニュアルは、更新されていません。 以下のリンク先に TOPPERS/HRP3 における TECS の使い方を説明しています。

TECS V1.5.0 の新機能

TECS V1.5.0 では、以下の機能が追加、強化されています。

  • マルチプラグイン

  • 新しいプラグインの指定方法

  • 複合セルタイプ(composite) プラグイン

  • TLSF アロケータと mruby のマルチVM対応

リファレンスマニュアルは、更新されていません。 以下のリンク先のドキュメントを参照してください。

TECS V1.4.0 の新機能

このリファレンスマニュアルの他の部分は、TECS V1.3.1.0 (2016年1月公開) に対応しています。 TECS V1.4.0 (2016年11月公開) の新機能は、機能別マニュアルとして、以下の節に記します。

TECS コンポーネント図

目次:

概要

TECS コンポーネント図は、コンポーネントを組み合わせて構築されるソフトウェアの構造を示すものとなります。

TECS コンポーネント図では、コンポーネントの属性値を除いて、TECS コンポーネント記述言語 (TECS CDL) の組上げ記述 (セル記述) と一対一に対応します。 つまり TECS コンポーネント図は、TECS CDL のソースとして用いることができますし、反対に TECS CDL の組上げ記述をコンポーネント図に表すことができます。

TECS コンポーネント図を記述する上での注意点として、レイア (階層) を意識して書くようにします。 上位レイアにはアプリケーション、下位レイアにはデバイスドライバや OS カーネルが位置します。 上位レイアは、図の上部、または左側に、下位レイアは図の下部、または右側に書くようにすると、直観的に理解しやすくなります。

TECS コンポーネント図の書き方

基本的なコンポーネント図

基本的な TECS コンポーネント図として、二つのセルが結合された図を示します。 セル、すなわちコンポーネントインスタンスは、長方形により表します。 長方形の内側に、セルの属するセルタイプのセルタイプ名およびセル名を記します。 受け口は、セルの長方形の辺に沿って塗つぶした三角形を長方形の内向きに置き、受け口名を添えます。 呼び口は、セルの長方形の辺から始まる線分により表します。 呼び口名を添えます。 結合は、呼び口から受け口へ向かう線分により表します。 結合の線分に沿ってシグニチャ名を添えます。

_images/basic.png

合流

結合の合流を示します。 一つの受け口に対し、複数の呼び口が結合することはできるが、その逆はできません。

合流する点には、3つの線分が集まるようにします。 4つの線分が集まる場合には、合流ではなく、2つの異なる受け口への結合の、図上の交差となるようにします。

_images/join.png

呼び口配列

呼び口配列の例を示します。 呼び口配列では、呼び口名に配列の添数を添えて記します。

_images/carray.png

受け口配列

受け口配列の例を示します。 受け口配列では、受け口名に配列の添数を添えて記します。

_images/earray.png

コールバック

コールバックの例を示します。

_images/callback.png

呼び口配列と受け口配列

呼び口配列と受け口配列の添数を対応付けて、コールバックを実現した例です。 複数の呼び元に対してコールバックを実現する場合には、この例のように呼び口と受け口を対応付けて結合します。

_images/cearray.png

アクティブ

長方形の辺を二重線により描くことで、アクティブセルであることを示します。

_images/active.png

複合セル(composite)

複合セル(composite) を示す TECS コンポーネント図です。 この図では compcell1 が複合セルですが、複合セルであることを明示しません。 コンポーネント図、および TECS CDL による組上げ記述では、複合セルと非複合セルを区別しません。

_images/composite.png

これは、複合セルの内部のセルを描いた図です。 通常、複合セルの内部のセルは、コンポーネント図に描きません。

_images/composite-internal.png

RPC

リモート呼び出しを行うための接続を示すTECS コンポーネント図です。 通常の結合とは異なり、二重線により接続を表します。

SysLog は、リクワイアされるために必要となっています。

_images/rpc.png

二重線で示される接続は、次のような RPC チャンネルコンポーネントに置き換えられます。 RPC チャンネルコンポーネントは、RPC チャンネルの種類によって内容が異なり、この図はトランスペアレント RPC の例になります。 この図は、説明のためのもので、通常この図は、用いません。

_images/rpc-expand.png

アロケータ

アロケータ、図のように結合の線に近接した▼からアロケータセルの受け口に結合の線を引いて表します。 TECS CDL で組上げ記述する場合には、受け口側で、アロケータセルを指定します。 コンポーネント図は、その記述に沿うものとなります。

_images/allocator.png

TECS ジェネレータにより、呼び元、および呼び先に send または receive 指定された引数に対応するアロケータ呼び口が内部生成されます。 この図は、内部生成されたアロケータ呼び口の結合を示します。 この図は、説明のためのもので、通常この図は、用いません。

_images/allocator-internal.png

多段リレーモデル

多段リレーモデルを表すTECS コンポーネント図です。 多段リレーモデルでは、アロケータにより確保されて send または receive 指定された引き数として受け口に渡されたメモリ領域を、再び呼び口からsend 指定された引き数として呼び出す際に引き渡します。 TECS CDL で組上げ記述する場合には、このように最も右側の受け口で、アロケータセルを指定します。

_images/relay.png

TECS ジェネレータにより、それぞれの呼び元、および呼び先に send または receive 指定された引数に対応するアロケータ呼び口が内部生成されます。 この図は、内部生成されたアロケータ呼び口の結合を示します。 この図は、説明のためのもので、通常この図は、用いません。

_images/relay-internal.png

TECS コンポーネント記述言語 (TECS CDL)

目次:

概要

TECS コンポーネント記述言語 (TECS CDL) の記述方法について、説明します。

対応バージョン

TECS ジェネレータ V1.3.1.0 の実装に対応します。

それ以降の新機能については「TECS V1.4.0 ~ V1.7.0 の新機能」の項を参照して下さい。

共通事項

TECS CDL 全体にわたり共通する仕様を説明します。 TECS CDL の文法は、C 言語の文法と親和性のあるものとなっています。

  • CDL ファイル

    TECS CDL は CDL ファイルに格納します。 CDL ファイルの拡張子は '.cdl' です。 CDL ファイルは、通常文字コードとして UTF-8 を用います。しかし、7bit ASCII を含む文字コードであれば、他の文字コードも可能です。 ただし sjis のようにマルチバイト文字の2バイト目以降に特殊な文字が来る可能性のある文字コードは、扱えるとは限りません。

  • 字句

  • 名前有効範囲

  • 名前付けの慣習

【補足説明】TECS ジェネレータ V1.3.0.1 の実装では、sjis, euc, utf-8, 8bit-ASCII を扱うことができます。

TECS CDL の記述内容

TECS CDL に記述する内容には、以下のものがあります。 前方参照に制約があるため、基本的には、以下の順序で記述します。前方参照とならない場合には、この順序に限定されません。

シグニチャ、セルタイプ、複合セルタイプの名前衝突を防ぐ目的で、ネームスペース記述を用いることができます。 セル(間接的にセルタイプを含む)のレイアウト、および名前衝突を防ぐ目的で、リージョン記述を用いることができます。

未記載事項

  • 実装済み * アロケータに関する説明 * 構造体メンバの指定子

  • 未実装 * リージョンのクラス属性 * 動的結合

字句

TECS CDL の字句には、以下のものがあります。

  • キーワード

  • 指定子キーワード

  • 識別子

  • リテラル

  • 型名

  • 記号

字句の区切りとして 0 個以上または、1 個以上の空白文字を使用します。

16 進数で 20 以下の文字コードは空白文字として扱われます。

TECS CDL の字句は1文字以上の空白文字によって区切られます。 ただし、空白文字がなくても字句が決定できる場合には、この限りではありません。

【制限】全角の空白文字は、空白文字とはみなされない。

キーワード

以下の語は、キーワードです。 キーワードは、識別子として用いることができません。

attr bool_t C_EXP call cell celltype char char_t composite const Descriptor double64_t entry enum enum16 enum32 enum64 enum8 factory FACTORY false float32_t generate import import_C int int128_t int16_t int32_t int64_t int8_t long namespace region require schar_t short signature signed struct true typedef uchar_t uint128_t uint16_t uint32_t uint64_t uint8_t unsigned var void volatile

指定子キーワード

以下の語は、指定子キーワードです。

指定子を記述可能な箇所 ('[', ']' に囲まれた箇所) においてのみキーワードとして扱われます。 従って、指定子キーワードを識別子として用いることができます。 ただし、指定子キーワードとして扱われる箇所に現れる識別子としては用いることができません。 例えば size_is などの引数に現れる場合には、指定子キーワードとは異なる語を用いる必要があります。

active allocator choice class context count_is deviate omain dynamic id idx_is_id in in_through inline inout linkunit node nullable omit oneway optional out out_through prototype receive ref_desc send singleton size_is string through to_through

識別子

識別子は、TECS CDL で定義する種々の物 (シグニチャ、セルタイプ、セルなど) の名前として用います。

識別子は、アルファベットまたは '_' で始まり、アルファベット、数字または '_' の繰返しからなります。

TECS CDL において識別子の長さを規定しませんが、CDL 記述を C 言語に翻訳する際にネームスペース、セルタイプ名、セル名、呼び口名、受け口名が連結されるため、連結語の長さが C コンパイラの識別可能な長さを超えない配慮が必要になります。 今日の多くのコンパイラは 255 文字までの長さの識別子を識別可能です。少なくとも、この長さに収まるようにする必要があります。

リテラル

リテラルは、 TECS CDL において値を表現するものです。

リテラルには、以下のものがあります。

  • 16進数リテラル (HEX_CONSTANT)

  • 8進数リテラル (OCTAL_CONSTANT)

  • 整数リテラル (INTEGER_CONSTANT)

  • 浮動小数リテラル (FLOATING_CONSTANT)

  • 文字列リテラル (STRING_LITERAL)

  • 山括弧文字列リテラル (AB_STRING_LITERAL)

  • 文字リテラル (CHARACTER_LITERAL)

  • ブール値リテラル (TRUE / FALSE)

【補足説明】上記の括弧内は、TECS ジェネレータの終端記号の名前である。

16進数リテラル:: '0x' で始まり、0-9 および/または a-f, A-F の 1 個以上繰返しです。

8進数リテラル:: '0' で始まり、0-7 の 1 個以上繰返しです。

浮動小数リテラル:: 1-9 で始まり 0-9 の繰返し(整数部)に続いて '.'、続いて 0-9 の 0 個以上の繰返し(小数部)、さらに続いて 'e' または 'E' に続く、符号 '+' または '-' (省略化)、最後に 0-9 の 1個以上の繰返し('e' または 'E' 以降、ここまで指数部)です。 小数部、指数部は省略可能である。ただし、0 に続いて '.' が続く場合は、8進数リテラルに優先して浮動小数として扱われます。

【補足説明】浮動小数リテラルは C 言語のそれよりも若干制限が強い。例えば ".1" は C 言語では正当な浮動小数であるが、TECS CDL においては浮動小数とはみなされない。

整数リテラル:: 1-9 で始まり、0-9 の 0 個以上繰返し、または '0' です。

文字列リテラル:: ダブルクオート '"' で囲まれた文字列です。

文字列リテラルに、ダブルクオートを含めるためには、バックスラッシュ '' を前置します。 文字列リテラルが改行文字を含む場合にも、行末に バックスラッシュ '' を置きます。

C 言語においては、バックスラッシュを前置することで改行コードなどの制御コードを記述しますが TECS CDL においては解釈せず、バックスラッシュの削除も行いません。 これは、文字列リテラルがそのまま C 言語へ渡されるためです。

ただし、factory または FACTORY の引数として与えられた場合には別に扱われます。以下は、制御文字コードに置換されます。
  • "n" … 改行コード

  • "r" … 復帰コード

  • "f" … フィードコード

  • "t" … TAB コード

これ以外に、バックスラッシュが前置されている場合、バックスラッシュは取り除かれ、それに続く文字は無条件に文字列の一部として扱われます。

【参照実装における制限】漢字を扱うための文字コードは SJIS, EUC, UTF8 を用いることができる。ただし SJIS を用いる場合には、C コンパイラが SJIS を扱えるものを用いなくてはならない。SJIS の文字コードには、第二バイトに

0x5c ('', バックスラッシュ)

を含むものがある。SJIS を扱えない C コンパイラでは、第2バイトの 0x5c をエスケープ文字として扱ってしまう。

山括弧文字列リテラル:: 山括弧 '<', '>' で囲まれた文字列です。

この文字列には、アルファベットの大文字、小文字、'_', '.', ' ' (空白文字) のみを用いることができます。

文字リテラル:: シングルクオートで囲まれた一文字です。

文字リテラルは、その文字コードの整数として扱われます。 バックスラッシュを前置することで、バックスラッシュに続くもう一文字を文字リテラルの一部として扱われます。

【参照実装における制限】多バイト文字を一文字として扱うことができる。ただし、C コンパイラが多バイト文字を、文字定数として扱うことができる必要がある。ポータビリティの観点からは、用いることは好ましくない。

ブール値リテラル:: true または false です.C 言語においては、整数の 1 と 0 に対応付けられます。

型名

typedef により定義される型名は、識別子と同じです。

ただし、typedef により定義されて以降は、「型名」として扱われ識別子とは区別されます。 このため typedef により型名として定義された識別子は、変数名、関数名の識別子としては用いることができません。

【参照実装における制限】型名を識別子とは別のリテラルとして扱うのは、実装上の理由による。

コメント

コメントとして記述された文字列は、TECS CDL の記述として解釈されません。 コメントの文字列は、以下の2通りの方法で記述できます。

  • '/', '/' で囲んだ文字列

  • '!//' から行末までの文字列

'/' と '/' の間には、改行文字を含むことができる。しかし、入れ子にすることはできません。

TECS CDL の言語仕様として定義する型には、TECS CDL の文法に予め組み込まれた組込み型と、typedef による型定義によって後から付け加えて使用する typedef 型があります。

型の分類

型の小分類

型名

値の範囲

備考

組込み型

値の範囲が明瞭な型

int8_t

-128 .. 127

8bit 有符号整数

int16_t

-32768 .. 32767

16bit 有符号整数

int32_t

-2147483648 .. 2147483647

32bit 有符号整数

int64_t

-9223372036854775808 .. 9223372036854775807

64bit 有符号整数

uint8_t

0 .. 255

8bit 無符号整数

uint16_t

0 .. 65535

16bit 無符号整数

uint32_t

0 .. 4294967295

32bit 無符号整数

uint64_t

0 .. 18446744073709551615

64bit 無符号整数

float32_t

±3.4028235E38~±1.4E-45

32bit 単精度浮動小数 (IEEE754)

double64_t

±1.7976931348623157E308~±4.9E-324

64bit 倍精度浮動小数 (IEEE754)

char_t

-128 .. 255

値としては 8bit 有符号、無符号の どちらも受けつける

値の範囲が明瞭な型

(C言語由来の型)

非推奨

char

実装依存

int

実装依存

short

実装依存

long

実装依存

float

実装依存

double

実装依存

typedef 型

t_stddef.h で 定義される型

int_t

実装依存

uint_t

実装依存

long_t

実装依存

ulong_t

実装依存

tecs.h で定義される型

short_t

実装依存

ushort_t

実装依存

組込み型

組込み型は、 TECS CDL の文法の一部として予め組み込まれた型です。 C 言語に由来しない型でも TECS CDL 記述内では typedef することなく使用できます。 しかし、C 言語のソースをコンパイルする段階では、組込み型を typedef するヘッダファイルがインクルードされている必要があります。 これは、ヘッダファイル tecs.h または t_stddef.h に記述されています。通常 import_C により、このいずれかを取り込みます。

C 言語に由来する型とは、char, short, int, long, float, double です。 このうち char, short, int, long は signed, unsigned で修飾することができます。 しかし TECS CDL で、すべての C 言語由来の型が扱えるわけではありません。 short int, long signed, unsigned など、C 言語では有効な型であっても、TECS CDL 有効な型とは限りません。

【補足説明】intN_t が組み込み型である理由は、最大値、最小値が明瞭になり、値の範囲をチェックできるためである。 intN_t を int や short などの型の typedef 型としてしまうと、最大値、最小値を tecsgen の段階では確定することができず、チェックできなくなってしまう。

typedef 型

ここに挙げた typedef 型は、TECS 仕様の一部とみなされる型です。 typedef 型は typedef により定義される型であり、ヘッダファイルを取り込んで typedef による型定義をしない限り使用することができません。

tecs.h と t_stddef.h

組込み型の C 言語での定義および、typedef 型を TECS CDL による記述で使用するために必要となる型の定義は、tecs.h に含まれます。 tecs.h は t_stddef.h をインクルードしています。 t_stddef.h は TOPPERS 新世代カーネル統合仕様に基づいて定義されるものであり、TECS で定義する型以外の型定義を含みます。

tecs.h では t_stddef.h で定義する型に加えて char_t, uchar_t, schar_t, short_t, ushort_t, int128_t, uint128_t が定義されます。

通常 TECS CDL による記述では tecs.h を直接的または間接的に import_C で取り込む必要があります。 ここで間接的にとは、import_C で取り込まれるヘッダファイルからインクルードされることであります。

【補足説明】typedef 型を TECS CDL による記述で用いないのであれば、必ずしも tecs.h を import_C で取り込む必要はないが、生成された C 言語のプログラムをコンパイルする際には、何らかの手段により tecs.h をインクルードする必要がある。 ターゲットがTOPPERS 新世代カーネル統合仕様に準拠しない環境である場合 tecs.h や t_stddef.h 以外で C 言語に由来しない組込み型や typedef 型の定義をし、それらを import_C により取り込んでもよい。

TECS CDL で記述された式は、コンポーネント記述が解釈されるときに評価されます。

式を評価するのは、以下の場合です。

  • 初期化子

  • 呼び口配列、受け口配列の添数

  • 指定子 (size_is, count_is, string, id) の引数

関数引き数や構造体メンバの size_is, count_is, string で他のパラメータを参照している場合、定数として値が求まらないものについては、型の導出のみを行います。

以下の表は、式を構成する部分式と演算内容についてまとめたものです。 上から順に優先度の高い演算となります。

種類

構成

内容

基本式

識別子

定数、属性、関数の引数の参照

'true'

ブール型の真

'false'

ブール型の偽

整数リテラル

整数値

浮動小数リテラル

実数値

8進数リテラル

8進整数値

16進数リテラル

16進整数値

文字リテラル

文字列

文字列リテラルリスト

文字列 (分割記述)

'(' 式 ')'

後置式

基本式

基本式

後置式 '![' 式 ']'

配列参照

後置式 '.' 識別子

構造体メンバ参照

後置式 '->' 識別子

構造体メンバ参照(ポインタの場合)

単項式

後置式

後置式

'&' キャスト式

変数のアドレス

'*' キャスト式

ポインタの間接参照

'+' キャスト式

オペランドの値

'-' キャスト式

オペランドの符号反転

'~' キャスト式

オペランドのビット単位の補数

'!' キャスト式

オペランドの論理否定

'sizeof' 単項式

オペランドのバイト数

'sizeof' '(' 型名 ')'

オペランドのバイト数

キャスト式

単項式

単項式

'(' 型名 ')' キャスト式

オペランドの型変換

乗除式

キャスト式

キャスト式

乗除式 '*' キャスト式

乗算

乗除式 '/' キャスト式

除算

乗除式 '%' キャスト式

剰余

加減式

乗除式

乗除式

加減式 '+' 乗除式

加算

加減式 '-' 乗除式

減算

シフト式

加減式

加減式

シフト式 '<<' 加減式

ビット左シフト

シフト式 '>>' 加減式

ビット右シフト

関係式

シフト式

シフト式

関係式 '<' シフト式

比較(右辺が大きければ真)

関係式 '>' シフト式

比較(左辺が大きければ真)

関係式 '<=' シフト式

比較(右辺が大きいか等しければ真)

関係式 '>=' シフト式

比較(左辺が大きいか等しければ真)

等価式

関係式

関係式

等価式 '==' 関係式

比較(等しければ真)

等価式 '!=' 関係式

比較(等しくなければ真)

and式

等価式

等価式

and式 '&' 等価式

ビット単位の論理積

exor式

and式

and式

exor式 '^' and式

ビット単位の排他的論理和

or式

exor式

exor式

or式 '|' exor式

ビット単位の論理和

論理AND式

or式

or式

論理AND式 '&&' or式

論理積

論理OR式

論理AND式

論理AND式

論理OR式 '||' 論理AND式

論理和

条件式

論理OR式

論理OR式

論理OR式 '?' 式 ':' 条件式

第1オペランドが真なら第2オペランド、偽なら第3オペランド

条件式

条件式

定数式

条件式

条件式

基本式における識別子

基本式における識別子は、以下のいずれかです。

  • 定数定義文により定義された定数

  • 式が関数仮引き数の size_is, count_is, string 指定子の引き数として用いられる場合、参照される他の仮引き数

  • 式が属性の size_is 指定子の引数として用いられる場合、参照される他の属性

  • 式が構造体メンバ変数の size_is, count_is, string 指定子の引数として用いられる場合、参照される他の構造体メンバ変数

  • 内部変数の初期化子

定数式の一部に C_EXP を用いることはできません。

【補足説明】C_EXP は単一の初期化子として用いるものであり、式の一部として用いることはできない。

文字列リテラルリスト

文字列リテラルリストは、1つ以上の文字列を並べたものです。 文字列リテラルリストに含まれる文字列は連結されて、一つの文字列リテラルとして扱われます。

【制限】整数については、無限精度により評価される。このため無符号整数と有符号整数との演算は、有符号で行われる。

【制限】型の格上げは暗黙的に行われるが、格下げは暗黙的に行われない。キャストが必要である。

【制限】文字列リテラルは、(char_t *) 以外の型にキャストできない

【制限】ブール型は、整数型にキャストしない限り、他の型との演算はできない

【制限】 後置式に関数呼び出しと後置インクリメント、デクリメント演算子がない

【制限】 前置式に前置インクリメント、デクリメント演算子がない

【制限】式にコンマ演算子がない

初期化子

初期化子は、定数式、集成型初期化子リストまたは C_EXP 初期化子です。 このいずれを取りうるかは、初期化される変数の型によります。

定数式は、整数型、浮動小数型、ブール型、ポインタ型を初期化することができます。ただし、size_is 指定されたポインタ型は定数式では初期化できません。

集成型初期化子

集成型初期化子は、'{', '}' で囲まれた初期化子リストです。 集成型の初期化子は、構造体型、配列型、size_is 指定されたポインタ型を初期化することができます。

【参照実装における制限】size_is 指定された構造体へのポインタ型は初期化子を指定できない。結果として var にのみ用いることができる。

C_EXP 初期化子

C_EXP 初期化子は、初期化する変数が集成型(構造体型、配列型)でない場合に、初期化子として指定することができます。

C_EXP 初期化子は、文字列リテラルを引数に取ります。 引数の文字列リテラルは、ジェネレータの出力の C 言語初期化子として出力されります。 ヘッダファイルで define 定義される値を参照するために使用することが意図されています。

プラグイン引数

プラグイン引数は、文字列定数です。

プラグイン引数は、プラグインモジュールによって解釈されるため各プラグインの仕様に依存しますが、以下の仕様が基本です。

  • '=' の左辺にパラメータ名、右辺に文字列を置く

  • 左辺のパラメータ名は、識別子である

  • つまりパラメータ名は、先頭文字はアルファベットか '_' で、2文字目以降はアルファベット, '_' または数字である

  • ',' で区切ることにより、複数のパラメータをプラグイン引数として渡すことができる

  • 右辺文字列の前後の空白文字は取り除かれる(" で囲まれている場合を除く)

  • 右辺文字列中のダブルクォート'"' は、バックスラッシュ'' で エスケープする必要がある

  • 右辺文字列中にカンマ ',' を含む場合には、右辺文字列全体を '"' で囲む必要がある

  • 右辺文字列中にダブルクォート'"' とカンマ ',' を含む場合には、右辺文字列全体を '"' で囲む必要がある

  • さらに右辺文字列中のダブルクォート'"'にカンマ ',' が続く場合は、カンマ ',' もバックスラッシュ '' でエスケープする必要がある

【記述例】

"param0 = val str" … '=' の左辺にパラメータ名、右辺に値の文字列 "param1 = val str, param2 = val str2" … ',' で連結 "param3 = "val str, val str2"" … 右辺文字列が ',' を含む場合 " で囲む "param4 = C_EXP( "MAIN_PRIORITY" )" … 右辺文字列が '"' を含む場合 "param5 = " "," "" … 右辺文字列が ',' と '"' を含む場合 '","' と解釈

名前有効範囲

TECSL CDL では用いる名前には、大域的な名前と局所的な名前とがあります。 局所的な名前は、単一の識別子です。 大域的な名前は、ネームスペース識別子です。

名前有効範囲(スコープ)は、単一の識別子によって一意に物を識別できる範囲のことです。 名前有効範囲には、属する物により、以下の 6 種類があります。

  • 一般名前有効範囲

  • シグニチャ関数名前有効範囲

  • 仮引数名前有効範囲

  • セル属性名前有効範囲

  • タグ名前有効範囲

  • フィールド名前有効範囲

同じ名前有効範囲では、名前として重複した識別子を与えることはできません。 同じ名前有効範囲で、異なる物に同一の識別子を名前として与えることを名前の衝突と呼びます。 ただし一般名前有効範囲においては、名前が有効となる境界を設けることができます。

一般名前有効範囲

以下の物は、一般名前有効範囲に属します。

  • 定数

  • 型定義

  • シグニチャ

  • セルタイプ

  • 複合セルタイプ

  • セル

  • ネームスペース

  • リージョン

一般名前有効範囲は、ネームスペースまたはリージョンにより境界を設けることができます。 ネームスペースやリージョンは、入れ子構造をとることができ、内側のネームスペースと外側のネームスペースでは異なる有効範囲となります。

ネームスペースには、シグニチャとセルタイプと複合セルタイプを置くことができます。 リージョンには、セルのみを置くことができます。 定数、型定義は、ネームスペースによる衝突回避を行うことはできません。

名前の有効範囲は、属するネームスペースおよびその内側のネームスペースです。 つまり内側のネームスペースから外側のネームスペースの物は直接参照できます。

この時、内側のネームスペースと外側のネームスペースで重複した識別子を用いられていても名前の衝突は生じません、内側の物から重複した名前を持つ外側の物を局所的な名前によっては参照することができません。 重複した名前を持つ外側の物は隠蔽されます。

シグニチャ関数名前有効範囲

シグニチャ内の関数名は、シグニチャ関数名前有効範囲に属し、それぞれのシグニチャごとに名前有効範囲が区切られます。

仮引数名前有効範囲

関数の仮引数は、仮引数名前有効範囲に属し、関数ごとに名前有効範囲がくぐられます。

セル属性名前有効範囲

以下の物は、セル属性名前有効範囲に属し、セルタイプごとに名前有効範囲が区切られます。

  • 呼び口名

  • 受け口名

  • 属性名

タグ名前有効範囲

構造体のタグは、タグ名前有効範囲に属します。

【制限事項】タグ名前有効範囲は、ネームスペースごとに区切られていない(ネームスペース下に構造体定義を置くことはできない)。

フィールド名前有効範囲

構造体のフィールド名は、フィールド名前有効範囲に属し、構造体ごとに名前有効範囲が区切られます。

名前付けの慣習

名前付け規則は、TECS CDL 文法の一部ではなく、慣用的なものです。

TECS では、コンポーネント実装において、名前を連結したグローバル名を使用します。 このため不用意な名前を用いると、連結した名前が、衝突する可能性があります。 名前付け規則に従って接頭文字を付加することは、名前の衝突を避ける効果もあります。

接頭文字

要素

接頭文字

その他

備考

シグニチャ

s

2文字目は大文字

sMotor, sLamp

タスクコンテキスト

シグニチャ

si

3文字目は大文字

siTask

非タスクコンテキスト (non-task)

シグニチャ

sn

3文字目は大文字

snInit

カーネル外コンテキスト

関数

なし

先頭は小文字

rotateRight

引数

なし

先頭は小文字

goalPositionX

セルタイプ

t

2文字目は大文字

tMotor, tLamp

セル

なし

先頭は大文字

Motor,Lamp

呼び口

c

2文字目は大文字

cMotor

受け口

e

2文字目は大文字

eMotor

属性

なし

先頭は小文字

countLimit

内部変数

なし

先頭は小文字

upCount

【参照実装における制限】定数は、上記の規則にはないが、属性、内部変数、関数の名前と重複しないこと。定数はヘッダファイルで define によって定義されるため、定数と他のものの名前が重複すると、Cコンパイラでコンパイルするときに、分りにくいエラーが発生する。

単語区切り

名前として、複数の単語を連結したものを用いる場合、以下のようにします。

  • 連結する単語の1文字目は、大文字とする

  • 単語と単語は直接連結する( '_' などを置かない)

型情報

通常、型に関する情報を名前に含めないが、以下の場合には名前に含めます。

  • 属性、変数、引き数がポインタ型の場合、'p_' を前置する

  • 属性、変数、引き数がパケットの場合、'pk_' を前置する

  • 属性、変数、引き数がパケットへのポインタ型の場合、'ppk_' を前置する

グローバル名

グローバル名は、主としてコンポーネント実装において用いられますが、TECS CDL の記述においても、一部グローバル名を指定する場合があります。 グローバル名は、属するネームスペース名にアンダスコア '_' を付加したものを前置きしたものです。

グローバル名の凡例を以下に示します。

対象となるもの

グローバル名

シグニチャ

(ネームスペース名) + '_' + (シグニチャ名)

セルタイプ

(ネームスペース名) + '_' + (セルタイプ名)

受け口関数

(ネームスペース名) + '_' + (セルタイプ名) + '_' + (受け口名) + '_' + (関数名)

セル

(リージョン名) + '_' + (セル名)

ここで + は文字列の連結を表わします。

ネームスペースが親ネームスペースに属する場合、親ネームスペース名にアンダスコア '_' を付加したものを、更に前置きします。 ルートネームスペースに属する場合には、ネームスペース名および '_' を含みません。 リージョンも、ネームスペースと同様です。

呼び口関数には、グローバル名が与えられることはありません。 呼び口関数は、セルタイプコードの中でのみ用いられるためです。

【補足説明】セルのグローバル名は、セルタイプコードの中で用いられることはない。

【補足説明】シグニチャのグローバル名についても、TECS ジェネレータで生成されるヘッダファイル内で用いられるだけで、セルタイプコードで記述することはない。

前置部

型定義など、前方参照できないため、参照される前に記述する必要があります。

前置部には、以下のものを記述することができます。

C 言語ヘッダのインポート(import_C)

C 言語で記述したヘッダファイルをインポートするには import_C を用います。

【記述例】

import_C( "my_header.h" );

実際に取り込まれるのは、型定義 (typedef) だけです。

マクロ定義 (#define) を含め、その他の記述は、取り込まれません。

【注意】 マクロ定義の参照には C_EXP を用いる。セルタイプの属性の項を参照。

【注意】 C++ 言語のヘッダファイルを取り込むことは、できない。

CDL ファイルのインポート(import)

CDl ファイルをインポートするには import を用います。

CDL ファイルを再利用する部分と、アプリケーション固有の部分に分けて記述する場合や、 CDL ファイルを分割して記述したい場合に用います。

再利用する部分の CDL ファイルをインポートするには、以下のように記述します。

【記述例】

import( <reusable.cdl> );

【補足】この場合、resuable.cdl 内に記述されたセルタイプは、すでに作成済とみなされ、TECS ジェネレータはテンプレートファイルを生成しない。

CDL ファイルを分割して記述したい場合は、以下のように記述します。

【記述例】

import( "appl.cdl" );

【補足】この場合 appl.cdl 内に記述されたセルタイプは、開発中とみなされ、TECS ジェネレータはテンプレートコードを生成する。

型定義(typedef)

型定義は、C 言語と同様です。

【記述例】

typedef  double64_t LengthM;
typedef  double64_t WeightKg;
typedef  int64_t    size64_t;

構造体(struct)

構造体のタグとメンバーの記述は、C 言語と同様です。

【記述例】

struct tag {
  int8_t  count;
};

【補足】構造体変数を定義することはできません。

列挙 (enum)

【注意】実装されていません。

定数(const)

定数は、C 言語の定数と同様に記述します。

【記述例】

const double64_t PI = 3.14159265;

定数は、CDL ファイル内の式を記述するところで参照できます。

【補足】TECS ジェネレータは、定数を global_tecsgen.h のマクロとして出力する。

シグニチャ記述

シグニチャ記述は、シグニチャを定義するものです。 シグニチャとは、コンポーネント間をインタフェースする関数頭部の集合で、呼び口、受け口に対応付けられます。

【記述例】

signature sInputOutput {
   ER  setOutput( [in]int8_t val );       // in 基本指定子
   ER  getInput( [out]int8_t *val );      // out 基本指定子
   ER  noParameter( void );               // 引数なし
};

ここで siganture はキーワードであり、sInputOutput はシグニチャ名です。'{', '}' で囲まれた中に ';' で区切って 0 個以上の関数頭部を列挙します。 慣習として、シグニチャ名は 's' で始めます。

関数の個数が 0 個の場合、コンポーネント間に何らかの関係があるが、実際には関数の呼び出しが行われないことを表します。 リージョン間のスループラグインは適用されません。

シグニチャ記述の指定子

コールバック(callback)指定子

コールバック(callback)指定子は、コールバックに用いられるシグニチャであることを指定します。 コールバック関数を呼び出すための呼び口、受け口に用いられることが意図されていることを表します。

コールバック指定されたシグニチャに対応付けられた受け口から呼び口への、逆結合が可能です。 組上げ記述 (セル記述)の逆結合の侯を参照してください。 通常の結合を用いることもできます。

コンテキスト(context)指定子

コンテキスト(context)指定子は、シグニチャがどのコンテキストで使用されるものかを指定します。 以下のいずれかを指定します。

  • "task" … タスク部

  • "non-task" … 非タスク部

  • "any" … いずれのコンテキストも可能

【記述例】

[context( "task" )]
  signature sSignature {
};

コンテキストが指定されていないシグニチャは、 "task" が指定されたものと仮定されます。

【補足説明】コンテキストの指定は、コンポーネントの設計者、および利用者に対するメモである。TECS ジェネレータは、この記述に基く検査はしない。

逸脱(deviate)指定子

逸脱(deviate)指定子は、関数の引数が、以下の規定に合わない(逸脱)ことを表します。

関数頭部

関数頭部は、C 言語と同様に記述しますが、引数には入出力方向を示する基本指定子を記述する必要があります。

関数に引数がない場合、 void を記述します。

関数頭部の指定子

一方向(oneway)指定子

一方向(oneway)指定子は、呼び元から呼び先へのみ値を渡すことができることを表します。 つまり oneway 指定された関数では、引数に in または send 基本指定子のみ指定することができます。

一方向指定された関数は、非同期実行される可能性があります。 一方向指定された関数が、戻り値を返すことはできますが、非同期実行された場合には、実際には返されません。 戻り値は、非同期実行を実現するコンポーネントから返されます。

一方向指定された関数が非同期実行される場合、in 基本指定子が指定されたポインタ型の引数について、ポインタが指している先の値のコピーが作成され、コピーへのポインタが渡されます。

【補足説明】一方向指定された関数が非同期実行される場合、in 基本指定子が指定されたポインタ型の引数について、コピーが取られるかどうかは、スループラグインの実装にかかっている。 一方向指定された関数を非同期実行させるスループラグインの実装者は、コピーが取られるように設計しなくてはならない。

ポインタ型の引数

ポインタの多重度は、以下のいずれかです。

  • 単一のポインタ

  • 二重ポインタ

ただし、receive 引数の場合は、上記のポインタ型の値を渡すため、もう一重、ポインタの多重度が増えます。

また、二重ポインタ(receive においては三重ポインタ)は、以下のいずれかの場合に用いることができます。

  • size_is と string の両方の指定子をを伴う場合

  • ポインタの指すものが構造体で、size_is が指定されている場合

さらに in 引数の場合、ポインタが指すものの型に const 指定子を付加する必要があります。

ポインタ型の引数が配列(文字列を含む)を指す場合には、ポインタ指定子を指定する必要があります。

引数に void 型のポインタを用いることはできません。

上記の条件を満たさない場合は、逸脱 (deviate) となります。

引数の指定子

基本指定子

基本指定子には、in, out, inout, send, receive があります。

以下の表は、それぞれの基本指定子について、データを渡す方向、非ポインタ型引数の可否、適用可能なポインタの多重度、渡されたメモリ領域を受け取った側がデアロケートする必要の有無を表します。 なお、二重ポインタ (receive においては三重ポインタ)は、ポインタ型の引数の項で示した条件を満たす場合に適用できます。

データを渡す方向

非ポインタ型

ポインタ多重度

デアロケート

備考

in

呼び元→呼び先

単一、二重

不要

ポインタ型の場合 const が必要

out

呼び元←呼び先

不可

単一、二重

不要

ポインタの参照する先のデータを返す

inout

呼び先⇔呼び元

不可

単一、二重

不要

send

呼び元→呼び先

不可

単一、二重

必要

引数としてアロケータシグニチャを取る

receive

呼び元←呼び先

不可

二重、三重

必要

引数としてアロケータシグニチャを取る

C 言語におけるポインタ型がの引数は、以下の点であいまいさがあります。

  • 呼び元から呼び先に値を渡すのか、その逆かが不明

  • ポインタが指す記憶域を、受け取った側が解放する必要があるのか、ないのか、不明

  • ポインタが、非配列を指すのか、配列を指すのか不明、また配列を指す場合、その大きさが不明

TECS CDL では、上記の問題を以下のように克服しています。

  • データを渡す方向を、基本指定子で表す

  • 記憶域の解放の要否は send, receive 基本指定子により表す

  • ポインタが非配列を指すのか、配列を指すのかを、配列を指す場合、その大きさをポインタ指定子により表す

in/out/inout 指定子の、いずれも記憶域は呼び元が準備します。

【記述例】

signature sInOut {
   ER      in( [in,string]char *buf );
                        /* in では、呼び元が文字列を用意する */
   ER      out( [out,string(64)]char *buf );
                        /* out では、呼び元が長さ 64 のバッファを用意する */
   ER      inout( [inout,string(*len)]char *buf, [inout]uint16_t *len );
                        /* inout では、呼び元が長さ len のバッファを用意する */
                        /* *len の出力方向は文字列長さを返す */
};

out 引数で文字列のコピーではなく、文字列へのポインタを返すことは逸脱になります。 例えば、エラーメッセージのような固定の文字列を出力引数で得る場合、以下の例のように逸脱となります。

【記述例】

[deviate]
signature sOutStringPointor {
   ER      getErrorMessage( [out]const char_t **message );
};

send/receive 指定子をしたシグニチャの例を示します。

【記述例】

signature sSendReceive {
   ER      sendMessage( [send(sAlloc),size_is(len)] int8_t *buf, [in]int16_t len );
   ER      receiveMessage( [receive(sAlloc),size_is(len)] int8_t **buf, [out]int16_t len );
};
ポインタ指定子

ポインタ指定子は、ポインタ型の引数に対して用いることができます。 ポインタ指定子には size_is, count_is, string, nullable があります。 ポインタが指すものが非配列の場合、size_is, count_is, string のいずれも指定しません。

size_is:: ポインタは配列を指すことを表すとともに、配列の大きさを引数で表す。

(配列の大きさであり、バイト数ではない) 多重ポインタに指定された場合、パラメータに最も近いポインタの大きさを指定する。 ただし receive においては、パラメータから2番目のポインタに対する指定となる。 size_is は引数を取るが、定数またはパラメータリストに内にある他の引数を含み、整数型を返す式である。 size_is の引数は、呼び元で指定する。receive の場合は呼び先で指定してもよい。 size_is は第二引数をとることができる。第二引数は size_is の最大値を定数で指定する。 セルタイプコードにおいて、size_is の引数値が 0 となる場合、ポインタ値として NULL を渡す。

count_is:: count_is は size_is を補助するもので、配列の有効な要素が含まれる個数(最大添数+1) を表す。

count_is は省略することができる。その場合、size_is で指定された大きさが有効な要素数とみなされる。 count_is は引数を取るが、定数またはパラメータリストに内にある他の引数を含み、整数型を返す式である。 count_is の引数は、ポインタが指す先に値を設定した側が行う。 in, send の場合は、呼び元が指定する。 out, receive の場合は、呼び先が指定する。 inout の場合は、呼び先、呼び元が、それぞれ設定する。

string:: ポインタは文字列を指すことを表す(char 以外の型の場合は、NULL 終端された配列)。

多重ポインタに指定された場合、パラメータから最も遠い (型指定子にもっとも近い) ポインタに対する指定となる。 size_is とともに指定された場合は、文字列へのポインタの配列であることを表す。つまり二重ポインタ (receive の場合は三重ポインタ)となる。 string は引数をとることもできる。引数は、定数またはパラメータないにある他の引数を返す式で、文字列の際だし長さを表す。文字列が最大長さに達する場合は、NULL 終端されていない。 string の引数は、呼び元で指定する。receive の場合は呼び先で指定してもよい。

nullable:: ポインタは NULL を渡すことがあることを示す。

多重ポインタの場合、パラメータに最も近いポインタが NULL を渡すことがあることを示す。 ただし receive の場合は、パラメータから2番目のポインタが NULL を渡すことがあることを示す (recieve 指定されたパラメータとしては NULL を渡すことはできない)。 size_is と nullable を同時に指定することはできない。 この場合、size_is のみを指定し、セルタイプコードにおいて size_is の引数値として 0 を渡す (size_is の項も参照)。

ポインタ指定子をしたシグニチャの例を示します。

【記述例】

signature sInputOutput {
   ER      putMessage( [in,size_is(len)] const int8_t *buf, [in]int16_t len );
   ER      getMessage( [out,size_is(*len),count_is(*len)] int8_t *buf, [inout]int16_t *len );
};

アロケータシグニチャ

アロケータは、メモリを割付けるコンポーネントのことです。 アロケータシグニチャは、アロケータの受け口が持つシグニチャのことです。 アロケータシグニチャは、send または receive 指定子の引き数として用いられます。 アロケータのシグニチャは、少なくとも alloc と dealloc 関数を持つ必要があります。

alloc 関数の第一引数は、アロケートしようとするメモリ領域のサイズ(バイト数;整数型)、または、メモリ領域へのポインタを返すポインタとします(二重ポインタ)。 alloc 関数の第二引数は、第一引数が整数の場合、アロケートされたメモリ領域へのポインタを返すポインタとします(二重ポインタ)。

dealloc 関数の第一引数は、デアロケートしようとするメモリ領域へのポインタとします。

alloc, dealloc が、2つ以上の引数を持つとき、through プラグインによって RPC チャネルを生成させるのに、関数の引数に与えるべき値をプラグイン引数として指定します。 仮引数名によってどの引数に対する値かを識別します。 このため alloc と dealloc で同じ仮引数名が指定されると、これらは同じ値を指定されることになります。 もし、異なる値を指定する必要があるのであれば、シグニチャの設計者は、これらに異なる仮引数名を与える必要があります。 関数の引数に与えるべき値として、定数または他の引数を指定できます。

alloc, dealloc 関数に引き数を追加することができます。 また、アロケータシグニチャに realloc 関数などを追加することもできます。

アロケータシグニチャの事例を以下に示します。 アロケータシグニチャは、alloc 関数において、二重ポインタの使用要件を満たさない、また void 型のポインタため、逸脱 (devaite) となります。

【記述例】

[deviate]
signature sAlloc {
  ER alloc( [in]size_t len, [out]void **p );
  ER dealloc( [in]void *p );
};

シグニチャプラグイン記述

シグニチャプラグイン記述は、シグニチャに対しプラグインを適用することを指示します。

【記述例】

generate( SignaturePluginName, sSignatureName, "option..." );
ここで、それぞれのワードは、以下を意味します。
  • generate はキーワードである

  • SignaturePluginName はシグニチャプラグイン名である

  • sSignatureName はシグニチャプラグインを適用するシグニチャの名前である

  • オプションは、プラグインごとに規定される。文字列リテラルを渡す

シグニチャプラグイン記述は、シグニチャを定義した後で記述します。

セルタイプ記述

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

【記述例】

[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$, $$ の置換のみが行われる。

複合セルタイプ記述

複合セルタイプは、1つ以上のセルを組合わせて新しいセルタイプを定義するものです。 複合セルタイプは、複数のセルを組合わせる目的以外に、属性の初期値を与えたり、固定結合させるのに用いることもできます。

【記述例】

[singleton]                             // 複合セルタイプの指定子
composite tCompositeCelltype {          // composite キーワードと複合セルタイプ名
    entry sSignature eEntry;            // entry  キーワード、対応付けられたシグニチャ名、受け口名
    call  sSignature cCall;             // call  キーワード、対応付けられたシグニチャ名、呼び口名
    attr {                              // 属性
        int32_t val = 10;
    };

    // 内部セル
    cell tCelltype Cell1 {
        cCellCall = Cell2.eEntry;       // 内部セルへの結合
        val = composite.val;            // 属性のエクスポート
    };
    cell tCelltype Cell2 {
        cCall => composite.cCall;       // 呼び口のエクスポート
    };
    composite.eEntry => cell2.eEntry;   // 受け口のエクスポート
};

複合セルタイプは、セルタイプと同様に、呼び口、受け口、属性、内部セルを持ちます。 複合セルタイプに組み入れられるセルを「内部セル」と呼びます。

複合セルタイプに属するセルの生成は、複合セルタイプの内部セルのコピーが作成されるとともに、呼び口の結合先や、属性の初期値が整えられます。

複合セルタイプの指定子

アクティブ(active)指定子

アクティブ(active)指定子は、少なくとも一つの内部セルのセルタイプがアクティブである場合、指定する必要があります。

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

シングルトン(singleton)指定子は、少なくとも一つの内部セルのセルタイプがシングルトンである場合、指定する必要があります。

シングルトン(singleton)指定子は、内部セルのセルタイプにシングルトンのものがない場合でも指定できます。 この場合、複合セルタイプのセルは、1つだけ定義することができます。

受け口

複合セルタイプの受け口は、内部セルの呼び口を複合セルタイプの受け口としてエクスポートするものです。 受け口配列とすることもできます。

受け口の指定子

アロケータ(allocator)指定子

アロケータ(allocator)指定子は、リレーアロケータまたは内部アロケータを指定するものです。

リレーアロケータの指定

【記述例】

composite tCompRelayAlloc {
    [allocator( func.a    <= cCallExt.func.a,
         func2.buf <= cCallExt.func2.buf )]
    entry sSig eEntExt;
    call sSig cCallExt;

    cell tRelay Cell1 {
        cCall => composite.cCallExt;
    };

    composite.eEntExt => Cell1.eEnt;
};

T.B.W.

内部アロケータの指定

【記述例】

composite tCompAlloc {
   entry sAlloc eAlloc;
   [allocator(
        func.a=eAlloc,
        func2.buf=eAlloc)]
   entry sSig  eEntExt;
   attr {
       int32_t  num;
   };

   [allocator(
       eEnt.func.a=Alloc.eA,
       eEnt.func2.buf=Alloc.eA)]
   cell tCt1 Cell1 {
       num = composite.num;
   };

   cell tAlloc Alloc{
       num = composite.num;
   };

   cell tAlloc Alloc2{
       num = composite.num;
   };

   composite.eEntExt => Cell1.eEnt;
   composite.eAlloc  => Alloc.eA;
};

T.B.W.

使用しない指定子

以下の指定子は、複合セルタイプの受け口では指定しません。

  • インライン(inline)指定子

インライン(inline)指定子は、セルタイプの実装において必要になるもので、セルタイプの利用者にとって、必要な情報ではありません。

固定結合

複合セルタイプにおいても、セルタイプの 固定結合 と同様に固定結合を指定できます。

内部セルのセルタイプにおいても固定結合が指定されている場合、複合セルタイプでしてされた固定結合と内部セルのセルタイプにおいて指定された固定結合の両方とも結合されます。

呼び口

複合セルタイプの呼び口は、内部セルの呼び口を複合セルタイプの受け口としてエクスポートするものです。 呼び口配列とすることもできます。

呼び口の指定子

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

オプショナル(optional)指定子は、内部セルのセルタイプにおいて optional と指定された受け口をエクスポートする場合に指定します。

属性

複合セルタイプの属性は、内部セルの属性をエクスポートするものです。

複合セルタイプの属性において初期値を与えることができます。 この場合、内部セルの属するセルタイプの属性において指定された初期値を上書きします。

C_EXP の名前置換

composite における名前置換は、特別な規則が適用されます。 composite の attr に現れる C_EXP における $id$, $ct$, $cell$ の名前置換では、複合セルタイプの名前、複合セルの名前に置換されます。 他の名前置換は、複合セルタイプの内部セルが展開されてコピーされたセルの名前によって置換されます。

以下に、複合セルタイプにおける名前置換の例を示します。 次のような TECS CDL 記述があるものとします。

【記述例】

composite tComposite {
  attr {
    int32_t  a = C_EXP( "A_$id$" );
  };
  cell tCelltype Cell1 {
    a = composite.a;
    b = C_EXP( "B_$id$" );
  };
  cell tCelltype2 Cell2 {
    a = composite.a;
    c = C_EXP( "C_$id$" );
 };
};

cell tComposite CompositeCell {
};

CompositeCell における、名前置換の結果は A_$id$ は "A_CompositeCell" に、B_$id$ は "B_CompositeCell_Cell" に、C_$id$ は "C_Composite_Cell2" となります。 属性 a は Cell1, Cell2 ともに、同じ初期値を持つことになります。

【仕様決定の理由】この仕様は、タスクとタスク例外を別のセルとして生成し、それらを composite で一つのセルにまとめる際に、タスクの ID の名前を一致させるために導入された(他の用途でも使用してもよい)

属性の指定子

size_is 指定子

size_is 指定子は、エクスポートする属性の、元のセルタイプ定義において指定されている場合に指定します。

使用しない指定子

以下の指定子は、複合セルタイプの属性では指定しません。

  • 省略(omit)指定子

省略(omit)指定子は、セルタイプの実装において必要になるもので、セルタイプの利用者にとって、必要な情報ではありません。

内部セル

内部セルは、複合セルタイプを構成するセルです。 複合セルタイプは、1個以上の内部セルを持ちます。

呼び口のエクスポート

内部セルの呼び口を複合セルタイプの呼び口としてエクスポートできます。 内部セル内に記述します。

エクスポートするものが、受け口配列の場合、配列全体をエクスポートする必要があります。 特定の添数のみエクスポートすることはできません。

受け口のエクスポート

内部セルの受け口を複合セルタイプの受け口としてエクスポートできます。 内部セルの外側に記述します。

エクスポートするものが、受け口配列の場合、配列全体をエクスポートする必要があります。 特定の添数のみエクスポートすることはできません。

属性のエクスポート

内部セルの属性を複合セルタイプの属性としてエクスポートできます。 内部セル内に記述します。

内部セルの指定子

アロケータ(allocator)指定子

内部セルのアロケータ(allocator)指定子は、セル記述のアロケータ指定子と同様です。 この場合のアロケータは、内部セルです。

使用しない指定子

以下の指定子は、複合セルタイプでは指定する必要がありません。

  • 省略(omit)指定子

  • インライン(inline)指定子

これらの指定子は、セルタイプの実装において必要になるもので、セルタイプの利用者にとって、必要な情報ではありません。

組上げ記述 (セル記述)

組上げ記述は、セル記述とも呼ばれ、セルを定義するものです。 セルとは、セルタイプ記述により定義されたコンポーネントの型に基づいて生成されるコンポーネントのインスタンスです。

【記述例】

cell tCelltype SimpleCell {       // cell キーワード, セルタイプ名、セル名
   cCall = SampleCell.eEntry;     // 呼び口を受け口に結合
   cCallArray[] = Sample0.eEntry; // 呼び口配列を受け口に結合
   attribute = 1;                 // 属性の初期値
};

ここで cell はキーワードであり、tCelltype はセルタイプ名です。'Cell' がセル名です。'{', '}' に囲まれた中に、呼び口の結合、または属性の初期化を記述します。

慣習としてセル名は、大文字で始めます。セル名の単語区切りも大文字とします。

組上げ記述の指定子

アロケータ(allocator)指定子

アロケータ(allocator)指定子は、セルの属するセルタイプの持つ受け口関数において、send, receive 指定子が指定されている場合に指定する必要があります。 ただし、セルの属するセルタイプ、または複合セルタイプにおいて、リレーアロケータ、または内部アロケータが指定されている場合には、指定しません。

【記述例】 T.B.W

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

ジェネレート(generate)指定子は、セルプラグインの適用を指示するものです。セルプラグインは、呼び口の結合、属性の初期化や、類似のセルの定義に用いられます。

ID(id) 指定子

ID (id) 指定子は、セルの ID 番号を指定するものです。 ID 指定子は、ID 番号を引数にとります 。 ID 番号は、正または負の整数です 。 TECS CDL においては、キーワードとして id を指定します。

ID 番号はセルタイプごとに 1 から(生成されるセルの個数)までの番号を指定できます。

指定できる ID 番号には、以下の制約があります。

  • iD 番号に範囲外となるものを指定できない

  • ID 番号が重複することはできない

セルに ID 指定子が指定されていない場合、出現順に 1 から順に ID 番号が与えられます ただし ID 指定子で指定されている ID 番号は避けられます。

TECS ジェネレータは ID 番号順に、コードを生成します。 セルの生成順序を TECS CDL の出現順序とは別に制御したい場合に用います。

【補足説明】tecsgen のオプション -u を指定すると、全体の通し番号となるが、セルタイプごとには連続した値が与えられる。 その場合でも ID = 1 のセルがセルタイプにおいて最初のセルとなる。 tecsgen のオプション -v を指定すると、最終的に与えられた ID 番号が表示される 。

【記述例】

[id(-1)]               // 一番後ろの ID となる (5)
cell tCelltype Cell5{
};

cell tCelltype Cell2{  // 未指定 id = 2 となる
};

cell tCelltype Cell3{  // 未指定 id = 3 となる(出現順)
};

[id(-2)]               // 後ろから2番目の ID となる(4)
cell tCelltype Cell4{
};

[id(1)]                // 一番先頭の ID となる (1)
cell tCelltype Cell1{
};
プロトタイプ(prototype)指定子

プロタイプ(prototype)指定子は、'{', '}' で囲まれた結合リストを伴うセル文が、プロトタイプ宣言であることを示します。

プロトタイプ指定子を伴わないセルの定義が CDL ファイル内で表れた時に、実際にセルが定義されます。

結合

結合とは、セル記述において、呼び口に受け口を割付けることです。 呼び口のシグニチャと、受け口のシグニチャは一致しなくてはなりません。

結合を記述しようとするセルの属するセルタイプに現れたすべての呼び口について、結合を記述します。 ただし、セルタイプの呼び口定義において otpional が指定されている場合には、未結合のままとすることができます。

呼び口配列

呼び口配列の場合には、結合の左辺において '[', ']' または '[', ']' で囲んで添数を指定します。

添数が指定される場合、添数は定数式で、評価の結果0から(配列サイズ−1)までの整数値になる必要があります。 セルタイプの呼び口の定義で配列サイズが指定されている場合、 0から(配列サイズ−1)までのすべての添数について、結合を記述します。 セルタイプの呼び口の定義で配列サイズが指定されていない場合、 0から指定された添数の最大値までのすべての配列要素が結合されなくてはなりません。

optional 指定されている呼び口の場合には、未結合の添数があってもよいです。 添数の出現順序は規定しないが、同じ添数が重複してはなりません。

添数が指定されない場合、出現順に0から(出現個数−1)までが添数として与えられます。 セルタイプの呼び口の定義で配列サイズが指定されている場合、 配列サイズ分の定義をしなくてはなりません。

以下の例のように、一つの呼び口配列について、添数を指定する場合と、指定しない場合を混在することはできません。

【不適切な記述例】:

cCall[0] = Cell.eEnt;
cCall[]  = Cell.eEnt;

【補足説明】配列の全体を結合するには、すべての添数について結合を記述する。添数なしの呼び口と受け口を指定して全体を結合する手段はない。

受け口配列

結合先の受け口が受け口配列の場合、'.' 演算子の右辺に現れる受け口名の後ろに '[', ']' で囲んだ添数を置きます。 添数は整数の定数式で、0から(受け口配列の大きさ−1)までの値です。 定数式には、定数定義文で定義された定数の識別子を含めることができます

添数を省略することができます。この場合、出現順に受け口配列の添数が与えられます。

逆結合

逆結合は、セルの受け口から、結合される呼び口を指定するものです。 以下の場合に限って用いることができます。

  • 指定プロトタイプ宣言の場合

  • コールバック指定されたシグニチャに対応づいた受け口の場合

指定プロトタイプ宣言の場合の例を示します。

【記述例】

[prototype]                // プロトタイプ指定子
cell tMain Main {
    eBody <= Task.cBody;     // 逆結合 (受け口に呼び口を結合させます)
};

コールバック指定されたシグニチャに対応づいた受け口においても、逆結合の書き方は同様です。

【補足説明】セルの実装では、呼び口において受け口へたどる情報を持つ(受け口から呼び口へたどるための情報は持っていない)ことから、呼び元のセルから結合先を指定するのを一般的な記述方法としている。従って、逆結合の使用は最小限にとどめるべきであることから、上記の制限が設けられている。

結合の指定子

スルー(through)指定子

スルー(through)指定子は、呼び口にスループラグインの適用を指示します プラグイン名で指定されたプラグインが ジェネレータにロードされ、ジェネレータがスルーセルを生成します。 スルーセルと呼ばれるセルが、呼び口と受け口の間に挿入されます。

属性の初期化

結合により、セルの属するセルタイプで定義されている属性について、初期値を与えることができます。 結合により属性の初期値が与えられない場合、セルタイプにおいて属性に与えられた初期値により初期化されます。 いずれにおいても属性の初期値が与えられない場合は、誤りです。

初期化子に現れる定数式には、定数定義文で定義された定数の識別子を含めることができます。

属性が整数型、浮動小数型、ブール型の場合、初期化子は定数式です。

属性がポインタ型で size_is 指定された配列の場合、初期化子は集成型初期化子とします。 非配列の場合、初期化子はポインタ型にキャストされた定数式です。

属性が構造体型の場合、初期化子は集成型初期化子です。

複合コンポーネントの内部セルの属性

結合が、複合セルタイプの内部セルの内側に現れた場合は、内部セルの属性を初期化するか、内部セルの属性を複合コンポーネントの属性に割付けるものになります。

内部セルの属性を初期化する場合は、前節の属性の初期化の場合と同じです。

内部セルの属性を複合コンポーネントの属性に割付ける場合、結合の割付記号 '=' の右辺の記号 '.' の左辺に 'composite' を置くことができます。 この場合、記号 '.' の右辺の識別子は、複合セルタイプ属性文で定義される複合セルタイプが外部に公開する属性の名前です。 複合セルタイプの属性名が、内部セルの持つ属性、変数、呼び口、受け口のいずれの名前とも重複しない場合には、'compsote' '.' を前置きすることなく、割付け記号 '=' の右辺に複合セルタイプの属性名のみを置くことができます。

【記述例】:

cell tCell2_active_single cell2 {
        a = composite.a;
        cCall = cell1.eEntry;
};

内部セルの属性を複合コンポーネントの属性に割付ける場合、両者の型が一致しなくてはならなりません。 また、内部セルの属するセルタイプにおいて属性の初期値が指定されていたとしても、この初期値は参照されません。 複合セルタイプの属性または、複合セルタイプから生成されるセル(複合セルタイプに属するセル)のいずれか、少なくとも一方において、初期値が指定されなくてはなりません。 両方で指定された場合、セルで指定された初期値が優先されます。

プロトタイプ宣言

セルのプロトタイプ宣言は、セルが定義される前に参照可能とするために、セルの名前と属するセルタイプまたは複合セルタイプを宣言するものです。 あるいは、セルを定義する前に、セルの一部または全部の属性、結合先、非結合先を指定する目的で用いることもできます。

プロトタイプ宣言には、純粋プロトタイプ宣言と指定プロトタイプ宣言の2通りがあります。

純粋プロトタイプ宣言

純粋プロトタイプ宣言は、セルを前方参照可能とする目的で用いられます。

TECS CDL ではセルの前方参照が可能であり、通常純粋プロトタイプ宣言を用いる必要はありませんが、意味解析後に生成され解釈されるポストコードで生成されるセルは、意味解析段階で参照できないため、プロトタイプ宣言が必要となります

【記述例】

cell tCelltype Cell;

'{', '}' で囲まれた結合リストを伴わない。

指定プロトタイプ宣言

指定プロトタイプ宣言は、プロトタイプ宣言で、呼び口や属性の一部または全部のを予め定義しておく目的で用いられます。 プロトタイプ宣言されたセルの定義が行われなければ、セルは生成されません 。

セルの定義では、プロトタイプ宣言された結合を変更することはできません(二重定義エラーとなる)。 プロトタイプ指定子とジェネレート指定子を同時に指定できません。 セルの定義が行われた後に、そのセルの指定プロトタイプ宣言を行うことはできません。

【補足説明】 ジェネレート指定子は構文解釈時にプラグインを呼び出す。意味定義段階でプラグインを呼び出すと、セル生成が不適切になる可能性がある。

プロトタイプ指定されたセルは、何度でも同名で宣言できます。

【記述例】

[prototype]      // プロトタイプ指定子 (一部の結合だけを指定する例)
cell tMotorA MotorA {
  eHandler <= GPIO_16bit_0.cIRQ[3];  // 逆結合
  cGPIO = GPIO_16bit_0.eGPIO[3];     // GPIO_16bit No.0 の bit 3 を要求
};

ネームスペース

ネームスペースは、一般名前有効範囲を区切り、セルタイプ、シグニチャの名前衝突を防ぐために用いられます。

【記述例】

namespace nNS {
    signature sSig {
       void func( void );
    };
    [active]
    celltype tCelltype {
       entry sSig  eEntry;
    };
};

cell nNS::tCelltype Cell {
};

ここで namespace はキーワードであり、nNS はネームスペース名です。'{', '}' に囲まれた中に、シグニチャ (signature)、セルタイプ (celltype) を記述します。

慣習として、ネームスペース名は 'n' で始めます。

同じネームスペース名を持つネームスペースを、繰り返し記述することができます。

ネームスペースは、再帰的に設けることができます。

【補足説明】ネームスペースは、セルタイプとシグニチャのみに用いる。セルは、リージョンの下に置く。名前衝突回避とともにセルのレイアウト制御を行う。

【補足説明】以下のものも、ネームスペース下に置くことができない。
  • 構造体 (struct) タグ

  • 型定義 (typedef) された型名

  • 定数 (const)

  • 列挙型 (enum)

これらを TECS CDL でネームスペース下に置くことに技術的困難はないが、C 言語の生成コードにおいて短縮して記述する方法がなく、グローバル名を使用することになり利便性がないため。

ネームスペース識別子

ネームスペース識別子は、ネームスペースに属するシグニチャやセルタイプを、異なるネームスペースから参照する際に用います。 シグニチャ名、セルタイプ名を指定する箇所で、ネームスペース識別子を用いることができます。

リージョンは、ネームスペースと同様に名前有効範囲を区切ります。 従ってセル名を指定する箇所でも、ネームスペース識別子を用いることができます。

【記述例】

nNS::sSig
nNS::tCelltype

ネームスペース識別子は、一般名前有効範囲に属する物を参照するときに使用します。 ネームスペース識別子には、以下の3種類があります。

種類

参照する対象

記述例

単一の識別子

同じネームスペース、または親ネームスペースに存在する物を参照。 同じネームスペースの物が優先されます。親ネームスペースにも存在しない場合、 更にその親ネームスペースを再帰的に探索していき、見つかった物を参照します。

tCelltype sSignature

絶対パス指定

ルートネームスペース (ルートリージョン) から指定して、物を参照。

::nNS::tCelltype ::rRegion::rSubRegion::Cell

相対パス指定

入れ子の内側のネームスペースに存在する物、または親ネームスペースに存在する物を参照。 '::' で区切られた最初の識別子を名前とするネームスペースが同一ネームスペースになければ、 親ネームペースを再帰的に探索します。 入れ子の内側へ向かって再帰的な探索は行われません。

nNS::sSignature nNS::nSubNS::tCelltype

単一の識別子、および相対パス指定の先頭の識別子と一致するものがネームスペース内にないとき、上位のネームスペースから探索します。

リージョン

リージョンは、セルのレイアウトを制御するものです。 ネームスペースの役割、すなわち一般名前有効範囲に境界を設ける役割も併せ持ちます。 さらにリージョン間のアクセス制御も行います。

【記述例】

[linkunit]                                            // リンク単位属性の指定
region rServer {                                      // リージョン
    cell      tSysLog ServerSysLog {
    };
    cell tCheckCode CheckCode {
        cCheckCode
           = rGuardedRegion::GuardedCell.eCheckCode;    // ネームスペース識別子によるセル指定
    };
    [in_through(GuardCheckPlugin,""), out_through()]  // スループラグインの指定
    region rGuardedRegion {                           // 子リージョン
        cell tGuardedCodeHolder GuardedCell {
           cSysLog = ServerSysLog.eSysLog;            // 外側のリージョンのセルの参照
        };
    };
};

ここで region はキーワードであり、rServer はリージョン名です。'{', '}' で囲まれたセルを持ちます。

慣習としてリージョン名は 'r' で始めます。

同じリージョン名を持つリージョンを、繰り返し記述することができます。 ただし、リージョン指定子は、最初に現れたときに指定する必要があります。 リージョン名が同じリージョンが再び現れた場合、指定子を指定することはできません。

リージョンは再帰的に設けることができます。

異なるリージョンに存在するセルを参照する場合、ネームスペース識別子を用います。

【補足説明】リージョンはセルのレイアウトだけでなく、セルタイプコードのレイアウトも制御します。 セルの所在するところに、セルを操作するコード、すなわちセルタイプコードが必要となるためです。 これが、セルはリージョンに置き、セルタイプはネームスペースに置く理由です。 ネームスペースには、セルタイプコードの所在を制御する機能はなく、もっぱら名前衝突の回避に用いられます。

【補足説明】最初に指定する必要があるのは、他のリージョンのセルからリージョン内のセルが参照される前に、参照可能かどうか決定できる必要があるためです。

【補足説明】前方参照ができないため最初にリージョン指定子リストを指定する必要がある。現在の仕様では2回目に現れたときには、リージョン指定子を指定できない。

【補足説明】この文法のリージョンは、TECS CDL 記述では直観的にわかりやすくない。ただし、リージョンはむやみやたらに使えばよいものではなく、またリージョン境界を設けるところは何らかの理由により独立性を高くしたい箇所であり、リージョン間の結合はそれほど多くならないはずである。

【補足説明】記述例で用いた GuardCheckPlugin の実装例はありません。

リージョン指定子

リージョン指定子の凡例と指定内容を以下に示します。

リージョン指定子の凡例

指定内容

in_through( プラグイン名, プラグイン引数 )

リージョン内への結合の許可とプラグイン適用

in_through()

リージョン内への結合の許可

out_through( プラグイン名 , プラグイン引数 )

リージョン外への結合の許可とプラグイン適用

out_through()

リージョン外への結合の許可

to_through( リージョン名, プラグイン名, プラグイン引数 )

リージョン間の結合の許可とプラグイン適用

to_through()

リージョン間の結合の許可

node

ノード属性の指定

linkunit

リンク単位属性の指定

domain( ドメインタイプ名, オプション文字列 )

ドメイン単位属性の指定

class( IDENTIFIER )

クラス単位属性の指定

以上のうち in_through, out_through, to_through をまとめて、リージョンスルー指定子と呼びます。 node, linkunit, domain, class をリージョン属性と呼びます。

リージョンスルー指定子

リージョンスルー指定子は、リージョン外部のセルの呼び口からリージョン内部のセルの受け口へ、同様に内部から外部へ、リージョン から他のリージョンへの結合を許可します。 デフォルトでは、リージョンから他のリージョン(内側、外側を含む)への結合は、禁止されます。

in_through は、リージョンの外部からリージョンの内部への結合を許可し、プラグイン(plugin)により挿入すべきスルーセルを生成させます。 in_through は第一引数としてプラグイン名、第二引数としてプラグイン引数を取ります。 これらの引数が省略された場合には、リージョン外部から内部への結合を(スルーセルを生成させることなく)許可するものです。 in_through は1つのリージョンに複数指定できます。 複数指定された場合、順にプラグインが(指定されていれば)呼び出され、スルーセルが(プラグインにより生成されれば)挿入されます。

out_through は、リージョンの内部からリージョンの外部への結合を許可します。その他 in_through と同様です。

to_through は、兄弟リージョン間での結合を許可します。 to_through は、第一引数に結合可能なリージョン名、第二引数にプラグイン名、第三引数にプラグイン引数を指定します。 第一引数のリージョン名は、前方参照が可能です。 親リージョン、子リージョン、甥リージョン、叔父リージョン、いとこリージョンなど兄弟関係にはないリージョンは指定できません。 このため第一引数は単一の識別子となります。

in_through, out_through, to_through で生成されるスルーセルは、受け口側のセルおよびセルの受け口が同じである場合、共有されます。

【補足説明】ジェネレータの実装として、共有可能なスルーセルを共有しないオプションを設けてもよい。

スルー指定子オプションの文字列置換

スルー指定子のオプションは、以下の文字列置換が行われます。

置換文字列

置換後文字列

$source$

呼び元のセル名

$destination$

呼び先のセル名

$SOURCE$

呼び元のセル名 (リージョン名を '_' で連結したグローバル名)

$DESTINATION$

呼び先のセル名 (リージョン名を '_' で連結したグローバル名)

$next$

次のセル名[[BR]] 複数の through がつながっている場合、すぐ後ろに来るもの

$NEXT$

次のセル名 (リージョン名を '_' で連結したグローバル名)

複数の through がつながっている場合、すぐ後ろに来るもの

$start_region$

$source$ のセルの存在するリージョン (グローバル名)

$end_region$

$destination$ のセルの存在するリージョン (グローバル名)

$preferred_region$

適切なリージョン (グローバル名), start_region または end_region

$count$

リージョン間の through 指定子の適用数

$$

$ に置換

リージョン属性

リージョン属性は、リージョンの特性を示すもので、ノード、リンク単位、ドメイン、クラスの 4 種類があります。 リージョン属性は、必ずしも指定する必要がない、一方、一つのリージョンには、いずれか一つのリージョン属性を指定できます。

ノード(node)

ノードは、通常一つのプロセッサとメモリから構成され、1つ以上のリンク単位を持ちます。 ノードを超えて直接結合することはできません。

ノードを超えて、呼び口と受け口を直接結合することはできないが、コンポーネント図上、またコンポーネント記述言語においては、接続 (connect) することができます。 この場合リージョン間のスループラグインにより、呼び口側、受け口側、それぞれに直接結合することなく接続させるためのコンポーネントを挿入することで実現されます。 実際に接続がどのように行われるかは、プラグインの仕様に依存します。

ノードが異なる場合、メモリ透過性がありません。 つまり、ポインタ値を渡したとしても、受け取った側では、ポインタ参照することができません。 このため引数がポインタ型である場合、ポインタの指すメモリ領域を渡す必要があります。

例えばオペイク RPC プラグインでは、通信チャンネルを使用することで、接続することができます。 オーバーヘッドが、通常の呼び出しに比べ非常に大きいため、頻繁な呼出しは適さないこと、上述のようにポインタ値を渡す場合、直接結合とは異なる振る舞いになる可能性があることに注意します。

TECS CDL においては、リージョンに node 指定子を指定することで、そのリージョンが一つのノードを構成することを示します。 node 指定されていないリージョンは、親リージョンのノードに属する。 ルートリージョンは、暗黙的に node が指定されます。

リンク単位(linkUnit)

リンク単位は、リンカーにより一つのモジュールとして生成される単位です。 リンク単位を超えて直接結合することはできません。

ノードの場合と同様にリージョン間のスループラグインにより異なるリンク単位のセルに接続することができます。

リージョンに linkUnit 指定子を指定することで、そのリージョンが一つのリンク単位を構成することを示します。 linkUnit 指定されていないリージョンは、親リージョンのリンクユニットに属します。

ノードは、暗黙的にリンク単位と見なされます。

ドメイン(domain)

ドメインは、TOPPERS/HRP2 カーネルの保護ドメインに対応させて、 リージョンを保護ドメインとして扱うことを念頭に置いたものです。 保護がどのように行われるかは、TECS 仕様としては規定しません。 ドメインタイプごとに定義される、ドメインプラグインの仕様により規定します。 また、ドメインプラグインの実装により、TOPPERS/HRP2 の保護ドメイン以外の保護機能にも対応できます。

TECS CDL においては、リージョンにドメイン指定子を指定することで、そのリージョンは、ドメインに属します。 リージョン名がドメイン名となる。 ドメイン指定されていないリージョンは、親リージョンのドメインに属します。

ドメイン指定子の第一引数は、ドメインタイプ名 (文字列ではなく、識別子) です。 ドメインタイプ名により識別されるドメインタイプは、親リージョンに波及します。 ただし、子リージョンから親リージョンへのドメインタイプの伝播は、ノードを超えません。 一つのノードにおいては、一つのドメインタイプに制限されます。 ルートリージョンは、いずれのドメインにも属さない、ドメイン外 (OutOfDomain) として扱われます。 従って、ドメインタイプの親リージョンへの波及は、ルートリージョンの直下のリージョンまでです。

ドメインタイプ名は、以下のようにドメインプラグイン名に変換されます。

(ドメインプラグイン名) = (ドメインタイプ名) + 'Plugin'

TOPPERS/HRP2 カーネルの保護ドメインに対応させる場合、ドメインタイプを HRP2 とします。プラグイン名は HRP2Plugin となります。

ドメイン指定子の第二引数は、オプション文字列です。 ドメインタイプ HRP2 では "trusted", "nontrusted" を指定します。

【補足説明】HRP2 ドメインの扱いについては、本書では詳細を説明しません。

クラス(class)

仕様未定である。TOPPERS/FMP カーネルのクラスに相当するものとして、予約されている。

T.B.W.

リージョン内セル

【補足説明】リージョン内部文リストとリージョン内部文に分離されていない。

セル記述は、プロトタイプ宣言と定義のいずれも可能です。 ただし、セルのプロトタイプ宣言と定義の両方において、同じリージョンに属するように記述する必要があります。

ビルド単位

ノード、または、リンク単位 属性を持つリージョンごとに、ビルドを行います。 これは、例えば分散システムで、ある部分システムのをビルドすることを想定したものです。

  • ビルド単位をまたいでリージョンの境界をまたぐ結合がないこと

ただし、以下のリージョン間をまたぐスルーセルを使用した接続を持つことは可能です。

  • スルーセルの内部のセルが、呼び側、受け側のいずれかのリージョンに属していること

  • スルーセルの内部のセルが、リージョンをまたぐ結合を持たないこと

複数のシングルトンセルタイプのセル

シングルトンセルタイプのセルは、リンク単位ごとに、最大1つ置くことができます。

ルートネームスペースとルートリージョン

ルートネームスペースは、いずれのネームスペース文の内側ではないところです。 ルートネームにのみ構造体 struct, 型定義 typedef, 定数変数 const の定義を置くことができます。

ルートリージョンは、いずれのリージョン文の内側ではないところです。 ルートネームスペースとルートリージョンは、共通した名前の空間を持ちます。

TECS コンポーネント実装モデル

TECS ジェネレータ V1.3.1.0 の実装に対応します。

ユーザー実装モデルとシステム実装モデル

TECS コンポーネント実装モデルには、TECS コンポーネントの振る舞いのコードの実装方法を規定するユーザー実装モデルと、TECS ジェネレータが生成するコードを規定するシステム実装モデルとがあります。

システム実装モデル

To be written

セルタイプコード

セルタイプコードは、コンポーネントの振る舞いを記述するもので、受け口関数の実装です。

使用言語

セルタイプコードは C 言語で記述します。

【補足説明】C++ として記述することもできる。ただし、外部名を C 言語に合わせる。

記述単位

セルタイプコードは、セルタイプごとにファイルを分けて記述します。 一つのセルタイプのセルタイプコードを、複数のファイルに分けて記述することはできます。

インラインの受け口関数と非インラインの受け口関数とでは、ファイルを分けて記述します。

【補足説明】複数のセルタイプのセルタイプコードを一つにまとめることはできない。

ファイル名

非インライン受け口関数を格納するファイルの名前は、セルタイプのグローバル名に C 言語の拡張子 .c を付加したものです。C++ で記述する場合には、適切な拡張子を付加します。

セルタイプコードを複数のファイルに分けて記述する場合、他のファイル名を付与します(名前付け規則は定めない)。

【ファイル名の例】

tCelltype.c

インラインのセルタイプコードのファイル名

インラインの受け口関数を格納するファイルのファイル名は、セルタイプのグローバル名に ’_inline.h' を付加したヘッダファイルとします。 インラインの受け口関数を実装するセルタイプコードを複数のファイルに分けて記述する場合、セルタイプのグローバル名に ’_inline.h' を付加した名前のヘッダファイルからインクルードします。

以下に、セルタイプのネームスペース識別子が nNS::tCelltype である場合のファイル名の例を示します。

【ファイル名の例】

nNS_tCelltype_inline.h

ファイルの記述内容

セルタイプコードを格納するファイルには、以下を記述します。

  • セルタイプヘッダファイルのインクルード

  • 受け口関数

  • 受け口関数から呼び出される関数

セルタイプヘッダのインクルード

セルタイプヘッダは、セルタイプコードからインクルードすべき、TECS ジェネレータの生成したヘッダファイルです。

非インライン受け口関数を実装するセルタイプコードを記述するファイルでは、セルタイプヘッダをインクルードします。 以下にセルタイプ tCelltype の場合の例を示します。

【セルタイプコード記述例】

#include "tCelltype_tecsgen.h"

セルタイプコードを記述しようとするセルタイプ以外のセルタイプヘッダをインクルードすることはできません。

【補足説明】複数のセルタイプのセルタイプコードを一つのファイルに含めることは想定されていない。C 言語のマクロを駆使して関数の結合先をコンパイル時に決定する TECS の実装では、やむを得ない制限である。

参照できるもの

セルタイプコードの中では、以下のものを参照できます。

これらは、いずれもセルタイプコードを記述しようとするセルタイプの持つものに限られます。

  • 呼び口関数

  • 属性

  • 内部変数

この他に、ライブラリとして提供されるものを参照することができますが、コンポーネントとして提供されるものの代わりにライブラリ参照するのは、望ましくない実装となります。

これ以外のものを参照する場合、逸脱になります。

受け口関数の実装

受け口に対応付けられたシグニチャで定義されたすべての関数を受け口関数として実装します。

受け口関数の名前は、以下のように受け口名と関数名を連結したものとなります。

(受け口関数名) = (受け口名) + '_' + (シグニチャで定義された関数名)

【補足説明】受け口関数名は、マクロにより、受け口関数のグローバル名に置換される。

セルタイプが非シングルトンの場合、シグニチャで定義された関数ヘッダに比べ、第一引数が挿入されます。 挿入される第一引数の型は、CELLIDX 型です。

以下に受け口関数の形式(関数ヘッダ)の例を示します。

受け口関数 (非シングルトンの場合)

【TECS CDL 記述例】

signature sSignature{
  ER func1( [in]int32_t inval, [out]int32_t *outval );
  ER func2( [in,size_is(size)]const int8_t *buf, [in]int32_t size );
};
celltype tCelltype {
  entry sSignature eEntry;
};

tCelltype のセルタイプコードに記述する必要のある受け口関数

【セルタイプコード記述例】

ER eEntry_func1( CELLIDX idx, int32_t inval, int32_t *outval )
ER eEntry_func2( CELLIDX idx, const int8_t *buf, int32_t size )

なお CELLIDX 型が何であるかは、ここでは規定しません。 ポインタ値であったり整数値であったりします。

受け口関数 (シングルトンの場合)

【TECS CDL 記述例】

[singleton]
celltype tCelltype {
  entry sSignature eEntry;
};

【セルタイプコード記述例】

ER eEntry_func1( int32_t inval, int32_t *outval )
ER eEntry_func2( const int8_t *buf, int32_t size )

シングルトンの場合、セルを識別するための引数 idx が挿入されません。

受け口関数の形式(受け口配列の場合)

受け口配列の場合、第二引数に配列添数を挿入します。

次に受け口配列の例を示す。以下のような TECS CDL の記述があったとします。

【TECS CDL 記述例】

signature sSignature{
  ER func1( [in]int32_t inval, [out]int32_t *outval );
  ER func2( [in,size_is(size)]const int8_t *buf, [in]int32_t size );
};
celltype tCelltype {
  entry sSignature eEntry[2];
};

tCelltype のセルタイプコードに記述する必要のある受け口関数の関数ヘッダは、以下のようになります。

【セルタイプコード記述例】

ER eEntry_func1( CELLIDX idx, int_t subscript, int32_t inval, int32_t *outval )
ER eEntry_func2( CELLIDX idx, int_t subscript, const int8_t *buf, int32_t size )

CB ポインタ

CB ポインタは、非シングルトンのセルタイプの場合に、セルを選択するために必要となります。 シングルトンのセルタイプでは、CB ポインタを得ることはできません。

以下に、セルタイプが非シングルトンの場合の、受け口関数の中で CB ポインタを得る方法を説明します。 CB ポインタが何物であるかは、ここでは規定しません。

CB ポインタを得るコードの例を以下に示します。

【セルタイプコード記述例】

CELLCB   *p_cellcb;    /* p_cellcb の名前を変えてはならない */
if (VALID_IDX(idx)) {
  p_cellcb = GET_CELLCB(idx);
}
else {
  return(E_ID);
}

以下に必須の要件を記します。

  • 非シングルトンセルタイプの場合、CB ポインタを得る

  • CB ポインタの変数名は p_cellcb とする

  • CB ポインタの型は CELLCB 型とする

  • 第一引き数 CELLIDX idx を検査する関数(マクロ)として VALID_IDX を使用する

  • 第一引き数 CELLIDX idx を CB ポインタに変換する関数(マクロ)として GET_CELLCB を使用する

先ほどの CB ポインタを得るコードの例にあって、この要件にないのは、VALID_IDX で idx が不正と判断された場合に E_ID を返すことです。 TOPPERS/ASP 系の OS では E_ID を返すのが妥当ですが、戻り値の型が ER や ER_INT でない場合、あるいは TOPPERS/ASP 系以外の OS で動作させることを目的に記述している場合には、E_ID を返す必要はありません。

【補足説明】実際の実装において idx_is_id が指定されいてない場合、 VALID_IDX が false を返すことはない。

【補足説明】呼び口関数、属性、内部変数のいずれも参照しない場合、p_cellcb は非参照となる。

呼び口関数

セルタイプコードにおいて、呼び口のシグニチャで定義された関数を呼び出し可能です。 呼び口関数は、シグニチャで定義された関数と以下の点で異なります。

(呼び口関数名) = (呼びけ口名) + '_' + (シグニチャで定義された関数名)

以下に例を示す。以下のような TECS CDL の記述があったとします。

【TECS CDL 記述例】

signature sSignature{
  ER func1( [in]int32_t inval, [out]int32_t *outval );
  ER func2( [in,size_is(size)]const int8_t *buf, [in]int32_t size );
};
celltype tCelltype {
  call sSignature cCall;
};

tCelltype のセルタイプコードでの呼び口関数の形式は以下のようになります。

【セルタイプコードでの形式の例】

ER cCall_func1( int32_t inval, int32_t *outval )
ER cCall_func2( const int8_t *buf, int32_t size )

【補足説明】受け口関数の場合は、第一引き数 idx が挿入されたが、呼び口関数では挿入されない。

呼び口関数(呼び口配列の場合)

次に呼び口配列の例を示します。以下のような TECS CDL の記述があるとします。

【TECS CDL 記述例】

signature sSignature{
  ER func1( [in]int32_t inval, [out]int32_t *outval );
  ER func2( [in,size_is(size)]const int8_t *buf, [in]int32_t size );
};
celltype tCelltype {
  call sSignature cCall[];
};

tCelltype のセルタイプコードでの呼び口関数は以下のようになります。

【セルタイプコード記述例】

ER cCall_func1( int_t subscript, int32_t inval, int32_t *outval )
ER cCall_func2( int_t subscript, const int8_t *buf, int32_t size )

非配列の場合に比べ、第一引き数に配列添数が加えられます。 配列添数の最小値は 0 です。 配列サイズは、マクロ NCP_cCall (cCall は呼び口名に置き換える) により知ることができます。

【訂正】(2016/11/12) N_CP_cCall は、通常形ですが、引数に p_that を取る場合と、取らない場合がありました。NCP_cCall (短縮形) は、常に引数 p_that を取りません。

属性

セルタイプコードにおいて、属性を参照可能です。 属性参照名は、以下のように属性名に 'ATTR_' を前置きしたものです。

(属性参照名) = 'ATTR_' + (属性名)

以下に例を示します。以下のような TECS CDL の記述があったとします。

【TECS CDL 記述例】

celltype tCelltype {
  attr {
    int32_t  attribute;
  }
};

tCelltype のセルタイプコードでの属性参照は以下のようになります。

【セルタイプコード記述例】

ATTR_attribute

ATTR_attribute は左辺値として扱うことができます。

内部変数

セルタイプコードにおいて、内部変数を参照可能です。

内部変数参照名は、以下のように内部変数名に 'VAR_' を前置きしたものです。

(内部変数参照名) = 'VAR_' + (内部変数名)

以下に例を示します。以下のような TECS CDL の記述があったとします。

【TECS CDL 記述例】

celltype tCelltype {
  var {
    int32_t  variable;
  }
};

tCelltype のセルタイプコードでの内部変数参照は以下のようになります。

【セルタイプコード記述例】

VAR_variable

VAR_variable は左辺値として扱うことができます。

非シングルトンセルタイプの場合のセルタイプコードの例

これまでの、セルタイプコードの規則に従ったコードの例を示します。 ここでは、非シングルトンセルタイプの場合を示します。

【TECS CDL 記述例】

signature sSignature{
  ER func1( [in]int32_t inval, [out]int32_t *outval );
  ER_INT func2( [in,size_is(size)]const uint8_t *buf, [in]int32_t size );
};
celltype tCelltype {
  entry sSignature eEntry;
  attr {
    int32_t  attribute;
  };
  var {
    int32_t  variable;
  };
};

tCelltype のセルタイプコードは以下のようになります。

【セルタイプコード記述例】

ER eEntry_func1( CELLIDX idx, int32_t inval, int32_t *outval )
{
  /* CB ポインタを得るコード */
  CELLCB   *p_cellcb;          /* p_cellcb の名前を変えてはならない */
  if (VALID_IDX(idx)) {
    p_cellcb = GET_CELLCB(idx);
  }
  else {
    return(E_ID);
  }

  *out_val = inval - ATTR_attribute;  /* 属性 attribute を参照

  return E_OK;
};
ER_INT eEntry_func2( CELLIDX idx, const uint8_t *buf, int32_t size )
{
  /* CB ポインタを得るコード */
  CELLCB   *p_cellcb;          /* p_cellcb の名前を変えてはならない */
  int32_t  i, sum = 0;
  if (VALID_IDX(idx)) {
    p_cellcb = GET_CELLCB(idx);
  }
  else {
    return(E_ID);
  }

  for( i = 0; i < size; i++ )
       sum += buf[i];

  return sum;
};

【補足説明】ATTR_attribute は CB ポインタ p_cellcb を含むマクロであることを想定するが、限定するものではない。実例として、ATTR_attribute ではさらに以下のものを含む。属性は ROM に置かれるが、これを INIB と呼ぶ。CB から INIB へのポインタ参照も ATTR_attribute マクロに含まれる。これは、最適化状態において変わりうる。

【補足説明】VAR_variable は CB ポインタ p_cellcb を含むマクロであることを想定するが、規定するものではない。

シングルトンセルタイプの場合のセルタイプコード

これまでの、セルタイプコードの規定に従ったコードの実例を示します。 ここでは、シングルトンセルタイプの場合を示します。

【TECS CDL 記述例】

signature sSignature{
  ER func1( [in]int32_t inval, [out]int32_t *outval );
  ER_INT func2( [in,size_is(size)]const uint8_t *buf, [in]int32_t size );
};
[singleton]
celltype tCelltype {
  entry sSignature eEntry;
  attr {
    int32_t  attribute;
  };
  var {
    int32_t  variable;
  };
};

tCelltype のセルタイプコードは以下のようになります。

【セルタイプコード記述例】

ER eEntry_func1( int32_t inval, int32_t *outval )
{
  *out_val = inval - ATTR_attribute;  /* 属性 attribute を参照 */

  return E_OK;
};
ER_INT eEntry_func2( const uint8_t *buf, int32_t size )
{
  int32_t i, sum = 0;

  for( i = 0; i < size; i++ )
       sum += buf[i];

  return sum;
};

【補足説明】シングルトンセルタイプのコードでは、idx 引き数がない、CB ポインタを得るコードがない点で、非シングルトンセルタイプのコードと異なる。

【補足説明】ATTR_attribute は INIB 構造体名を含むマクロであることを想定するが、規定するものではない。

【補足説明】VAR_variable は CB 構造体名を含むマクロであることを想定するが、規定するものではない。

初期化コード

TECS のコードが実行される前に、以下のマクロを呼び出して初期化を行います。

INITILIZE_TECS()

INITILIZE_TECS は、必要に応じて以下を行います。

  • 内部変数の初期化

  • CB から INIB へのポインタ設定

初期化を行う前に TECS のコードが実行された場合の振る舞いは、未定義です。

【補足説明】TECS ジェネレータ V1.2.* まで INITIALZE_TECSGEN であったが、V1.3.0.0 以降、INITIALIZE_TECS に変更となった。ただし INITIALIZE_TECSGEN を INITIALIZE_TECS に置換するマクロが定義されるため、従来のコードも期待した通りにコンパイル、リンクスうることができる。

【補足説明】TECS ジェネレータ V1.2.* まで、INITIALIZE_TECS() は TECS ジェネレータにオプション -R が指定された時だけ生成されていたが、V1.3.0.1 以降、常に生成される。ただし -R が指定されていない場合、INITIALIZE_TECS()の内容は空であり INITIALIZE_TECS() が呼び出されない従来のコードも動作する。ただし、将来においても成り立つとは限らない。

ファクトリ

ファクトリでは、任意のファイルに出力できますが、以下の2つのファイルは、予め想定するファイルです。

コンフィギュレーションファイル

ファクトリの第一の使用目的は、コンフィギュレーションファイルに TOPPERS/ASP 系カーネルの静的 API を生成することです。 TECS ジェネレータにより生成されるコンフィギュレーションファイルの名前は、以下を推奨します。

tecsgen.cfg

以下は、コンフィギュレーションファイルに静的 API を生成する TECS CDL の記述例です。 セルが生成されるごとに、コンフィギュレーションファイルに静的 API が出力されます。

celltype tTask {
  attr {
          ID                   id = C_EXP( "TASKID_$id$" );
          VP_INT               exinf;
    [omit]ATR                  tskatr;
    [omit]PRI                  itskpri;
    [omit]SIZE                 stksize = 4096;
  };

  factory {
    write( "tecsgen.cfg",
           "CRE_TSK(%s,{%s,&$id$_CB,tTask_start_task,%s,%s,NULL});",
           id, tskatr, itskpri, stksize );
  };
};

【補足説明】ファクトリで記述できることは限られている。判断や繰り返しが必要な場合、セルタイププラグインにより実現する。

ファクトリヘッダ

ファクトリヘッダは、セルタイプコードに取込むためのヘッダファイルであり、セルタイプヘッダにおいてインクルードされます。 ファクトリヘッダには、セルの属性、変数において C_EXP で与えられた初期値に含まれるマクロの定義を記述することができます。 ファクトリヘッダの名前は、以下のとおりです。 CELLTYPENAME の部分は、セルタイプ名に置き換えます。

CELLTYPENAME_factory.h

以下の例は、セルタイプファクトリで TOPPERS/ASP のコンフィグレータの生成する kernel_cfg.h をインクルードするものです。 これによりコンフィグレータの出力するマクロを、セルの属性、変数の C_EXP 初期化子の中で参照することができます。

celltype tCelltype {
  FACTORY {
    write( "$ct$_factory.h", "#include \"kernel_cfg.h\"" );
  };
};

FOREACH_CELL マクロ

セルタイプコードにおいて、そのセルタイプに属するすべてのセルの変数を操作を行うために FOREACH_CELL マクロを使用できます。 主として、初期化の際に用います。

FOREACH_CELL マクロの使用

すべてのセルに対する操作を行うには、FOREACH_CELL マクロで始め END_FOR_EACHCELL で終わるループにより実現できます。 以下にコードの例を示します。

#include "tCelltype_tecsgen.h"

...

func()
{
  /* tCelltype のすべてのセルについて初期値を作業変数に移す */

  CELLCB  *p_cellcb;          /* 短縮形で属性、内部変数を参照するために p_cellcb とします */
  int      i;                 /* ループ変数を用意する必要があります.名前は適当で構いません */

  FOREACH_CELL(i,p_cellcb)    /* FOREACH_CELL でループの開始を宣言します */
    VAR_a0 = ATTR_a;              /* 短縮形 VAR_a0, ATTR_a で変数、属性参照できます */
    VAR_b0 = ATTR_b;
  END_FOREACH_CELL
}

FOREACH_CELL マクロの多重使用

FOREACH_CELL マクロを多重ループで用いることができます。 この場合、内側のループ内では外側のループのセルの属性、変数には直接アクセスすることはできません。 外側のループの属性、変数は別の自動変数に写し取ることで、内側のループで参照できます。

#include "tCelltype_tecsgen.h"

...

func()
{
  CELLCB  *p_cellcb;          /* 短縮形で属性参照するために p_cellcb としました */
  int      i;

  FOREACH_CELL(i,p_cellcb)
    CELLCB   *p;              /* p としたので短縮形で属性参照できません */
    int      j;               /* 内側のループ変数を j とします */
    FOREACH_CELL(j,p)
      /* 外側のループには短縮形が使えるが、内側のループはセルタイプのグローバル名を伴うマクロを使用 */
      if ( ATTR_a == tCelltype_ATTR_a( p ) ) {
         ...
      }
    END_FOREACH_CELL
  END_FOREACH_CELL
}

セルタイプコードでのアロケータ

シグニチャの関数の引数の基本指定子として send または receive を指定すると、引数としてアロケータによりアロケートされたメモリ領域のアドレスが渡されます。 渡されたメモリ領域は、受け取った側で解放します。

send 指定された引数の場合、呼び元でアロケートし、呼び先でデアロケートします。 receive 指定された引数の場合、呼び先でアロケートし、呼び元でデアロケートします。 アロケート、デアロケート操作は、アロケータ呼び口を通して行います。

アロケータ呼び口

TECS では、メモリアロケータをセルとして実装しますが、アロケータセルの受け口に結合する呼び口が必要となります。 この呼び口のことをアロケータ呼び口と呼びます。 アロケータ呼び口は TECS CDL に明示的に記述しません。TECS ジェネレータにより生成されます。

アロケータ呼び口には、以下の名前が与えられます。

(アロケータ呼び口名) = (呼び口名または受け口名) + '_' + (関数名) + '_' + (引数名)

アロケータ使用の具体例

以下に、アロケータを使用する例を示します。

TECS CDL のコード例には、呼び先のセルタイプおよびセル、呼び元のセルタイプおよびセルが実装されているとします。 ジェネレータによって呼び先および呼び元の双方に、アロケータ呼び口およびその結合が自動的に挿入されます。

【TECS CDL 記述例】

signature sSendRecv {
  /* この関数名に send, receive を使ってしまうとアロケータ指定できない */
  ER snd( [send(sAlloc),size_is(sz)]int8 *buf, [in]int32  sz );
  ER rcv( [receive(sAllocTMO),size_is(*sz)]int8 **buf, [out]int32  *sz );
};

celltype tTestComponent {
  entry  sSendRecv eS;
};

// 受け口側で、send/receive 指定された引数ごとにアロケータを指定
[allocator(eS.snd.buf=alloc.eA,eS.rcv.buf=alloc.eA)]
cell tTestComponent comp{
};

celltype tTestClient {
call   sSendRecv cS;
};

// 呼び口側では、アロケータを指定しない
cell tTestClient cl {
  cS = comp.eS;
};

【アロケータ呼び口が挿入されたコード(TECS ジェネレータにより内部生成された状態)】

以下のコードは、内部状態を説明するためのものであって、以下のような TECS CDL コードを記述するものではありません。

celltype tTestComponent {
  entry  sSendRecv eS;

  /* 自動生成されたアロケータ呼び口 */
  call   sAlloc    cS_snd_buf;    <<< 自動生成された呼び口
  call   sAlloc    cS_rcv_buf;    <<< 自動生成された呼び口
};

[allocator(eS.snd.buf=alloc.eA,eS.rcv.buf=alloc.eA)]
cell tTestComponent comp{

  /* 自動生成されたアロケータ呼び口の結合 */
  eS_snd_buf = alloc.eA;          <<< 自動生成された結合
  eS_rcv_buf = alloc.eA;          <<< 自動生成された結合
};

celltype tTestClient {
  call   sSendRecv cS;

  /* 自動生成されたアロケータ呼び口 */
  call   sAlloc    cS_snd_buf;    <<< 自動生成された呼び口
  call   sAlloc    cS_rcv_buf;    <<< 自動生成された呼び口
};

cell tTestClient cl {
  cS = comp.eS;

  /* 自動生成されたアロケータ呼び口の結合 */
  cS_snd_buf = alloc.eA;          <<< 自動生成された結合
  cS_rcv_buf = alloc.eA;          <<< 自動生成された結合
};

セルタイプ tTestClient の呼び口 cS の関数の send, receive 指定された引数に対して、以下のようなアロケータ呼び口関数が、生成されます。 アロケート関数、デアロケート関数の両方が使用できますが、send 指定された引数の場合、通常、呼び元で使用する必要があるのは、アロケート関数です。 rceive 指定された引数の場合は、デアロケート関数です。

// allocator port for call port: cS func: send param: buf
  ER             cS_snd_buf_alloc( int32_t size, void** p );
  ER             cS_snd_buf_dealloc( const void* p );
// allocator port for call port: cS func: receive param: buf
  ER             cS_rcv_buf_alloc( int32_t size, void** p );
  ER             cS_rcv_buf_dealloc( const void* p );
// allocator port for call port: cA func: send param: buf
  ER             cA_snd_buf_alloc( subscript, int32_t size, void** p );
  ER             cA_snd_buf_dealloc( subscript, const void* p );
// allocator port for call port: cA func: receive param: buf
  ER             cA_rcv_buf_alloc( subscript, int32_t size, void** p );
  ER             cA_rcv_buf_dealloc( subscript, const void* p );

セルタイプ tTestComponent の受け口 eS の関数の send, receive 指定された引数に対しても、同様なアロケータ呼び口関数が、生成されます。

【未決定事項】アロケータを一々使い分けるのは、誤りのもとである。まとめる手段が必要。

アロケータの例

アロケータセルの例を以下に示します。

【TECS CDL 記述例】

signature sAlloc {
   ER alloc( [in]size_t len, [out]void *p );
   ER dealloc( [in]void *p );
};

celltype tAlloc {
  entry sAlloc eA;
};

cell alloc {
};

リレーアロケータ

リレーアロケータの TECS CDL 記述例を示します。

【TECS CDL 記述例】

signature sSendRecv {
  /* この関数名に send, receive を使ってしまうとアロケータ指定できない */
  ER snd( [send(sAlloc),size_is(sz)]int8_t *buf, [in]int32_t  sz );
  ER rcv( [receive(sAlloc),size_is(*sz)]int8_t **buf, [out]int32_t  *sz );
};

celltype tThroughComponent {
  [allocator(                  /* 受け口から呼び口へリレー */
      snd.buf <= cSR.snd.buf,  /* cSR:前方参照可能 */
      rcv.buf <= cSR.rcv.buf
  )]
  entry  sSendRecv eS;
  call   sSendRecv cSR;
};

 /* セルの定義で、受け口の send/receive 指定された引数のアロケータ指定不要 */
 cell tThroughComponent comp{
   cSR = TargetCell.eS;   /* TargetCell でアロケータ指定が必要 */
 };

リレーアロケータの場合も、上述のアロケータの例と同様に、アロケータ呼び口と結合が生成されます。 tThroughComponent のセルタイプコードでは、以下のアロケータ呼び口関数が生成されます。 ただし、受け取ったものをそのまま渡すため、これらの呼び口関数は、実際には使用する必要はありません。 もし、受け取ったものをそのまま渡すのではなく、再アロケート(reallc) するような場合には、これらの呼び口を用いることになります。 (この例では realloc は含まれません)

// allocator port for call port: eA func: snd param: buf
  ER             eA_snd_buf_alloc( subscript, int32_t size, void** p );
  ER             eA_snd_buf_dealloc( subscript, const void* p );
// allocator port for call port: eA func: rcv param: buf
  ER             eA_rcv_buf_alloc( subscript, int32_t size, void** p );
  ER             eA_rcv_buf_dealloc( subscript, const void* p );
// allocator port for call port: eS func: snd param: buf
  ER             eS_snd_buf_alloc( int32_t size, void** p );
  ER             eS_snd_buf_dealloc( const void* p );
// allocator port for call port: eS func: rcv param: buf
  ER             eS_rcv_buf_alloc( int32_t size, void** p );
  ER             eS_rcv_buf_dealloc( const void* p );
// allocator port for call port: cSR func: snd param: buf
  ER             cSR_snd_buf_alloc( int32_t size, void** p );
  ER             cSR_snd_buf_dealloc( const void* p );
// allocator port for call port: cSR func: rcv param: buf
  ER             cSR_rcv_buf_alloc( int32_t size, void** p );
  ER             cSR_rcv_buf_dealloc( const void* p );

マクロ

以下に、TECS ジェネレータが生成し、セルタイプコードで使用可能なマクロの一覧を記します。 セルタイプコードを記述する場合、短縮形を用います。

マクロ

短縮形

通常形

IDXの正当性チェック

VALID_IDX

tCelltype_VALID_IDX

セルCBを得るマクロ

GET_CELLCB

tCelltype_GET_CELLCB

属性アクセスマクロ

ATTR_attribute

tCelltype_ATTR_attribute

内部変数アクセスマクロ

VAR_variable

tCelltype_VAR_variable

呼び口関数マクロ

cCall_func

受け口関数マクロ

eEntry_func

tCelltype_eEntry_func

呼び口関数マクロ

cCall_func

呼び口配列サイズマクロ

NCP_cCall

N_CP_cCall

FOREACH_CELLマクロ

FOREACH_CELL

この表では、一例を示しています。 以下のような置き換えが必要です。

  • attribute は属性名に置き換える

  • variable は内部変数名に置き換える

  • func は関数名に置き換える

  • cCall は呼び口名に置き換える

  • eEntry は受け口名に置き換える

  • tCelltype はセルタイプ名に置き換える

短縮形マクロ

短縮形マクロは、通常形に優先して使用されることが意図されています。 また、テンプレートコードは、短縮形の使用を意図して生成されています。 属性・変数参照マクロでは CELLCB へのポインタが p_cellcb という名前で定義されることが仮定されています。

セルCBを得るマクロ(短縮形)

セル CB を得るマクロは、GET_CELLCB です。

【マクロ定義例】

#define GET_CELLCB(idx)  tAttribute_GET_CELLCB(idx)

IDXの正当性チェックマクロ(短縮形)

IDXの正当性チェックマクロは VALID_IDX です。

【マクロ定義例】

#define VALID_IDX(IDX)  tAttribute_VALID_IDX(IDX)

属性アクセスマクロ(短縮形)

属性アクセスマクロは、接頭辞 'ATTR_' に属性名を結合した名前です。

【マクロ定義例】

#define ATTR_size              ((p_cellcb)->_inib->size)
#define ATTR_size_array        ((p_cellcb)->_inib->size_array)
#define ATTR_ptr               ((p_cellcb)->_inib->ptr)

内部変数アクセスマクロ(短縮形)

内部変数アクセスマクロは、接頭辞 'VAR_' に属性名を結合した名前です。

【マクロ定義例】

#define VAR_sz_array           ((p_cellcb)->sz_array)

呼び口配列の大きさを得るマクロ(短縮形)

呼び口配列の大きさを得るマクロは、接頭辞 'NCP_' に呼び口名を結合した名前です。 呼び口が配列の場合のみ、このマクロが生成されます。

【マクロ定義例】

#define NCP_carray    (2)

【訂正】(2016/11/12) 本マニュアルの最初の公開時(以前のTECS 仕様書においても)、呼び口配列の大きさを得るマクロについて、(NCP_cCall ではなく) N_CP_cCall としていましたが、これは引数を取る場合と、取らない場合がありました。シングルトン、または配列添数が定数の場合に引数を取りませんでした。なお、TECS ジェネレータの生成するテンプレートのコメントは、以前から NCP_cCall の形式となっていました。

オプショナル呼び口テストマクロ(短縮形)

呼び口配列の場合、このマクロで結合をチェックする前に、呼び口配列の大きさが1以上であることを確認してください。

【マクロ定義例】

#define is_cCall_joined      ((p_cellcb)->_inib->cCall!=0)

通常形マクロ

通常形のマクロは、他のセルの属性、変数を参照するために使用することが意図されています。

IDXの正当性チェックマクロ

【マクロ定義例】

#define tAttribute_VALID_IDX(IDX) (1)

セルCBを得るマクロ

【マクロ定義例】

#define tAttribute_GET_CELLCB(idx) (idx)

属性アクセスマクロ

【マクロ定義例】

#define tAttribute_ATTR_size( p_that ) ((p_that)->_inib->size)
#define tAttribute_ATTR_size_array( p_that )   ((p_that)->_inib->size_array)
#define tAttribute_ATTR_ptr( p_that )  ((p_that)->_inib->ptr)

#define tAttribute_GET_size(p_that)    ((p_that)->_inib->size)
#define tAttribute_GET_size_array(p_that)      ((p_that)->_inib->size_array)
#define tAttribute_GET_ptr(p_that)     ((p_that)->_inib->ptr)

変数アクセスマクロ

【マクロ定義例】

#define tAttribute_VAR_sz_array        ((p_cellcb)->sz_array)

#define tAttribute_GET_sz_array(p_that)        ((p_that)->sz_array)
#define tAttribute_SET_sz_array(p_that,val)    ((p_that)->sz_array=(val))

オプショナル呼び口テストマクロ

呼び口配列の場合、このマクロで結合をチェックする前に、呼び口配列の大きさが1以上であることを確認すること。

【マクロ定義例】

#define tCelltype_is_cCall_joined(p_that)      ((p_that)->_inib->cCall!=0)

ファイルの一覧

TECS コンポーネント実装で用いられるファイルの一覧をまとめたものです。

種類

ファイル名

自動生成

備考

セルタイプコード

CELLTYPE.c

テンプレート自動生成

種類

ファイル名

自動生成

備考

セルタイプヘッダ

CELLLTYPE_tecsgen.h

セルタイプファクトリヘッダ

CELLLTYPE_factory.h

セルタイプtecsgenコード

CELLLTYPE_tecsgen.c

セルタイプインラインコード

CELLLTYPE_inline.h

テンプレート自動生成

△は、プラグインにより自動生成される場合があることを表します。

セルタイプコードは、インライン指定されていない受け口関数を実装するものです。 一方、セルタイプインラインコードは、インライン指定された受け口関数を実装するものです。

自動生成されたファイルは、編集することは意図されていません。 テンプレートは、TECS ジェネレータの実行により上書きされるため、別に移してから編集します。

ASP3+TECS

TOPPERS/ASP3

課題

to be filled in

目次:

ASP3+TECSについて

課題

to be filled in

カーネルオブジェクトのID番号

TOPPERS/ASP3を含むμITRON準拠OSでは、いくつかのカーネルオブジェクトはID番号によって識別されます。静的APIの引数として識別子を指定することで、具体的な値はカーネルコンフィギュレータによって自動割付され、プログラム中からはその識別子を用いて値を参照することができます。

ASP3+TECSでは、TECSの機能を用いることで

課題

to be filled in

タスク ― tTask

タスクはプログラムの並行実行の単位です。

課題

to be filled in

使用方法

タスクの生成

アプリケーション開発者は tTask セルタイプのセルを生成することにより、タスクを生成することができます。次の例では MyTask という名前のタスクセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
    entry sTaskBody eTaskBody;
};

cell tMyCellType MyCell {};

cell tTask MyTask {
    attribute = C_EXP("TA_ACT");
    stackSize = 1024;
    priority = 42;

    cTaskBody = MyCell.eTaskBody;
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
タスクの制御

tTask が提供する eTask という名前の受け口を利用することにより、タスクの制御及び状態の取得を行うことができます。

app.cdl
cell tTask MyTask {};

celltype tMyAnotherCellType {
    call sTask cTask;
};

cell tMyAnotherCellType MyAnotherCell {
    cTask = MyTask.eTask;
};
tMyAnotherCellType.c
// タスクの起動
cTask_activate();

// タスクの現在状態の参照
T_RTSK taskStatus;
cTask_refer(&taskStatus);

なお、非タスクコンテキスト内では、eTask の代わりに eiTask を使用する必要があります。

リファレンス

セルタイプ
celltype tTask

タスクの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_TSK 静的API [NGKI1023] によりタスクの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("TSKID_$id$")

タスクのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL")

タスク属性 [NGKI3526] を C_EXP で囲んで指定します (省略可能)。複数個指定する場合、ビット毎の論理和演算子を用いて C_EXP("TA_ACT | TA_NOACTQUE") のようにして指定します。

TA_ACT

タスクの生成時にタスクを起動します。

TA_NOACTQUE

タスクに対する起動要求をキューイングしません。

TA_RSTR

生成するタスクを制約タスクとします。

注意

ASP3 カーネルでは、制約タスクはサポートしません [ASPS0102]。 ただし、制約タスク拡張パッケージを用いることで、制約タスクの機能を追加することができます [NGKI1022]。

attr PRI priority

タスクの起動時優先度を指定します。

attr size_t stackSize

スタック領域のサイズを指定します (バイト数)。

entry sTask  eTask

タスクの制御及び状態の取得を行うための受け口です。

entry siTask  eiTask

タスクの制御を行うための受け口です (非タスクコンテキスト用)。

call sTaskBody  cTaskBody

タスクの本体として呼び出される受け口をこの呼び口に結合します。

entry siNotificationHandler  eiActivateNotificationHandler

タイムイベント通知 の通知方法として「タスクの起動による通知」を用いる場合に結合する受け口です。

entry siNotificationHandler  eiWakeUpNotificationHandler

タイムイベント通知 の通知方法として「タスクの起床による通知」を用いる場合に結合する受け口です。

シグニチャ
signature sTask

タスクの制御、及び状態の取得を行うためのシグニチャです。

ER activate(void)

タスクに対して起動要求を行います。

この関数は act_tsk サービスコール [NGKI3529] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER_UINT cancelActivate(void)

タスクに対する処理されていない起動要求をすべてキャンセルし、キャンセルした起動要求の数を返します。

この関数は can_act サービスコール [NGKI1138] のラッパーです。

Return

キューイングされていた起動要求の数 (正の値または0) またはエラーコード。

ER getTaskState([out]STAT * p_tskstat)

タスクの状態を参照します。

この関数は get_tst サービスコール [NGKI3613] のラッパーです。

Param p_tskstat

タスク状態を入れるメモリ領域へのポインタ

Return

正常終了 (E_OK) またはエラーコード。

ER changePriority([in]PRI priority)

タスクのベース優先度を、 priority で指定した優先度に変更します。

この関数は chg_pri サービスコール [NGKI1183] のラッパーです。

Param priority

ベース優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER getPriority([out]PRI * p_priority)

タスクの現在優先度を参照します。

この関数は get_pri サービスコール [NGKI1202] のラッパーです。

Param p_priority

現在優先度を入れるメモリ領域へのポインタ

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out]T_RTSK * pk_taskStatus)

タスクの現在状態を参照します。

この関数は ref_tsk サービスコール [NGKI1217] のラッパーです。

Param pk_taskStatus

タスクの現在状態を入れるメモリ領域へのポインタ

Return

正常終了 (E_OK) またはエラーコード。

ER wakeup(void)

タスクを起床します。

この関数は wup_tsk サービスコール [NGKI3531] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER_UINT cancelWakeup(void)

タスクに対する処理されていない起床要求をすべてキャンセルし、キャンセルした起床要求の数を返します。

この関数は can_wup サービスコール [NGKI1276] のラッパーです。

Return

キューイングされていた起床要求の数 (正の値または0) またはエラーコード。

ER releaseWait(void)

タスクを強制的に待ち解除します。

この関数は rel_wai サービスコール [NGKI3532] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER suspend(void)

タスクを強制待ちにします。

この関数は sus_tsk サービスコール [NGKI1298] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER resume(void)

タスクを強制待ちから再開します。

この関数は rsm_tsk サービスコール [NGKI1312] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER raiseTerminate(void)

タスクに終了要求を行います。

この関数は ras_ter サービスコール [NGKI3469] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER terminate(void)

タスクを終了させます。

この関数は ter_tsk サービスコール [NGKI1170] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

signature siTask

タスクの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER activate(void)

タスクに対して起動要求を行います。

この関数は iact_tsk サービスコール [NGKI3529][NGKI0562] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER wakeup(void)

タスクを起床します。

この関数は iwup_tsk サービスコール [NGKI3531][NGKI0562] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER releaseWait(void)

タスクを強制的に待ち解除します。

この関数は irel_wai サービスコール [NGKI3532][NGKI0562] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

signature sTaskBody

タスクのメインルーチンとして呼び出される受け口に使用するシグニチャです。

void main(void)

タスクのメインルーチンとして呼び出されます。

実装の詳細

タスクの生成

tTask によるタスクの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write("tecsgen.cfg",
      "CRE_TSK(%s, { %s, $cbp$, tTask_start, %s, %s, NULL });",
                id, attribute, priority, stackSize);
};

最初の MyTask を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_TSK(TSKID_tTask_MyTask, { TA_ACT, &tTask_CB_tab[0], tTask_start, 42, 1024, NULL });

tTask が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

メインルーチン

上で示した静的 API 記述では、メインルーチンとして tTask_start という名前の関数が指定されています。この関数では以下に示すコードにより TECS への橋渡しを行います。

tTask.c
void
tTask_start(intptr_t exinf)
{
    CELLCB  *p_cellcb = (CELLCB *) exinf;

    cTaskBody_main();
}
サービスコール

eTask 及び eiTask に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tTask_inline.h
Inline ER
eTask_activate(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(act_tsk(ATTR_id));
}

イベントフラグ ― tEventflag

イベントフラグは、イベントの有無をビットごとのフラグで表現することにより、同期を行うためのオブジェクトです。

使用方法

イベントフラグの生成

アプリケーション開発者は tEventflag セルタイプのセルを生成することにより、イベントフラグを生成することができます。次の例では MyEventflag という名前のイベントフラグセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call sEventflag cEventflag;
};

cell tMyCellType MyCell {
  cEventflag = MyEventflag.eEventflag;
};

cell tEventflag MyEventflag {
  attribute = C_EXP("TA_NULL");
  flagPattern = 0;
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
イベントフラグの制御

todo tTask が提供する eTask という名前の受け口を利用することにより、タスクの制御及び状態の取得を行うことができます。

app.cdl
cell tTask MyTask {};

celltype tMyAnotherCellType {
    call sTask cTask;
};

cell tMyAnotherCellType MyAnotherCell {
    cTask = MyTask.eTask;
};
tMyAnotherCellType.c
// フラグのセット
FLGPTN setPattern;
cEventflag_set(setPattern);

// フラグの現在状態の参照
T_RFLG *pk_eventflagStatus;
cEventflag_refer(pk_eventflagStatus);

なお、非タスクコンテキスト内では、eEventflag の代わりに eiEventflag を使用する必要があります。

リファレンス

セルタイプ
celltype tEventflag

イベントフラグの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_FLG 静的API [NGKI1558] によりイベントフラグの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("FLGID_$id$");

イベントフラグのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL");

イベントフラグ属性 [NGKI1550] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

TA_WMUL

複数のタスクが待つのを許す。

TA_CLR

タスクの待ち解除時にイベントフラグをクリアする。

attr FLGPTN flagPattern

イベントフラグのビットパターン(符号なし整数)。

attr ACPTN accessPattern [4]

todo

entry sEventflag  eEventflag

イベントフラグの制御及び状態の取得を行うための受け口です。

entry siEventflag  eiEventflag

イベントフラグの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature sEventflag

イベントフラグの制御、及び状態の取得を行うためのシグニチャです。

ER set([in]FLGPTN setPattern)

イベントフラグに対して、setPatternで指定されるビットをセットします。サービスコール呼び出し前のビットパターンとsetPatternの値のビット毎の論理和に更新します。

この関数は set_flg サービスコール [NGKI3534] のラッパーです。

Param setPattern

セットするビットパターン。

Return

正常終了 (E_OK) またはエラーコード。

ER clear([in] FLGPTN clearPattern);

イベントフラグに対して、clearPatternが対応するビットが0になっているビットをクリアします。

この関数は clr_flg サービスコール [NGKI1611] のラッパーです。

Param clearPattern

クリアするビットパターン(ビット毎の反転値)。

Return

正常終了 (E_OK) またはエラーコード。

ER wait([in] FLGPTN waitPattern, [in] MODE waitFlagMode, [out] FLGPTN *p_flagPattern);

イベントフラグのビットパターンがwaitPatternとWaitFlagModeで指定される待ち解除条件満たすのを待ちます。

この関数は wai_flg サービスコール [NGKI1618] のラッパーです。

Param waitPattern

待ちビットパターン。

Param waitFlagMode

待ちモード。

Param p_flagPattern

待ち解除時のビットパターンを入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER waitPolling([in] FLGPTN waitPattern, [in] MODE waitFlagMode, [out] FLGPTN *p_flagPattern);

イベントフラグのビットパターンがwaitPatternとWaitFlagModeで指定される待ち解除条件満たすのを待ちます(ポーリング)。

この関数は pol_flg サービスコール [NGKI1619] のラッパーです。

Param waitPattern

待ちビットパターン。

Param waitFlagMode

待ちモード。

Param p_flagPattern

待ち解除時のビットパターンを入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER waitTimeout([in] FLGPTN waitPattern, [in] MODE waitFlagMode, [out] FLGPTN *p_flagPattern, [in] TMO timeout);

イベントフラグのビットパターンがwaitPatternとWaitFlagModeで指定される待ち解除条件満たすのを待ちます(タイムアウトあり)。

この関数は twai_flg サービスコール [NGKI1620] のラッパーです。

Param waitPattern

待ちビットパターン。

Param waitFlagMode

待ちモード。

Param p_flagPattern

待ち解除時のビットパターンを入れるメモリ領域へのポインタ。

Param timeout

タイムアウト指定。

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象イベントフラグを再初期化します。対象イベントフラグのビットパターンは初期ビットパターンに初期化されます。

この関数は ini_flg サービスコール [NGKI1639] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RFLG *pk_eventflagStatus);

イベントフラグの現在状態を参照します。

この関数は ref_flg サービスコール [NGKI1648] のラッパーです。

Param pk_eventflagStatus

イベントフラグの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siEventflag

イベントフラグの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER set([in] FLGPTN setPattern);

イベントフラグに対して、setPatternで指定されるビットをセットします。サービスコール呼び出し前のビットパターンとsetPatternの値のビット毎の論理和に更新します。

この関数は set_flg サービスコール [NGKI3534] のラッパーです。

Param setPattern

セットするビットパターン。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

イベントフラグの生成

tEventflag によるイベントフラグの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write( "tecsgen.cfg", "CRE_FLG(%s, { %s, %s});", id, attribute, flagPattern);
};

最初の MyEventflag を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_FLG( FLGID_tEventflag_MyEventflag, { TA_NULL, 0 });

tEventflag が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eEventflag 及び eiEventflag に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tEventflag_inline.h
Inline ER
eEventflag_set(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(set_flg(ATTR_id, FLGPTN setptn));
}

データキュー― tDataqueue

データキューは、1ワードのデータをメッセージとして、FIFO順で送受信するための同期・通信オブジェクトである。 より大きいサイズのメッセージを送受信したい場合には、メッセージを置いたメモリ領域へのポインタを1ワードのデータとして送受信する方法がある。 データキューは,データキューIDと呼ぶID番号によって識別する[NGKI1657].

課題

to be filled in

リファレンス

セルタイプ
celltype tDataqueue

データキューの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_DTQ 静的API [NGKI1665] によりデータキュー の生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("DTQID_$id$");

データキューのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL")

タスク属性 [NGKI3526] を C_EXP で囲んで指定します (省略可能)。

TA_TPRI

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

TA_NULL

送信待ち行列はFIFO順になる[NGKI1662]。

attr uint_t dataCount = 1;

データキュー管理領域に格納できるデータ数です。デフォルトは1に設定されます。

attr void * dataqueueManagementBuffer = C_EXP("NULL");

データキュー管理領域の先頭番地。デフォルトは C_EXP("NULL")に設定されます。 NULLとした場合,dtqcntで指定した数のデータを格納できるデータキュー管理領域が, コンフィギュレータまたはカーネルにより確保される[NGKI1682]。

entry sDataqueue  eDataqueue

データキューの制御及び状態の取得を行うための受け口です。

entry siDataqueue  eiDataqueue

データキューの制御を行うための受け口です (非タスクコンテキスト用)。

entry siNotificationHandler eiNotificationHandler;

タイムイベント通知 の通知方法として「データキューへの送信による通知」を用いる場合に結合する受け口です。

シグニチャ
signature sDataqueue

データキューの制御、及び状態の取得を行うためのシグニチャです。

ER send([in]intptr_t data)

データキューへの送信。

この関数は snd_dtq サービスコール [NGKI1718] のラッパーです。

Param data

送信データ。

Return

正常終了(E_OK)またはエラーコード。

ER sendPolling([in]intptr_t data)

データキューへの送信(ポーリング)。

この関数は psnd_dtq サービスコール [NGKI3535] のラッパーです。

Param data

送信データ。

Return

正常終了(E_OK)またはエラーコード。

ER sendTimeout([in]intptr_t data, [in]TMO timeout)

データキューへの送信(タイムアウト付き)。

この関数は tsnd_dtq サービスコール [NGKI1721] のラッパーです。

Param data

送信データ。

Param timeout

タイムアウト時間。

Return

またはエラーコード。

ER sendForce([in]intptr_t data)

データキューへの強制送信。

この関数は fsnd_dtq サービスコール [NGKI3536] のラッパーです。

Param data

送信データ。

Return

正常終了(E_OK)またはエラーコード。

ER receive([out]intptr_t * p_data)

データキューからの受信。

この関数は rcv_dtq サービスコール [NGKI1751] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Return

正常終了(E_OK)またはエラーコード。

ER receivePolling([out]intptr_t * p_data)

データキューからの受信(ポーリング)。

この関数は prcv_dtq サービスコール [NGKI1752] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Return

正常終了(E_OK)またはエラーコード。

ER receiveTimeout([out]intptr_t * p_data, [in]TMO timeout)

データキューからの受信(タイムアウト付き)。

この関数は trcv_dtq サービスコール [NGKI1753] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。。

Param timeout

Return

正常終了(E_OK)またはエラーコード。

ER initialize(void)

データキューの再初期。

この関数は ini_dtq サービスコール [NGKI1772] のラッパーです。

Return

正常終了(E_OK)またはエラーコード。

ER refer([out]T_RDTQ * pk_dataqueueStatus)

データキューの状態参照。

この関数は `` サービスコール [NGKI1781] のラッパーです。

Param pk_dataqueueStatus

データキューの現在状態を入れるパケットへのポインタ。

Return

正常終了(E_OK)またはエラーコード。

signature siDataqueue

データキューの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER sendPolling([in] intptr_t data);

タスクに対して起動要求を行います。

この関数は iact_tsk サービスコール [NGKI3529][NGKI0562] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER sendForce([in] intptr_t data);

タスクを起床します。

この関数は iwup_tsk サービスコール [NGKI3531][NGKI0562] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

データキューの生成

tDataqueue によるデータキューの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write("tecsgen.cfg", "CRE_DTQ(%s, { %s, %s, %s });",
          id, attribute, dataCount, dataqueueManagementBuffer);
};

最初の MyDataqueue を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_DTQ(DTQID__tDataqueue_Dataqueue, { TA_NULL, 1 ,C_EXP("NULL") });

tDataqueue が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eDataqueue 及び eiDataqueue に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tDataqueue_inline.h
Inline ER
eDataqueue_send(CELLIDX idx, intptr_t data)
{
   CELLCB  *p_cellcb = GET_CELLCB(idx);
   return(snd_dtq(ATTR_id, data));
}

タイムイベント通知

タイムイベント通知は、時間の経過 (タイムイベントの発生) をアプリケーションに通知する機能です。

タイムイベント通知には以下の2種類があり、これらを総括してタイムイベント通知と呼びます:

周期通知

サービスコールまたは静的APIによる指定で動作開始要求が行われると、指定した周期で、繰り返し通知を行います。通知が行われる時刻は、周期通知が起動された時刻、または TA_PHS 属性が指定された場合は周期通知が生成された時刻を基準として、通知位相+通知周期×(n-1) (n=1, 2, ...) と表すことができます。

アラーム通知

サービスコールで指定した相対時間後に通知を行います。

タイムイベントの通知は、次のいずれかの方法で行うことができます [NGKI3689]。

通知方法

対応する(疑似)コード

タイムイベントハンドラの呼出し

handler.ciHandlerBody.main();

変数の設定

*setVariableAddress = setVariableValue;

変数のインクリメント

++*incrementedVariableAddress;

タスクの起動

er = act_tsk(handler.id);

タスクの起床

er = wup_tsk(handler.id);

セマフォの資源の返却

er = sig_sem(handler.id);

イベントフラグのセット

er = set_flg(handler.id, flagPattern);

データキューへの送信

er = psnd_dtq(handler.id, dataqueueSentValue);

これらの通知方法のうち、最後の5つは通知のためのサービスコールがエラーを返し、タイムイベントの通知に失敗する場合があります。タイムイベントの通知に失敗した場合、エラーの通知を次のいずれかの方法で行うことができます [NGKI3690]。

エラー通知方法

対応する(疑似)コード

なし

変数の設定

*setVariableAddressForError = er;

変数のインクリメント

++*incrementedVariableAddressForError;

タスクの起動

act_tsk(errorHandler.id);

タスクの起床

wup_tsk(errorHandler.id);

セマフォの資源の返却

sig_sem(errorHandler.id);

イベントフラグのセット

set_flg(errorHandler.id, flagPatternForError);

データキューへの送信

psnd_dtq(errorHandler.id, er);

エラー通知が失敗した場合、エラーは無視され、何も行われません [NGKI3691]。

使用方法

周期通知・アラーム通知

アプリケーション開発者は tCyclicNotifier セルタイプのセルを生成することにより、周期通知を生成することができます。

cell tCyclicNotifier Cyclic {
    attribute = C_EXP("TA_STA"); // 生成直後から動作開始
    cycleTime = 1000000; // 1,000,000 マイクロ秒 (1秒) 周期
};

同様に、 tAlarmNotifier セルタイプのセルを生成することにより、アラーム通知を生成することができます。

cell tAlarmNotifier Alarm {
};

タイムイベント通知を使用する場合、さらに通知方法を指定する必要があります。通知方法の指定について次に説明します。 以下の説明では tAlarmNotifier のみを使用しますが、 tCyclicNotifier でも同様の方法で指定することができます。

変数の設定・インクリメントによる通知

変数の設定により通知を行いたい場合、まずヘッダファイルで変数を宣言します。続いてヘッダファイルの変数宣言をTECS CDLから import_C により読込み、 setVariableAddress 属性でその変数のアドレスを指定し、setVariableValue で設定する値を指定します。

app.c
#include "app.h"
intptr_t foo_variable;
app.h
extern intptr_t foo_variable;
import_C("app.h");
cell tAlarmNotifier Alarm {
    setVariableAddress = C_EXP("&foo_variable");
    setVariableValue = 42;
};

変数のインクリメントにより通知を行いたい場合は、incrementedVariableAddress で変数のアドレスを指定します。

import_C("app.h");
cell tAlarmNotifier Alarm {
    incrementedVariableAddress = C_EXP("&foo_variable");
};
タスクの起動・起床による通知

タスクの起動により通知を行いたい場合、タイムイベント通知セルの呼び口 ciNotificationHandler を、タスクの tTask::eiActivateNotificationHandler に結合します。

cell tTask MyTask { /* 省略 */ };
cell tAlarmNotifier Alarm {
    ciNotificationHandler = MyTask.eiActivateNotificationHandler;
};

同様に、tTask::eiWakeUpNotificationHandler に結合することで、タスクの起床により通知を行うことができます。

セマフォの返却による通知

タスクの起動により通知を行いたい場合、タイムイベント通知セルの呼び口 ciNotificationHandler を、セマフォの tSemaphore::eiNotificationHandler に結合します。

cell tSemaphore MySemaphore { /* 省略 */ };
cell tAlarmNotifier Alarm {
    ciNotificationHandler = MySemaphore.eiNotificationHandler;
};
イベントフラグのセットによる通知

イベントフラグのセットにより通知を行いたい場合、タイムイベント通知セルの呼び口 ciNotificationHandler を、セマフォの tEventflag::eiNotificationHandler に結合します。セットするフラグパターンは属性 flagPattern により指定します。

cell tEventflag MyEventFlag { /* 省略 */ };
cell tAlarmNotifier Alarm {
    ciNotificationHandler = MyEventFlag.eiNotificationHandler;
    flagPattern = 1;
};
データキューへの送信による通知

データキューへの送信により通知を行いたい場合、タイムイベント通知セルの呼び口 ciNotificationHandler を、セマフォの tDataqueue::eiNotificationHandler に結合します。セットするフラグパターンは属性 dataqueueSentValue により指定します。

cell tDataqueue MyDataqueue { /* 省略 */ };
cell tAlarmNotifier Alarm {
    ciNotificationHandler = MyDataqueue.eiNotificationHandler;
    dataqueueSentValue = 0xdeadbeef;
};
ハンドラ関数による通知

ハンドラ関数により通知を行いたい場合、tAlarmNotifier, tCyclicNotifier の代わりに tAlarmHandler, tCyclicHandler を使用します。通知先にシグニチャ siHandlerBody の受け口を定義し、タイムイベント通知セルの呼び口 ciHandlerBody をその受け口に結合します。

tMyCellType.c
void eiHandlerBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
celltype tMyCellType {
    entry siHandlerBody eiHandlerBody;
};

cell tMyCellType MyCell {};

cell tAlarmHandler Alarm {
    ciHandlerBody = MyCell.eiHandlerBody;
};

注意

タイムイベントの通知方法は複数ありますが、各タイムイベント通知に対し一度に指定できる通知方法は一つに制限されます。 例えば、 setVariableAddress (設定先変数) と incrementedVariableAddress (インクリメント先変数) を同時に指定することはできず、この指定があるときにTECSジェネレータを実行すると、エラーが発生します。

通知方法を指定しなかった場合もエラーとなります。

エラー通知

以上の通知方法のうち、タスクの起動, タスクの起床, セマフォの資源の返却, イベントフラグのセット, データキューへの送信の5つは、内部的にはそれぞれ対応するサービスコールの呼出しにより実現されています。 サービスコールの呼出しが行われるとき、様々な要因によりサービスコールが失敗しエラーを返すことがあります。エラーが発生する具体的状況をいくつか挙げてみましょう (網羅的ではありません):

  • タスクの起動 (act_tsk): タスク起動要求キューイングオーバーフロー (E_QOVR)

  • タスクの起床 (wup_tsk): タスクが休止状態 (E_OBJ)、タスク起床要求キューイングオーバーフロー (E_QOVR)

  • セマフォの資源の返却: セマフォの資源数がすでに最大値に達している (E_QOVR)

  • イベントフラグのセット: (ASP3+TECS で発生するエラーはありません)

  • データキューへの送信: バッファオーバフロー (E_TMOUT)

タイムイベント通知には、こうした場合にもう一つの通知方法を用いてエラーを通知することができます。

エラー通知方法は、通常の通知と同様に指定することができます (ただし、ハンドラ関数をエラー通知に用いることはできません)。呼び口は ciNotificationHandler の代わりに ciErrorNotificationHandler を用い、属性は末尾に ForError を加えたものを使用しますが、いくつか例外が存在します。属性名の対応表を次に示します:

通常通知

エラー通知

setVariableAddress

setVariableAddressForError

setVariableValue

--

incrementedVariableAddress

incrementedVariableAddressForError

flagPattern

flagPatternForError

dataqueueSentValue

--

この表の右の列が空欄になっている属性は、対応する属性が存在せず、エラー番号が代わりの値として使用されます。

注意

通常の通知方法と同様に、エラー通知方法は複数ありますが、各タイムイベント通知に対し一度に指定できるエラー通知方法は一つに制限されます。

エラー通知方法の指定を省略することは可能ですが、TECSジェネレータの実行時に警告が出力されます。警告を表示したくない場合は属性 ignoreErrorstrue に設定してください。

通常の通知方法がエラーが発生しないもの (タイムイベントハンドラの呼出し, 変数の設定, 変数のインクリメント) である場合、エラー通知方法を指定することはできず、指定した場合はエラーが発生します。

周期通知を制御する

tCyclicNotifier が提供する eCyclic という名前の受け口を利用することにより、周期通知の制御及び状態の取得を行うことができます。

app.cdl
cell tCyclicNotifier Cyclic {};

celltype tMyCellType {
    call sCyclic cCyclic;
};

cell tMyCellType MyCell {
    cCyclic = Cyclic.eCyclic;
};
tMyCellType.c
// 周期通知を動作開始
cCyclic_start();

// 周期通知の現在状態の参照
T_RCYC cyclicStatus;
cCyclic_refer(&cyclicStatus);

周期通知は非タスクコンテキストから操作することはできません。

アラーム通知を制御する

tAlarmNotifier が提供する eAlarm という名前の受け口を利用することにより、アラーム通知の制御及び状態の取得を行うことができます。

app.cdl
cell tAlarmNotifier Alarm {};

celltype tMyCellType {
    call sAlarm cAlarm;
};

cell tMyCellType MyCell {
    cAlarm = Alarm.eAlarm;
};
tMyCellType.c
// アラーム通知を動作開始
cAlarm_start(1000000); // 1,000,000 マイクロ秒 (1秒) 後に通知

// アラーム通知の現在状態の参照
T_RALM alarmStatus;
cAlarm_refer(&alarmStatus);

非タスクコンテキスト内では、eAlarm の代わりに eiAlarm を使用する必要があります。

リファレンス

セルタイプ
celltype tAlarmNotifier

アラーム通知の生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_ALM 静的API [NGKI2487] によりアラーム通知の生成を行います。

注意

通知方法に関係する属性はTECSのコンポーネントモデル上はすべて「省略可能」として定義されていますが、実際には専用のTECSジェネレータプラグインの働きにより、複雑な条件によって指定が制約されています。可能な指定方法については使用方法のセクションを参照して下さい。

attr ID id = C_EXP("ALMID_$id$")

アラーム通知のID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL")

アラーム通知属性を C_EXP で囲んで指定します (省略可能)。ASP3では指定できる属性はありません [NGKI3423] ので、指定できる値は C_EXP("TA_NULL") のみです [NGKI3424]。

attr bool_t ignoreErrors = false

通知方法としてエラーが発生する可能性があるもの (タスクの起動, タスクの起床, セマフォの資源の返却, イベントフラグのセット, データキューへの送信) を指定しているとき、エラー通知方法を指定しなかった場合、TECSジェネレータ実行時に警告を出力するかを指定します (省略可能)。

デフォルト値は false で、エラー通知方法が未指定の場合に警告を出力します。

attr intptr_t * setVariableAddress = 0

通知方法として「変数の設定」を使用する場合に、設定先の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t setVariableValue = 0

通知方法として「変数の設定」を使用する場合に、変数に設定する値を指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t * incrementedVariableAddress = 0

通知方法として「変数のインクリメント」を使用する場合に、インクリメント対象の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr FLGPTN flagPattern = 0

通知方法として「イベントフラグのセット」を使用する場合に、セットするフラグパターンを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t dataqueueSentValue = 0

通知方法として「データキューへの送信」を使用する場合に、データキューに送信する値を指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t * setVariableAddressForError = 0

エラー通知方法として「変数の設定」を使用する場合に、エラーコードを設定する先の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t * incrementedVariableAddressForError = 0

エラー通知方法として「変数のインクリメント」を使用する場合に、インクリメント対象の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr FLGPTN flagPatternForError = 0

エラー通知方法として「イベントフラグのセット」を使用する場合に、セットするフラグパターンを指定します。

他の通知方法を使用する場合は、指定してはけません。

call siNotificationHandler ciNotificationHandler

通知先のセルを結合します。結合可能なセルタイプ・受け口は通知方法ごとに異なります。

通知方法

セルタイプ, 受け口

タイムイベントハンドラの呼出し

tTimeEventHandler::eiNotificationHandler

変数の設定

結合してはいけません

変数のインクリメント

結合してはいけません

タスクの起動

tTask::eiActivateNotificationHandler

タスクの起床

tTask::eiWakeUpNotificationHandler

セマフォの資源の返却

tSemaphore::eiNotificationHandler

イベントフラグのセット

tEventflag::eiNotificationHandler

データキューへの送信

tDataqueue::eiNotificationHandler

上記の表にないセルタイプ・受け口を結合した場合、TECSジェネレータ実行時にエラーが発生します。

call siNotificationHandler ciErrorNotificationHandler

エラー通知先のセルを結合します。結合可能なセルタイプ・受け口は通知方法ごとに異なります。

エラー通知方法

セルタイプ, 受け口

なし

結合してはいけません

変数の設定

結合してはいけません

変数のインクリメント

結合してはいけません

タスクの起動

tTask::eiActivateNotificationHandler

タスクの起床

tTask::eiWakeUpNotificationHandler

セマフォの資源の返却

tSemaphore::eiNotificationHandler

イベントフラグのセット

tEventflag::eiNotificationHandler

データキューへの送信

tDataqueue::eiNotificationHandler

上記の表にないセルタイプ・受け口を結合した場合、TECSジェネレータ実行時にエラーが発生します。

entry sAlarm eAlarm

アラーム通知の制御及び状態の取得を行うための受け口です (タスクコンテキスト用)。

entry siAlarm eiAlarm

アラーム通知の制御を行うための受け口です (非タスクコンテキスト用)。

celltype tCyclicNotifier

周期通知の生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_CYC 静的API [NGKI3727] により周期通知の生成を行います。

周期通知は、動作している状態と動作していない状態のいずれかをとり [NGKI2366]、動作している状態にすることを動作開始、動作していない状態にすることを動作停止と呼びます。

周期通知による通知は、基準時刻を基準として、 cyclePhase+cyclicTime*(n-1) (n=1, 2, ...) で表される時刻に行われます。基準時刻は属性 TA_PHS を指定した場合は周期通知の生成がされた時刻、指定されなかった場合は周期通知が最後に動作開始した時刻が用いられます [NGKI2365]。

注意

通知方法に関係する属性はTECSのコンポーネントモデル上はすべて「省略可能」として定義されていますが、実際には専用のTECSジェネレータプラグインの働きにより、複雑な条件によって指定が制約されています。可能な指定方法については使用方法のセクションを参照して下さい。

attr ID id = C_EXP("CYCID_$id$")

周期通知のID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL")

周期通知属性を C_EXP で囲んで指定します [NGKI2370] (省略可能)。複数個指定する場合、ビット毎の論理和演算子を用いて C_EXP("TA_STA | TA_PHS") のようにして指定します。

TA_STA

周期通知の生成時に周期通知を動作開始します。

TA_PHS

周期通知を生成した時刻を基準時刻とします。

attr RELTIM cycleTime

周期通知の通知周期をマイクロ秒単位で指定します。

attr RELTIM cyclePhase = 0

周期通知の通知位相をマイクロ秒単位で指定します (省略可能)。

attr bool_t ignoreErrors = false

通知方法としてエラーが発生する可能性があるもの (タスクの起動, タスクの起床, セマフォの資源の返却, イベントフラグのセット, データキューへの送信) を指定しているとき、エラー通知方法を指定しなかった場合、TECSジェネレータ実行時に警告を出力するかを指定します (省略可能)。

デフォルト値は false で、エラー通知方法が未指定の場合に警告を出力します。

attr intptr_t * setVariableAddress = 0

通知方法として「変数の設定」を使用する場合に、設定先の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t setVariableValue = 0

通知方法として「変数の設定」を使用する場合に、変数に設定する値を指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t * incrementedVariableAddress = 0

通知方法として「変数のインクリメント」を使用する場合に、インクリメント対象の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr FLGPTN flagPattern = 0

通知方法として「イベントフラグのセット」を使用する場合に、セットするフラグパターンを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t dataqueueSentValue = 0

通知方法として「データキューへの送信」を使用する場合に、データキューに送信する値を指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t * setVariableAddressForError = 0

エラー通知方法として「変数の設定」を使用する場合に、エラーコードを設定する先の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr intptr_t * incrementedVariableAddressForError = 0

エラー通知方法として「変数のインクリメント」を使用する場合に、インクリメント対象の変数を指すポインタを指定します。

他の通知方法を使用する場合は、指定してはけません。

attr FLGPTN flagPatternForError = 0

エラー通知方法として「イベントフラグのセット」を使用する場合に、セットするフラグパターンを指定します。

他の通知方法を使用する場合は、指定してはけません。

call siNotificationHandler ciNotificationHandler

通知先のセルを結合します。結合可能なセルタイプ・受け口は通知方法ごとに異なります。

通知方法

セルタイプ, 受け口

タイムイベントハンドラの呼出し

tTimeEventHandler::eiNotificationHandler

変数の設定

結合してはいけません

変数のインクリメント

結合してはいけません

タスクの起動

tTask::eiActivateNotificationHandler

タスクの起床

tTask::eiWakeUpNotificationHandler

セマフォの資源の返却

tSemaphore::eiNotificationHandler

イベントフラグのセット

tEventflag::eiNotificationHandler

データキューへの送信

tDataqueue::eiNotificationHandler

上記の表にないセルタイプ・受け口を結合した場合、TECSジェネレータ実行時にエラーが発生します。

call siNotificationHandler ciErrorNotificationHandler

エラー通知先のセルを結合します。結合可能なセルタイプ・受け口は通知方法ごとに異なります。

エラー通知方法

セルタイプ, 受け口

なし

結合してはいけません

変数の設定

結合してはいけません

変数のインクリメント

結合してはいけません

タスクの起動

tTask::eiActivateNotificationHandler

タスクの起床

tTask::eiWakeUpNotificationHandler

セマフォの資源の返却

tSemaphore::eiNotificationHandler

イベントフラグのセット

tEventflag::eiNotificationHandler

データキューへの送信

tDataqueue::eiNotificationHandler

上記の表にないセルタイプ・受け口を結合した場合、TECSジェネレータ実行時にエラーが発生します。

entry sCyclic eCyclic

周期通知の制御及び状態の取得を行うための受け口です (タスクコンテキスト用)。

非タスクコンテキスト用の受け口はありません。

celltype tTimeEventHandler

タイムイベント通知セルで、通知方法「タイムイベントハンドラの呼出し」により通知を行いたい場合に使用するセルタイプです。

一般的なアプリケーションではこのセルタイプを直接する必要はなく、 tAlarmHandler または tCyclicHandler を使用することが推奨されます。

entry siNotificationHandler eiNotificationHandler

通知元のタイムイベント通知セルの tAlarmNotifier::ciNotificationHandler または tCyclicNotifier::ciNotificationHandler に結合します。

call siHandlerBody ciHandlerBody

タイムイベントハンドラの本体となる受け口を結合します。

celltype tAlarmHandler

アラーム通知の生成、制御及び状態の取得を行うコンポーネントです。このセルタイプはハンドラ関数により通知を行う場合に使用します。他の通知方法を使用したい場合、 tAlarmNotifier を使用して下さい。

本コンポーネントは CRE_ALM 静的API [NGKI2487] によりアラーム通知の生成を行います。

attr ID id = C_EXP("ALMID_$id$")

アラーム通知のID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL")

アラーム通知属性を C_EXP で囲んで指定します (省略可能)。ASP3では指定できる属性はありません [NGKI3423] ので、指定できる値は C_EXP("TA_NULL") のみです [NGKI3424]。

entry sAlarm eAlarm

アラーム通知の制御及び状態の取得を行うための受け口です (タスクコンテキスト用)。

entry siAlarm eiAlarm

アラーム通知の制御を行うための受け口です (非タスクコンテキスト用)。

call siHandlerBody ciHandlerBody
celltype tCyclicHandler

周期通知の生成、制御及び状態の取得を行うコンポーネントです。このセルタイプはハンドラ関数により通知を行う場合に使用します。他の通知方法を使用したい場合、 tCyclicNotifier を使用して下さい。

本コンポーネントは CRE_CYC 静的API [NGKI3727] により周期通知の生成を行います。

周期通知は、動作している状態と動作していない状態のいずれかをとり [NGKI2366]、動作している状態にすることを動作開始、動作していない状態にすることを動作停止と呼びます。

周期通知による通知は、基準時刻を基準として、 cyclePhase+cyclicTime*(n-1) (n=1, 2, ...) で表される時刻に行われます。基準時刻は属性 TA_PHS を指定した場合は周期通知の生成がされた時刻、指定されなかった場合は周期通知が最後に動作開始した時刻が用いられます [NGKI2365]。

attr ID id = C_EXP("CYCID_$id$")

周期通知のID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute = C_EXP("TA_NULL")

周期通知属性を C_EXP で囲んで指定します [NGKI2370] (省略可能)。複数個指定する場合、ビット毎の論理和演算子を用いて C_EXP("TA_STA | TA_PHS") のようにして指定します。

TA_STA

周期通知の生成時に周期通知を動作開始します。

TA_PHS

周期通知を生成した時刻を基準時刻とします。

attr RELTIM cycleTime

周期通知の通知周期をマイクロ秒単位で指定します。

attr RELTIM cyclePhase = 0

周期通知の通知位相をマイクロ秒単位で指定します (省略可能)。

entry sCyclic eCyclic

周期通知の制御及び状態の取得を行うための受け口です (タスクコンテキスト用)。

非タスクコンテキスト用の受け口はありません。

call siHandlerBody ciHandlerBody
シグニチャ
signature siHandlerBody

タイムイベントハンドラの本体の呼出しに用いるシグニチャです。

void main(void)

ハンドラの本体です。タイムイベントが発生した際に、カーネルによって呼び出されます。

signature sAlarm

アラーム通知の制御、及び状態の取得を行うためのシグニチャです (タスクコンテキスト用)。

ER start([in]RELTIM alarmTime)

アラーム通知を動作開始します。既に動作している状態である場合、通知時刻の再設定のみが行われます。

この関数は sta_alm サービスコール [NGKI3543] のラッパーです。

Param alarmTime

通知時刻 (現在時刻からの相対時間, マイクロ秒単位)

Return

正常終了 (E_OK) またはエラーコード。

ER stop(void)

アラーム通知を動作停止します。動作していない状態である場合、何も行われずに正常終了します。

この関数は stp_alm サービスコール [NGKI3545] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out]T_RALM * pk_alarmStatus)

アラーム通知の現在状態を参照します。

この関数は ref_alm サービスコール [NGKI2572] のラッパーです。

Param pk_alarmStatus

アラーム通知の現在状態を入れるメモリ領域へのポインタ

Return

正常終了 (E_OK) またはエラーコード。

signature siAlarm

アラーム通知の制御、及び状態の取得を行うためのシグニチャです (非タスクコンテキスト用)。

ER start([in]RELTIM alarmTime)

アラーム通知を動作開始します。既に動作している状態である場合、通知時刻の再設定のみが行われます。

この関数は ista_alm サービスコール [NGKI3543][NGKI0562] のラッパーです。

Param alarmTime

通知時刻 (現在時刻からの相対時間, マイクロ秒単位)

Return

正常終了 (E_OK) またはエラーコード。

ER stop(void)

アラーム通知を動作停止します。動作していない状態である場合、何も行われずに正常終了します。

この関数は istp_alm サービスコール [NGKI3545][NGKI0562] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

signature sCyclic

周期通知の制御、及び状態の取得を行うためのシグニチャです (タスクコンテキスト用)。

非タスクコンテキスト用のシグニチャはありません。

ER start(void)

周期通知を動作開始します。既に動作している状態である場合、次回通知時刻の再設定のみが行われます。

この関数は sta_cyc サービスコール [NGKI2431] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER stop(void)

周期通知を動作停止します。動作していない状態である場合、何も行われずに正常終了します。

この関数は stp_cyc サービスコール [NGKI2455] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out]T_RCYC * pk_cyclicHandlerStatus)

周期通知の現在状態を参照します。

この関数は ref_cyc サービスコール [NGKI2463] のラッパーです。

Param pk_cyclicHandlerStatus

周期通知の現在状態を入れるメモリ領域へのポインタ

Return

正常終了 (E_OK) またはエラーコード。

signature siNotificationHandler

タイムイベント通知の通知先を指定するためシグニチャです。 アプリケーション定義のセルではこのシグニチャの呼び口・受け口を定義しないで下さい。

このシグニチャに関数は含まれていません。

実装の詳細

タイムイベント通知の生成

tAlarmNotifier 及び tCyclicNotifier によるタイムイベント通知の生成は、パラメータの指定方法が特殊な為ファクトリ記述では行えず、代わりに TECS ジェネレータセルタイププラグイン NotifierPlugin を利用して行います。

kernel.cdl (抜粋)
[active, generate(NotifierPlugin,
  "factory=\"CRE_ALM({{id}}, { {{attribute}}, {{{_handler_params_}}} });\", "
  "output_file=tecsgen.cfg")]
celltype tAlarmNotifier {
  /* ... */
};

NotifierPlugin は、対象のセルタイプに、タイムイベント通知固有の属性及び呼び口のセットが定義されていると仮定し、セルに指定された属性値と、プラグインの引数として指定されたテンプレート文字列を基にして、適切な静的 API 記述を生成します。以下はテンプレート文字列を抜粋したものです。

tAlarmNotifier のテンプレート文字列
CRE_ALM({{id}}, { {{attribute}}, {{{_handler_params_}}} });

この中に含まれる二重中かっこで囲われた属性名 (e.g., {{id}}) は、対応する属性値で置換されます。ただし、 {{_handler_params_}} は特別な扱いを受け、この後説明する通知先指定アルゴリズムにより、通知先を指定するパラメータ列で置換されます。 例えば、タスクイベント通知の使用方法の一つとしてタスクを通知先とする場合を例として挙げましたが、この場合は次の静的 API 記述が生成されます。

tecsgen.cfg
CRE_ALM(ALMID_tAlarmNotifier_Alarm, { TA_NULL, { TNFY_ACTTSK, TSKID_tTask_MyTask }});

属性値は id を除き、全て静的 API 記述の引数、または NotifierPlugin の入力としてのみ用いられます。この為、 [omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

通知先の指定

タイムイベント通知の通知先としてカーネルオブジェクトを指定する場合、静的 API にはハンドラ関数ではなく、通知先オブジェクトの ID を直接指定することになります。 NotifierPlugin では、通知先オブジェクトの ID を呼び口 ciNotificationHandler 及び ciErrorNotificationHandler の結合先の属性値を読み取ることで、通知先を決定します。

したがって、これらの呼び口に対応するシグニチャ siNotificationHandler は実行時には使用されず、この為、このシグニチャには関数は定義されていません。

通知先指定アルゴリズムの役割は、セルの属性値・呼び口の結合先の組み合わせを、オペレーティングシステムの仕様で定義されている通知方法 [NGKI3689] にマッピングし、その通知方法を指定するのに必要な適切なパラメータ列を生成することです。このアルゴリズムの説明に入る前に、いくつか用語を定義しておきましょう。

ハンドラ

通常通知とエラー通知を、ここではハンドラと呼びます。例えば「各ハンドラに対応する呼び口がある」と言う場合、通常通知用の呼び口とエラー通知用の呼び口が個別に存在することを意味します。

共通呼び口

通知先オブジェクトを結合するための呼び口 (ハンドラ毎に存在し、それぞれ ciNotificationHandler 及び ciErrorNotificationHandler) は共通呼び口と呼ばれます。

これらの呼び口が共通呼び口と呼ばれる理由は、通知先オブジェクトが種類が何であっても、全てこの呼び口に結合することで、通知先を指定することになる為です。

ハンドラタイプ

通知方法を細分化し、通常通知とエラー通知の違いを表せるようにしたものです。

通知方法

通常のハンドラ

エラーハンドラ

なし

N/A

NullHandlerType

タイムイベントハンドラの呼出し

UserHandlerType

N/A

変数の設定

SetVariableHandlerType

SetVariableToErrorCodeHandlerType

変数のインクリメント

IncrementVariableHandlerType

タスクの起動

ActivateTaskHandlerType

タスクの起床

WakeUpTaskHandlerType

セマフォの資源の返却

SignalSemaphoreHandlerType

イベントフラグのセット

SetEventflagHandlerType

データキューへの送信

SendToDataqueueHandlerType

SendErrorCodeToDataqueueHandlerType

通知先指定アルゴリズムは各タイムイベント通知セル (厳密に言うと、NotifierPluginが適用されたセルタイプのセル) に対し、以下の手順を実施します。

  1. 以下のステップを各ハンドラに対して実行する。

    1. 現在処理中のハンドラに対応する共通呼び口の結合先のセルのIDとセルタイプ名を取得する。また、通知先指定に関わる属性の属性値及び、指定の有無 (いずれも [optional] として指定されているが、ここではそれは重要ではない) を取得する。

    2. 各ハンドラタイプが持つ属性・結合先セルタイプ名の組み合わせと、実際に指定されたものを照合する。完全一致するものが存在しなかった場合、エラーを出力して当該セルの処理を終了する。

    3. 現在処理中のハンドラ用の静的 API 記述のパラメータ列を含む断片を生成する。

  2. 通常のハンドラが「エラーが発生する可能性がある」ものとしてマークされている場合、エラーハンドラが指定されている (NullHandlerType 以外のハンドラタイプである) ことを確認する。もし指定されておらず、ignoreErrorstrue ではない場合、警告を出力する。

  3. 通常のハンドラが「エラーが発生する可能性がある」ものとしてマークされていないのにも関わらず、エラーハンドラが指定されている場合、エラーを出力する。

  4. 前のステップで得られた静的 API 記述の断片と、指定されたテンプレート文字列を用い、最終的な静的 API 記述を生成する。

ユーザハンドラの呼び出し

呼び口 ciNotificationHandlertTimeEventHandler::eiNotificationHandler が結合された場合、ハンドラタイプ UserHandlerType が選択され、ユーザハンドラの呼び出しに必要な静的 API 記述が生成されます。

ユーザの便宜のために単体でユーザハンドラ受け口に直接結合可能な tAlarmHandler, tCyclicHandler が用意されています。これらは複合セルタイプで、それぞれ tAlarmNotifier, tCyclicNotifier と、tTimeEventHandler が含まれ、tTimeEventHandler::ciHandlerBody がエクスポートされており、ユーザはこれをアプリケーション定義のセルの受け口に結合するだけで使用することができます。

ユーザハンドラの呼び出しに必要な静的 API の引数は以下の通りです [NGKI3722]。

type T_NFY_HDR

タイムイベントハンドラ呼出し用の付随情報を含む構造体。

intptr_t exinf

タイムイベントハンドラに渡される引数。

TMEHDR tmehdr

タイムイベントハンドラの先頭番地。

従って T_NFY_HDR::tmehdr にハンドラ関数を指定する訳ですが、ユーザハンドラの受け口関数を直接ここに指定することはできません。受け口関数のシグニチャは状況によって4通りに変化します。

void tCelltype_eiHandlerBody_main(CELLIDX idx); // tCelltypeが非singleton, 受け口が配列でない
void tCelltype_eiHandlerBody_main(void); // singleton, 受け口が配列でない
void tCelltype_eiHandlerBody_main(CELLIDX idx, int_t subscript); // 非singleton, 受け口配列
void tCelltype_eiHandlerBody_main(int_t subscript); // singleton, 受け口配列

このため、カーネルからの呼出しを仲介するための関数が必要となります。この関数はアダプタ関数と呼ばれ、NotifierPlugin によって生成されます。

アダプタ関数は受け口関数を呼ぶ際、最大3個の情報 (受け口関数, idx, subscript) が必要となります。T_NFY_HDR::exinf を介して引数を受け取ることができますが、これを介して直接渡せる引数は1個だけです。解決策には様々なものがありますが、NotifierPlugin では引数のうち1個を T_NFY_HDR::exinf を介して渡し、受け口関数と残った引数はその値ごとに関数を特殊化するアプローチを採用しています。このアプローチは最も時間・空間効率に優れていると考えられています。

生成例を示します。以下はハンドラ受け口が非配列で、所属セルタイプが [singleton] ではない場合の出力例です (紙面の節約のため、簡略化しています)。

tecsgen.cfg
CRE_CYC(ALMID_tCyclicHandler_CyclicHandler, { TA_NULL, { TNFY_HANDLER,
  &tCT_CB_tab[1], tTimeEventHandler_tCyclicNotifier_tCT_eiHandlerBody_adap }, 50, 0 });
tTimeEventHandler.c
void
tTimeEventHandler_tCyclicNotifier_tCT_eiHandlerBody_adap
(intptr_t extinf) {
    tCT_eiHandlerBody_main((CELLIDX)extinf);
}

次はハンドラ受け口が配列で、周期通知が複数ある場合の出力です。アダプタ関数が特定のセル Cell に特殊化されていることに着目して下さい。

tecsgen.cfg
CRE_CYC(ALMID_tCyclicHandler_CyclicHandler, { TA_NULL, { TNFY_HANDLER,
  0, tTimeEventHandler_tCyclicNotifier_tCT_eiHandlerBody_adap_Cell }, 50, 0 });
CRE_CYC(ALMID_tCyclicHandler_CyclicHandler, { TA_NULL, { TNFY_HANDLER,
  1, tTimeEventHandler_tCyclicNotifier_tCT_eiHandlerBody_adap_Cell }, 50, 0 });
tTimeEventHandler.c
void
tTimeEventHandler_tCyclicNotifier_tCT_eiHandlerBody_adap_Cell
(intptr_t extinf) {
    tCT_eiHandlerBody_main(&tCT_CB_tab[1], (int_t)extinf);
}
サービスコール

eCycliceAlarm 及び eiAlarm に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tAlarmNotifier_inline.h
Inline ER
eAlarm_start(CELLIDX idx, RELTIM alarmTime)
{
  CELLCB  *p_cellcb = GET_CELLCB(idx);
  return(sta_alm(ATTR_id, alarmTime));
}

セマフォ ― tSemaphore

セマフォは、使用されていない資源の有無や数量を数値で表現することにより、その資源を使用する際の排他制御や同期を行うためのオブジェクトである。

使用方法

セマフォの生成

アプリケーション開発者は tSemaphore セルタイプのセルを生成することにより、セマフォを生成することができます。次の例では MySemaphore という名前のセマフォセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call sSemaphore cSemaphore;
};

cell tMyCellType MyCell {
  cSemaphore = MySemaphore.eSemaphore;
};

cell tSemaphore MySemaphore {
  attribute = C_EXP("TA_NULL");
  count = 0;
  max = 1;
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
セマフォの制御

tSemaphore が提供する eSemaphore という名前の受け口を利用することにより、セマフォの制御及び状態の取得を行うことができます。

app.cdl
cell tSemaphore MySemaphore {};

celltype tMyAnotherCellType {
    call sSemaphore cSemaphore;
};

cell tMyAnotherCellType MyAnotherCell {
    cSemaphore = MySemaphore.eSemaphore;
};
tMyAnotherCellType.c
// セマフォ資源の返却
cSemaphore_signal();

// セマフォの現在状態の参照
T_RSEM *pk_semaphoreStatus;
cSemaphorek_refer(pk_semaphoreStatus);

なお、非タスクコンテキスト内では、eSemaphore の代わりに eiSemaphore を使用する必要があります。

リファレンス

セルタイプ
celltype tSemaphore

セマフォの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_SEM 静的API [NGKI1452] によりセマフォの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("SEMID_$id$");

セマフォのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute

セマフォ属性 [NGKI1448] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

attr uint32_t count

セマフォの初期資源数。

attr uint32_t max = 1;

セマフォの最大資源数。

entry sSemaphore  eSemaphore

セマフォの制御及び状態の取得を行うための受け口です。

entry siSemaphore  eiSemaphore

セマフォの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature sSemaphore

セマフォの制御、及び状態の取得を行うためのシグニチャです。

ER signal(void)

対象セマフォに資源を返却します。対象セマフォの待ち行列にタスクが存在する場合には、待ち行列の先頭のタスクが待ち解除されます。

この関数は sig_sem サービスコール [NGKI3533] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER wait(void);

対象セマフォから資源を獲得します。対象セマフォの資源数が1以上の場合には、資源数から1が減ぜられます。

この関数は wai_sem サービスコール [NGKI1510] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER waitPolling(void);

対象セマフォから資源を獲得します(ポーリング)。対象セマフォの資源数が1以上の場合には、資源数から1が減ぜられます。

この関数は pol_sem サービスコール [NGKI1511] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER waitTimeout([in] TMO timeout);

対象セマフォから資源を獲得します(タイムアウト付き)。対象セマフォの資源数が1以上の場合には、資源数から1が減ぜられます。

この関数は twai_sem サービスコール [NGKI1512] のラッパーです。

Param timeout

タイムアウト時間

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象セマフォを再初期化します。対象セマフォの資源数は初期資源数に初期化されます。

この関数は ini_sem サービスコール [NGKI1526] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RSEM *pk_semaphoreStatus);

セマフォの現在状態を参照します。

この関数は ref_sem サービスコール [NGKI1535] のラッパーです。

Param pk_semaphoreStatus

セマフォの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siSemaphore

セマフォの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER signal();

この関数は sig_sem サービスコール [NGKI3533] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

セマフォの生成

tSemaphore によるセマフォの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
  write( "tecsgen.cfg", "CRE_SEM(%s, { %s, %s, %s });", id, attribute, count, max);
};

最初の MySemaphore を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_SEM( SEMID_tSemaphore_MySemaphore, { TA_NULL, 0, 1 });

tSemaphore が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eSemaphore 及び eiSemaphore に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tSemaphore_inline.h
Inline ER
eSemaphore_signal(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(sig_sem(ATTR_id));
}

優先度データキュー ― tPriorityDataqueue

優先度データキューは、1ワードのデータをメッセージとして、データの優先度順で送受信するための同期・通信カーネルオブジェクトである。より大きいサイズのメッセージを送受信したい場合には、メッセージを置いたメモリ領域へのポインタを1ワードのデータとして送受信する方法がある。優先度データキューは,優先度データキューIDと呼ぶID番号によって識別する [NGKI1791]。

使用方法

優先度データキューの生成

アプリケーション開発者は tPriorityDataqueue セルタイプのセルを生成することにより、優先度データキューを生成することができます。次の例では MyPriorityDataqueue という名前の優先度データキューセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call sPriorityDataqueue cPriorityDataqueue;
};

cell tMyCellType MyCell {
  cPriorityDataqueue = MyPriorityDataqueue.ePriorityDataqueue;
};

cell tPriorityDataqueue MyPriorityDataqueue {
  attribute = C_EXP("TA_NULL");
  count = 1;
  maxDataPriority = C_EXP("TMAX_DPRI");
  pdqmb = C_EXP( "NULL" );
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
優先度データキューの制御

tPriorityDataqueue が提供する ePriorityDataqueue という名前の受け口を利用することにより、優先度データキューの制御及び状態の取得を行うことができます。

app.cdl
cell tPriorityDataqueue MyPriorityDataqueue {};

celltype tMyAnotherCellType {
    call sPriorityDataqueue cPriorityDataqueue;
};

cell tMyAnotherCellType MyAnotherCell {
    cPriorityDataqueue = MyPriorityDataqueue.ePriorityDataqueue;
};
tMyAnotherCellType.c
// 優先度データキューの送信
intptr_t data;
PRI dataPriority;
cPriorityDataqueue_send( data, dataPriority );

// 優先度データキューの受信
intptr_t *p_data;
PRI *p_dataPriority;
cPriorityDataqueue_receive( p_data, p_dataPriority );

なお、非タスクコンテキスト内では、ePriorityDataqueue の代わりに eiPriorityDataqueue を使用する必要があります。

リファレンス

セルタイプ
celltype tPriorityDataqueue

優先度データキューの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_PDQ 静的API [NGKI1800] により優先度データキューの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("PDQID_$id$");

優先度データキューのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute

優先度データキュー属性 [NGKI1795] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

attr uint32_t count = 1;

優先度データキューの容量。

attr PRI maxDataPriority

優先度データキューに送信できるデータ優先度の最大値。

attr void * pdqmb = C_EXP("NULL");

優先度データキュー管理領域の先頭番地。

entry sPriorityDataqueue  ePriorityDataqueue

優先度データキューの制御及び状態の取得を行うための受け口です。

entry siPriorityDataqueue  eiPriorityDataqueue

優先度データキューの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature sPriorityDataqueue

優先度データキューの制御、及び状態の取得を行うためのシグニチャです。

ER send([in]intptr_t data, [in]PRI dataPriority)

対象優先度データキューに、dataで指定したデータを、dataPriorityで指定した優先度で送信します。対象優先度データキューの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendPolling([in]intptr_t data, [in]PRI dataPriority)

対象優先度データキューに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(ポーリング)。対象優先度データキューの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は psnd_pdq サービスコール [NGKI3537] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendTimeout([in]intptr_t data, [in]PRI dataPriority, [in]TMO timeout)

対象優先度データキューに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(タイムアウト付き)。対象優先度データキューの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は tsnd_pdq サービスコール [NGKI1858] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER receive([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象優先度データキューからデータを受信します。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は rcv_pdq サービスコール [NGKI1877] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receivePolling([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象優先度データキューからデータを受信します(ポーリング)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は prcv_pdq サービスコール [NGKI1878] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receiveTimeout([out]intptr_t * p_data, [in]PRI * p_dataPriority, [in]TMO timeout)

対象優先度データキューからデータを受信します(タイムアウト付き)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は trcv_pdq サービスコール [NGKI1879] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象優先度データキューを再初期化します。対象優先度データキューの優先度データキュー管理領域は、格納されているデータがない状態に初期化されます。

この関数は ini_pdq サービスコール [NGKI1902] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RSEM *pk_priorityDataqueueStatus);

優先度データキューの現在状態を参照します。

この関数は ref_pdq サービスコール [NGKI1911] のラッパーです。

Param pk_priorityDataqueueStatus

優先度データキューの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siPriorityDataqueue

優先度データキューの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER sendPolling([in]intptr_t data, [in] PRI dataPriority);

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

優先度データキューの生成

tPriorityDataqueue による優先度データキューの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write( "tecsgen.cfg", "CRE_PDQ( %s, { %s, %s, %s, %s} );",
         id, attribute, count, maxDataPriority, pdqmb);
};

最初の MyPriorityDataqueue を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_PDQ( PDQID_tPriorityDataqueue_MyPriorityDataqueue, { TA_NULL, 1, TMAX_DPRI, NULL });

tPriorityDataqueue が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

ePriorityDataqueue 及び eiPriorityDataqueue に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tPriorityDataqueue_inline.h
Inline ER
ePriorityDataqueue_send(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(snd_pdq(ATTR_id));
}

固定長メモリプール ― tFixedSizeMemoryPool

固定長メモリプールは、生成時に決めたサイズのメモリブロック(固定長メモリブロック)を動的に獲得・返却するための同期・通信オブジェクトである。固定長メモリプールは、固定長メモリプールIDと呼ばれるID番号で識別する [NGKI2215]。

使用方法

固定長メモリプールの生成

アプリケーション開発者は tFixedSizeMemoryPool セルタイプのセルを生成することにより、固定長メモリプールを生成することができます。次の例では MyFixedSizeMemoryPool という名前の固定長メモリプールセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call sFixedSizeMemoryPool cFixedSizeMemoryPool;
};

cell tMyCellType MyCell {
  cFixedSizeMemoryPool = MyFixedSizeMemoryPool.eFixedSizeMemoryPool;
};

cell tFixedSizeMemoryPool MyFixedSizeMemoryPool {
  attribute = C_EXP("TA_NULL");
  blockCount = TODO;
  blockSize = ;
  mpf = C_EXP("NULL");
  mpfmb = C_EXP("NULL");
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
固定長メモリプールの制御

tFixedSizeMemoryPool が提供する eFixedSizeMemoryPool という名前の受け口を利用することにより、固定長メモリプールの制御及び状態の取得を行うことができます。

app.cdl
cell tFixedSizeMemoryPool MyFixedSizeMemoryPool {};

celltype tMyAnotherCellType {
    call sFixedSizeMemoryPool cFixedSizeMemoryPool;
};

cell tMyAnotherCellType MyAnotherCell {
    cFixedSizeMemoryPool = MyFixedSizeMemoryPool.eFixedSizeMemoryPool;
};
tMyAnotherCellType.c
// 固定長メモリブロックの獲得
void **p_block;
cFixedSizeMemoryPool_get(p_block);

// 固定長メモリプールの現在状態の取得
T_RMPF *pk_memoryPoolFixedSizeStatus
cFixedSizeMemoryPool_refer(pk_memoryPoolFixedSizeStatus);

なお、非タスクコンテキスト内では、eFixedSizeMemoryPool の代わりに eiFixedSizeMemoryPool を使用する必要があります。

リファレンス

セルタイプ
celltype tFixedSizeMemoryPool

固定長メモリプールの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_MPF 静的API [NGKI2221] により固定長メモリプールの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("MPFID_$id$");

固定長メモリプールのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute

固定長メモリプール属性 [NGKI2218] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

attr uint32_t blockCount

TODO

attr uint32_t blockSize

TODO

attr MPF_T * mpf = C_EXP("NULL");

TODO

attr void * mpfmb = C_EXP("NULL");

固定長メモリプール管理領域の先頭番地。

entry sFixedSizeMemoryPool  eFixedSizeMemoryPool

固定長メモリプールの制御及び状態の取得を行うための受け口です。

entry siFixedSizeMemoryPool  eiFixedSizeMemoryPool

固定長メモリプールの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature sFixedSizeMemoryPool

固定長メモリプールの制御、及び状態の取得を行うためのシグニチャです。

ER get([out]void ** p_block)

対象固定長メモリプールから固定長メモリブロックを獲得し、その先頭番地をp_blockが指すメモリ領域に返す。

この関数は get_mpf サービスコール [NGKI2287] のラッパーです。

Param p_block

獲得した固定長メモリブロックの先頭番地を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER getPolling([out]void ** p_block)

対象固定長メモリプールから固定長メモリブロックを獲得し、その先頭番地をp_blockが指すメモリ領域に返す(ポーリング)。

この関数は pget_mpf サービスコール [NGKI2288] のラッパーです。

Param p_block

獲得した固定長メモリブロックの先頭番地を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER getTimeout([out]void ** p_block, [in]TMO timeout)

対象固定長メモリプールから固定長メモリブロックを獲得し、その先頭番地をp_blockが指すメモリ領域に返す(タイムアウト付き)。

この関数は tget_mpf サービスコール [NGKI2289] のラッパーです。

Param p_block

獲得した固定長メモリブロックの先頭番地を入れるメモリ領域へのポインタ。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER release([in]const void * block)

対象固定長メモリプールに、blkで指定した固定長メモリブロックを返却する。

この関数は rls_mpf サービスコール [NGKI2304] のラッパーです。

Param block

返却する固定長メモリブロックの先頭番地。

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象固定長メモリプールを再初期化します。対象固定長メモリプールの固定長メモリプール管理領域は、格納されているデータがない状態に初期化されます。

この関数は ini_mpf サービスコール [NGKI2314] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RSEM *pk_fixedSizeMemoryPoolStatus);

固定長メモリプールの現在状態を参照します。

この関数は ref_mpf サービスコール [NGKI2323] のラッパーです。

Param pk_fixedSizeMemoryPoolStatus

固定長メモリプールの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siFixedSizeMemoryPool

固定長メモリプールの制御を行うためのシグニチャです (非タスクコンテキスト用)。TODO(元々非タスクコンテキスト?kernel.cdlを見る限り)

ER sendPolling([in]intptr_t data, [in] PRI dataPriority);

この関数は snd_mpf サービスコール [NGKI1855] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

固定長メモリプールの生成

tFixedSizeMemoryPool による固定長メモリプールの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
  write("tecsgen.cfg","CRE_MPF( %s, {%s, %s, %s, %s, %s} );",
      id, attribute, blockCount, blockSize, mpf, mpfmb);
};

最初の MyFixedSizeMemoryPool を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_MPF( MPFID_tFixedSizeMemoryPool_MyFixedSizeMemoryPool, { TA_NULL, TODO, TODO, NULL, NULL });

tFixedSizeMemoryPool が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eFixedSizeMemoryPool 及び eiFixedSizeMemoryPool に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tFixedSizeMemoryPool_inline.h
Inline ER
eFixedSizeMemoryPool_get(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(get_mpf(ATTR_id));
}

初期化ルーチン ― tInitializeRoutine

初期化ルーチンは、カーネルが実行を制御する処理単位で、カーネルの動作開始の直前に、カーネル非動作状態で実行される [NGKI1791]。

使用方法

初期化ルーチンの生成

アプリケーション開発者は tInitializeRoutine セルタイプのセルを生成することにより、初期化ルーチンを生成することができます。次の例では MyInitializeRoutine という名前の初期化ルーチンセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call sInitializeRoutineBody cInitializeRoutine;
};

cell tMyCellType MyCell {
  cInitializeRoutine = MyInitializeRoutine.eInitializeRoutine;
};

cell tInitializeRoutine MyInitializeRoutine {
  attribute = C_EXP("TA_NULL");
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
初期化ルーチンの制御

tInitializeRoutine が提供する eInitializeRoutine という名前の受け口を利用することにより、初期化ルーチンの制御及び状態の取得を行うことができます。

app.cdl
cell tInitializeRoutine MyInitializeRoutine {};

celltype tMyAnotherCellType {
    call sInitializeRoutineBody cInitializeRoutine;
};

cell tMyAnotherCellType MyAnotherCell {
    cInitializeRoutine = MyInitializeRoutine.eInitializeRoutine;
};
tMyAnotherCellType.c
// 初期化ルーチン本体
cInitializeRoutine_main();

なお、非タスクコンテキスト内では、eInitializeRoutine の代わりに eiInitializeRoutine を使用する必要があります。

リファレンス

セルタイプ
celltype tInitializeRoutine

初期化ルーチンの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_PDQ 静的API [NGKI1800] により初期化ルーチンの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("PDQID_$id$");

初期化ルーチンのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute

初期化ルーチン属性 [NGKI1795] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

attr uint32_t count = 1;

初期化ルーチンの容量。

attr PRI maxDataPriority

初期化ルーチンに送信できるデータ優先度の最大値。

attr void * pdqmb = C_EXP("NULL");

初期化ルーチン管理領域の先頭番地。

entry sInitializeRoutineBody  eInitializeRoutine

初期化ルーチンの制御及び状態の取得を行うための受け口です。

entry siInitializeRoutine  eiInitializeRoutine

初期化ルーチンの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature sInitializeRoutineBody

初期化ルーチンの制御、及び状態の取得を行うためのシグニチャです。

ER send([in]intptr_t data, [in]PRI dataPriority)

対象初期化ルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します。対象初期化ルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendPolling([in]intptr_t data, [in]PRI dataPriority)

対象初期化ルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(ポーリング)。対象初期化ルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は psnd_pdq サービスコール [NGKI3537] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendTimeout([in]intptr_t data, [in]PRI dataPriority, [in]TMO timeout)

対象初期化ルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(タイムアウト付き)。対象初期化ルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は tsnd_pdq サービスコール [NGKI1858] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER receive([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象初期化ルーチンからデータを受信します。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は rcv_pdq サービスコール [NGKI1877] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receivePolling([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象初期化ルーチンからデータを受信します(ポーリング)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は prcv_pdq サービスコール [NGKI1878] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receiveTimeout([out]intptr_t * p_data, [in]PRI * p_dataPriority, [in]TMO timeout)

対象初期化ルーチンからデータを受信します(タイムアウト付き)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は trcv_pdq サービスコール [NGKI1879] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象初期化ルーチンを再初期化します。対象初期化ルーチンの初期化ルーチン管理領域は、格納されているデータがない状態に初期化されます。

この関数は ini_pdq サービスコール [NGKI1902] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RSEM *pk_initializeRoutineStatus);

初期化ルーチンの現在状態を参照します。

この関数は ref_pdq サービスコール [NGKI1911] のラッパーです。

Param pk_initializeRoutineStatus

初期化ルーチンの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siInitializeRoutine

初期化ルーチンの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER sendPolling([in]intptr_t data, [in] PRI dataPriority);

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

初期化ルーチンの生成

tInitializeRoutine による初期化ルーチンの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write( "tecsgen.cfg", "CRE_PDQ( %s, { %s, %s, %s, %s} );",
         id, attribute, count, maxDataPriority, pdqmb);
};

最初の MyInitializeRoutine を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_PDQ( PDQID_tInitializeRoutine_MyInitializeRoutine, { TA_NULL, 1, TMAX_DPRI, NULL });

tInitializeRoutine が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eInitializeRoutine 及び eiInitializeRoutine に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tInitializeRoutine_inline.h
Inline ER
eInitializeRoutine_send(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(snd_pdq(ATTR_id));
}

終了処理ルーチン ― tTerminateRoutine

終了処理ルーチンは、1ワードのデータをメッセージとして、データの優先度順で送受信するための同期・通信カーネルオブジェクトである。より大きいサイズのメッセージを送受信したい場合には、メッセージを置いたメモリ領域へのポインタを1ワードのデータとして送受信する方法がある。終了処理ルーチンは,終了処理ルーチンIDと呼ぶID番号によって識別する [NGKI1791]。

使用方法

終了処理ルーチンの生成

アプリケーション開発者は tTerminateRoutine セルタイプのセルを生成することにより、終了処理ルーチンを生成することができます。次の例では MyTerminateRoutine という名前の終了処理ルーチンセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call sTerminateRoutine cTerminateRoutine;
};

cell tMyCellType MyCell {
  cTerminateRoutine = MyTerminateRoutine.eTerminateRoutine;
};

cell tTerminateRoutine MyTerminateRoutine {
  attribute = C_EXP("TA_NULL");
  count = 1;
  maxDataPriority = C_EXP("TMAX_DPRI");
  pdqmb = C_EXP( "NULL" );
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
終了処理ルーチンの制御

tTerminateRoutine が提供する eTerminateRoutine という名前の受け口を利用することにより、終了処理ルーチンの制御及び状態の取得を行うことができます。

app.cdl
cell tTerminateRoutine MyTerminateRoutine {};

celltype tMyAnotherCellType {
    call sTerminateRoutine cTerminateRoutine;
};

cell tMyAnotherCellType MyAnotherCell {
    cTerminateRoutine = MyTerminateRoutine.eTerminateRoutine;
};
tMyAnotherCellType.c
// 終了処理ルーチンの送信
intptr_t data;
PRI dataPriority;
cTerminateRoutine_send( data, dataPriority );

// 終了処理ルーチンの受信
intptr_t *p_data;
PRI *p_dataPriority;
cTerminateRoutine_receive( p_data, p_dataPriority );

なお、非タスクコンテキスト内では、eTerminateRoutine の代わりに eiTerminateRoutine を使用する必要があります。

リファレンス

セルタイプ
celltype tTerminateRoutine

終了処理ルーチンの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_PDQ 静的API [NGKI1800] により終了処理ルーチンの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("PDQID_$id$");

終了処理ルーチンのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute

終了処理ルーチン属性 [NGKI1795] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

attr uint32_t count = 1;

終了処理ルーチンの容量。

attr PRI maxDataPriority

終了処理ルーチンに送信できるデータ優先度の最大値。

attr void * pdqmb = C_EXP("NULL");

終了処理ルーチン管理領域の先頭番地。

entry sTerminateRoutine  eTerminateRoutine

終了処理ルーチンの制御及び状態の取得を行うための受け口です。

entry siTerminateRoutine  eiTerminateRoutine

終了処理ルーチンの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature sTerminateRoutine

終了処理ルーチンの制御、及び状態の取得を行うためのシグニチャです。

ER send([in]intptr_t data, [in]PRI dataPriority)

対象終了処理ルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します。対象終了処理ルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendPolling([in]intptr_t data, [in]PRI dataPriority)

対象終了処理ルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(ポーリング)。対象終了処理ルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は psnd_pdq サービスコール [NGKI3537] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendTimeout([in]intptr_t data, [in]PRI dataPriority, [in]TMO timeout)

対象終了処理ルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(タイムアウト付き)。対象終了処理ルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は tsnd_pdq サービスコール [NGKI1858] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER receive([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象終了処理ルーチンからデータを受信します。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は rcv_pdq サービスコール [NGKI1877] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receivePolling([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象終了処理ルーチンからデータを受信します(ポーリング)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は prcv_pdq サービスコール [NGKI1878] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receiveTimeout([out]intptr_t * p_data, [in]PRI * p_dataPriority, [in]TMO timeout)

対象終了処理ルーチンからデータを受信します(タイムアウト付き)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は trcv_pdq サービスコール [NGKI1879] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象終了処理ルーチンを再終了処理します。対象終了処理ルーチンの終了処理ルーチン管理領域は、格納されているデータがない状態に終了処理されます。

この関数は ini_pdq サービスコール [NGKI1902] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RSEM *pk_terminateRoutineStatus);

終了処理ルーチンの現在状態を参照します。

この関数は ref_pdq サービスコール [NGKI1911] のラッパーです。

Param pk_terminateRoutineStatus

終了処理ルーチンの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siTerminateRoutine

終了処理ルーチンの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER sendPolling([in]intptr_t data, [in] PRI dataPriority);

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

終了処理ルーチンの生成

tTerminateRoutine による終了処理ルーチンの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write( "tecsgen.cfg", "CRE_PDQ( %s, { %s, %s, %s, %s} );",
         id, attribute, count, maxDataPriority, pdqmb);
};

最初の MyTerminateRoutine を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_PDQ( PDQID_tTerminateRoutine_MyTerminateRoutine, { TA_NULL, 1, TMAX_DPRI, NULL });

tTerminateRoutine が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eTerminateRoutine 及び eiTerminateRoutine に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tTerminateRoutine_inline.h
Inline ER
eTerminateRoutine_send(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(snd_pdq(ATTR_id));
}

割込みサブルーチン ― tISR

割込みサブルーチンは、カーネルが実行を制御する処理単位である。割込みサブルーチンは,割込みサブルーチンIDと呼ぶID番号によって識別する [NGKI2947]。

使用方法

割込みサブルーチンの生成

アプリケーション開発者は tISR セルタイプのセルを生成することにより、割込みサブルーチンを生成することができます。次の例では MyISR という名前の割込みサブルーチンセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
  call siHandlerBody ciBody;
};

cell tMyCellType MyCell {
  ciBody = MyISR.eISR;
};

cell tISR MyISR {
  attribute = C_EXP( "TA_NULL" );
  interruptNumber = TODO;
  priority = 1;
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
割込みサブルーチンの制御

tISR が提供する eISR という名前の受け口を利用することにより、割込みサブルーチンの制御及び状態の取得を行うことができます。

app.cdl
cell tISR MyISR {};

celltype tMyAnotherCellType {
    call siHandlerBody ciBody;
};

cell tMyAnotherCellType MyAnotherCell {
    ciBody = MyISR.eISR;
};
tMyAnotherCellType.c
// 割込みの許可
ciBody_enable();

// 割込みの禁止
ciBody_disable();

なお、非タスクコンテキスト内では、eISR の代わりに eiISR を使用する必要があります。

リファレンス

セルタイプ
celltype tISR

割込みサブルーチンの生成、制御及び状態の取得を行うコンポーネントです。

本コンポーネントは CRE_PDQ 静的API [NGKI1800] により割込みサブルーチンの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。

attr ID id = C_EXP("PDQID_$id$");

割込みサブルーチンのID番号の識別子 (詳しくは カーネルオブジェクトのID番号 を参照) を C_EXP で囲んで指定します (省略可能)。

attr ATR attribute

割込みサブルーチン属性 [NGKI1795] を C_EXP で囲んで指定します (省略可能)。

TA_NULL

デフォルト値(FIFO待ち)。

TA_TPRI

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

attr uint32_t count = 1;

割込みサブルーチンの容量。

attr PRI maxDataPriority

割込みサブルーチンに送信できるデータ優先度の最大値。

attr void * pdqmb = C_EXP("NULL");

割込みサブルーチン管理領域の先頭番地。

entry siHandlerBody  eISR

割込みサブルーチンの制御及び状態の取得を行うための受け口です。

entry siISR  eiISR

割込みサブルーチンの制御を行うための受け口です (非タスクコンテキスト用)。

シグニチャ
signature siHandlerBody

割込みサブルーチンの制御、及び状態の取得を行うためのシグニチャです。

ER send([in]intptr_t data, [in]PRI dataPriority)

対象割込みサブルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します。対象割込みサブルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendPolling([in]intptr_t data, [in]PRI dataPriority)

対象割込みサブルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(ポーリング)。対象割込みサブルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は psnd_pdq サービスコール [NGKI3537] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Return

正常終了 (E_OK) またはエラーコード。

ER sendTimeout([in]intptr_t data, [in]PRI dataPriority, [in]TMO timeout)

対象割込みサブルーチンに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(タイムアウト付き)。対象割込みサブルーチンの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。

この関数は tsnd_pdq サービスコール [NGKI1858] のラッパーです。

Param data

送信データ。

Param dataPriority

送信データの優先度。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER receive([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象割込みサブルーチンからデータを受信します。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は rcv_pdq サービスコール [NGKI1877] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receivePolling([out]intptr_t * p_data, [in]PRI * p_dataPriority)

対象割込みサブルーチンからデータを受信します(ポーリング)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は prcv_pdq サービスコール [NGKI1878] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

ER receiveTimeout([out]intptr_t * p_data, [in]PRI * p_dataPriority, [in]TMO timeout)

対象割込みサブルーチンからデータを受信します(タイムアウト付き)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。

この関数は trcv_pdq サービスコール [NGKI1879] のラッパーです。

Param p_data

受信データを入れるメモリ領域へのポインタ。

Param p_dataPriority

受信データの優先度を入れるメモリ領域へのポインタ。

Param timeout

タイムアウト時間。

Return

正常終了 (E_OK) またはエラーコード。

ER initialize(void);

対象割込みサブルーチンを再割込みサブします。対象割込みサブルーチンの割込みサブルーチン管理領域は、格納されているデータがない状態に割込みサブされます。

この関数は ini_pdq サービスコール [NGKI1902] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

ER refer([out] T_RSEM *pk_isrStatus);

割込みサブルーチンの現在状態を参照します。

この関数は ref_pdq サービスコール [NGKI1911] のラッパーです。

Param pk_isrStatus

割込みサブルーチンの現在状態を入れるメモリ領域へのポインタ。

Return

正常終了 (E_OK) またはエラーコード。

signature siISR

割込みサブルーチンの制御を行うためのシグニチャです (非タスクコンテキスト用)。

ER sendPolling([in]intptr_t data, [in] PRI dataPriority);

この関数は snd_pdq サービスコール [NGKI1855] のラッパーです。

Return

正常終了 (E_OK) またはエラーコード。

実装の詳細

割込みサブルーチンの生成

tISR による割込みサブルーチンの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。

kernel.cdl (抜粋)
factory {
    write( "tecsgen.cfg", "CRE_PDQ( %s, { %s, %s, %s, %s} );",
         id, attribute, count, maxDataPriority, pdqmb);
};

最初の MyISR を用いた例の場合、以下のような静的API記述が生成されます。

tecsgen.cfg
CRE_PDQ( PDQID_tISR_MyISR, { TA_NULL, 1, TMAX_DPRI, NULL });

tISR が持つ属性は、 id を除き実行時にはすべて未使用である為、[omit] 指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。

サービスコール

eISR 及び eiISR に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。

tISR_inline.h
Inline ER
eISR_send(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    return(snd_pdq(ATTR_id));
}

ATK2+TECS

ATK2+TECS

課題

to be filled in

目次:

ATK2+TECS について

課題

to be filled in

カーネル ― tKernel

課題

to be filled in

使用方法

カーネルの生成

アプリケーション開発者は tKernel セルタイプのセルを生成することにより、カーネルを生成することができます。次の例では MyKernel という名前のタスクセルを生成し、 MyCellsHookBody を結合しています。

app.cdl
celltype tMyCellType {
    entry sHookBody   eStartupHookBody;
};

cell tMyCellType MyCell {};

cell tKernel MyKernel {
    cStartupHookBody[0] = Sample.eStartupHookBody;
    cPreTaskHookBody = Sample.ePreTaskHookBody;
    cPostTaskHookBody = Sample.ePostTaskHookBody;
    cErrorHookBody = Sample.eErrorHookBody;
    cShutdownHookBody[0] = Sample.eShutdownHookBody;
    status = "EXTENDED";
    useGetServiceId = TRUE;
    useParameterAccess = TRUE;
    StackMonitoring = TRUE;
    stackSize = 512;
    ScalabilityClass ="SC1";
};
tMyCellType.c
void eStartupHookBody_main()
{
  #ifdef TOPPERS_ENABLE_SYS_TIMER
    target_timer_initialize();
  #endif /* TOPPERS_ENABLE_SYS_TIMER */
  syslog_initialize();
  syslog_msk_log(LOG_UPTO(LOG_INFO));
  InitSerial();
  print_banner();
  blsm_autosar_init();
}

リファレンス

セルタイプ
celltype tKernel

カーネルの生成を行うコンポーネントです。

attr char_t * name = C_EXP("$cell$")

カーネルの名前を指定します。 指定しない場合、セルの名前が使用されます。

attr char_t * status = "EXTENDED"

エラーコード種別を指定します。 指定しない場合、EXTENDEDが使用されます。

"EXTENDED"

標準エラーと拡張エラーを検出

"STANDARD"

標準エラーのみ検出

attr bool_t StackMonitoring

スタックモニタリング使用の有無を指定します。

True

スタックモニタリングを使用します。

False

スタックモニタリングを使用しません。

attr uint32_t stackSize

C2ISR用スタックとフック用スタックを1つのスタックで確保する場合のスタックサイズを指定します。

attr char_t * ScalabilityClass = "SC1"

OSのスケーラビリティクラスを指定します。 現在はSC1しかサポートしていません。

attr bool_t useGetServiceId

OSErrorGetServiceId()の使用有無を指定します。

True

OSErrorGetServiceId()を使用します。

False

OSErrorGetServiceId()を使用しません。

attr bool_t useParameterAccess

エラーが発生したシステムサービスの引数取得の使用有無を指定します。

True

エラーが発生したシステムサービスの引数取得有効。

False

エラーが発生したシステムサービスの引数取得無効。

シグニチャ
signature sKernelTask

Task用のカーネル本体を呼び出すシグニチャ

StatusType schedule(void)

明示的な再スケジューリングを行う。

void enableAllInterrupts(void)

disableAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す。

void disableAllInterrupts(void)

ターゲットの割込みをすべて禁止し、クリティカルセクションに入る。

void resumeAllInterrupts(void)

suspendAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendAllInterrupts(void)

ターゲットの割込み状態を保存した後、ターゲットの割込みをすべて禁止しクリティカルセクションに入る。

void resumeOsInterrupts(void)

suspendOSInterrupts によって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendOsInterrupts(void)

ターゲットの割込み状態を保存した後、C2ISRをすべて禁止しクリティカルセクションに入る。

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

void shutdownOs([in]StatusType ercd)

すべてのOSサービスを終了する。

signature sKernelISR1

ISR1用のカーネル本体を呼び出すシグニチャ

void enableAllInterrupts(void)

disableAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す.。

void disableAllInterrupts(void)

ターゲットの割込みをすべて禁止し、クリティカルセクションに入る。

void resumeAllInterrupts(void)

suspendAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendAllInterrupts(void)

ターゲットの割込み状態を保存した後、ターゲットの割込みをすべて禁止しクリティカルセクションに入る。

void resumeOsInterrupts(void)

suspendOSInterrupts によって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendOsinterrupts(void)

ターゲットの割込み状態を保存した後、C2ISRをすべて禁止しクリティカルセクションに入る。

signature sKernelISR2

ISR2用のカーネル本体を呼び出すシグニチャ

void enableAllInterrupts(void)

disableAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す.。

void disableAllInterrupts(void)

ターゲットの割込みをすべて禁止し、クリティカルセクションに入る。

void resumeAllInterrupts(void)

suspendAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendAllInterrupts(void)

ターゲットの割込み状態を保存した後、ターゲットの割込みをすべて禁止しクリティカルセクションに入る。

void resumeOsInterrupts(void)

suspendOSInterrupts によって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendOsinterrupts(void)

ターゲットの割込み状態を保存した後、C2ISRをすべて禁止しクリティカルセクションに入る。

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

void shutdownOs([in]StatusType ercd)

すべてのOSサービスを終了する。

signature sKernelErrorHook

カーネル本体を呼び出すシグニチャ(ErrorHook用)

void resumeAllInterrupts(void)

suspendAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendAllInterrupts(void)

ターゲットの割込み状態を保存した後、ターゲットの割込みをすべて禁止しクリティカルセクションに入る。

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

void shutdownOs([in]StatusType ercd)

すべてのOSサービスを終了する。

signature sKernelPreTaskHook

カーネル本体を呼び出すシグニチャ(PreTaskHook用)

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

signature sKernelPostTaskHook

カーネル本体を呼び出すシグニチャ(PostTaskHook用)

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

signature sKernelStartupHook

カーネル本体を呼び出すシグニチャ(StartupHook用)

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

void shutdownOs([in]StatusType ercd)

すべてのOSサービスを終了する。

signature sKernelShutdownHook

カーネル本体を呼び出すシグニチャ(ShutdownHook用)

AppModeType getActiveApplicationMode(void)

OS起動時に指定されたアプリケーションモードを取得する。

signature sKernelAlarmCallback

カーネル本体を呼び出すシグニチャ(AlarmCallback用)

void resumeAllInterrupts(void)

suspendAllInterruptsによって設定された割込み禁止状態を割込み許可状態に戻す。

void suspendAllInterrupts(void)

ターゲットの割込み状態を保存した後、ターゲットの割込みをすべて禁止しクリティカルセクションに入る。

signature snKernel

カーネル起動シグニチャ

void startOs([in]AppModeType mode)

  指定されたアプリケーションモードでOSを起動する。

signature sEventISR2
StatusType set([in]TaskType tskid, [in]EventMaskType mask)

TaskID で指定されたタスクに Mask で指定されたイベントを設定する。

Return

正常終了 (E_OK) またはエラーコード。

StatusType get([in]TaskType tskid, [out]EventMaskRefType p_mask)

TaskID で指定されたタスクが保持しているイベントマスク値を取得する。

Return

正常終了 (E_OK) またはエラーコード。

signature sEventHook
StatusType get([in]TaskType tskid, [out]EventMaskRefType p_mask)

TaskID で指定されたタスクが保持しているイベントマスク値を取得する。

Return

正常終了 (E_OK) またはエラーコード。

タスク ― tTask

タスクはプログラムの並行実行の単位です。

課題

to be filled in

使用方法

タスクの生成

アプリケーション開発者は tTask セルタイプのセルを生成することにより、タスクを生成することができます。次の例では MyTask という名前のタスクセルを生成し、 MyCelleTaskBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
    entry sTaskBody eTaskBody;
};

cell tMyCellType MyCell {};

cell tTask MyTask {
    stackSize = 1024;
    priority = 42;

    cTaskBody = MyCell.eTaskBody;
};
tMyCellType.c
void eTaskBody_main(CELLIDX idx)
{
    CELLCB  *p_cellcb = GET_CELLCB(idx);
    // ...
}
タスクの制御

tTask が提供する eTask という名前の受け口を利用することにより、タスクの制御及び状態の取得を行うことができます。

app.cdl
cell tMyCellType MyCell {};

cell tMyAnotherCellType MyAnotherCell {
    cTask = MyTask.eTask;
};
tMyAnotherCellType.c
// タスクの起動
cTask_activate();

// タスクの現在状態の参照
TaskRefType taskStatus;
cTask_getState(&taskStatus);

リファレンス

セルタイプ
celltype tTask

タスクの生成、制御及び状態の取得を行うコンポーネントです。

attr TaskType idx = C_EXP("$cell$")

タスクのIDの識別子を指定します。

指定しない場合、 セルの名前が使用されます。

attr bool_t autoStart

タスクを自動起動させるか指定します。

True

タスクを自動起動します。

False

タスクを自動起動しません。

attr char_t * appMode []

タスクの自動起動を設定した場合、appMode[]で指定したappModeでタスクを自動起動させる(複数選択可能)。

attr uint32_t priority

タスクの起動時優先度を指定します。

attr uint32_t activation

タスクの最大起動要求回数を指定します。

attr char_t * schedule

タスクのスケジューリングポリシを指定します。

Full

フルプリエンプティブスケジューリング

Non

ノンプリエンプティブスケジューリング

attr char_t * event []

タスクの持つイベントを指定します(複数指定可能)。

attr char_t * resource []

タスクが獲得するリソースを指定します(複数選択可能)。

attr uint32_t stackSize

タスク用のスタックサイズを指定します。

entry sTask  eTask

タスクの制御及び状態の取得を行うための受け口です。

call sTaskBody  cBody

タスクの本体として呼び出される受け口をこの呼び口に結合します。

entry sTaskISR2  eTaskISR2
entry sTaskHook  eTaskHook
entry sTaskEvent  eTaskEvent
シグニチャ
signature sTask

タスクの制御、及び状態の取得を行うためのシグニチャです。

StatusType activate(void)

タスクに対して起動要求を行います。 この関数は ActivateTask(TalskType TaskID) のラッパーです。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType terminate(void)

タスクを終了します。 この関数は TermmateTask(void) のラッパーです。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType chain(void)

自タスクを終了し、指定したタスクを起動します。 todo この関数は ChainTask(TaskType TaskID) のラッパーです。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType getId([out]TaskRefType p_tskid)

実行中のタスクIDを取得します。 結果はp_tskidに格納されます。 :return: 正常終了 (E_OK) またはエラーコード。 この関数は GetTasklD(TaskRefType TasklD) のラッパーです。

StatusType getState([out]TaskStateRefType p_state)

タスクの状態を取得します。 結果はp_stateに格納されます。 :return: 正常終了 (E_OK) またはエラーコード。 この関数は GetTaskState(TaskType TaskID,TaskStateRefType State) のラッパーです。

signature sTaskISR2

タスクを操作するためのシグニチャISR2用

StatusType activate(void)

タスクに対して起動要求を行います。 この関数は ActivateTask(TalskType TaskID) のラッパーです。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType getId(out] TaskRefType p_tskid)

実行中のタスクIDを取得します。 結果はp_tskidに格納されます。 :return: 正常終了 (E_OK) またはエラーコード。 この関数は GetTasklD(TaskRefType TasklD) のラッパーです。

StatusType getState([out]TaskStateRefType p_state)

タスクの状態を取得します。 結果はp_stateに格納されます。 :return: 正常終了 (E_OK) またはエラーコード。 この関数は GetTaskState(TaskType TaskID,TaskStateRefType State) のラッパーです。

signature sTaskHook

タスクを操作するためのシグニチャ各Hook用

StatusType getId(out] TaskRefType p_tskid)

実行中のタスクIDを取得します。 結果はp_tskidに格納されます。 :return: 正常終了 (E_OK) またはエラーコード。 この関数は GetTasklD(TaskRefType TasklD) のラッパーです。

StatusType getState([out]TaskStateRefType p_state)

タスクの状態を取得します。 結果はp_stateに格納されます。 :return: 正常終了 (E_OK) またはエラーコード。 この関数は GetTaskState(TaskType TaskID,TaskStateRefType State) のラッパーです。

signature sEventTask

イベントを操作するためのシグニチャ(Task用)

StatusType set([in]EventMaskType mask)

TaskID で指定されたタスクに Mask で指定されたイベントを設定する。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType clear([in]EventMaskType mask)

Mask で指定されたイベントをクリアする。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType get([out]EventMaskRefType p_mask)

TaskID で指定されたタスクが保持しているイベントマスク値を取得する。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType wait([in]EventMaskType mask)

本関数を呼び出したタスクを待ち状態とする。 :return: 正常終了 (E_OK) またはエラーコード。

signature sTaskEvent

イベントを操作するためのシグニチャTask用

StatusType set([in]TaskType tskid, [in]EventMaskType mask)

TaskID で指定されたタスクに Mask で指定されたイベントを設定する。 :return: 正常終了 (E_OK) またはエラーコード。

StatusType get([in]TaskType tskid, [out]EventMaskRefType p_mask)

TaskID で指定されたタスクが保持しているイベントマスク値を取得する。 :return: 正常終了 (E_OK) またはエラーコード。

割込み管理 -tISR

割込みサービスルーチン(割込み処理関数)を登録して、割込み発生時に呼び出す機能です。

課題

to be filled in

使用方法

割込みの生成

アプリケーション開発者は tISR セルタイプのセルを生成することにより、割込みを生成することができます。次の例では MyISR という名前の割込みセルを生成し、 MyCelleISRBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
    entry sHandlerBody eISRBody;
};

cell tMyCellType MyCell {};

cell tISR MyISR {
    cBody = MyCell.eISRBody;
    category = 2;
    priority = 15;
    entryNumber = 48;
    interruptsource ="ENABLE";
};
tMyCellType.c
void eISRBody_main(CELLIDX idx)
{
}

リファレンス

セルタイプ
celltype tISR

割込みの生成を行うコンポーネントです。

attr char_t * name = C_EXP("$cell$")

割込みの名前を指定します。 指定しない場合、セルの名前が使用されます。

attr uint32_t category

割込みのカテゴリを指定します。

1

カテゴリ1ISR(C11SR) OSのコードを経由せずに高速に呼び出される 割込み制御関連以外のOSのシステムサービスを呼び出せない C11SRは,C21SRよりも割込み優先度が高い

2

カテゴリ2ISR(C21SR) OSのコードを経由して呼び出される OSのサービスを呼び出せる

attr uint32_t priority

割込みの優先度を指定します。

attr uint32_t entryNumber

割込み番号を指定します。

attr char_t * interruptsource

割込み要因の初期状態を指定します。 SC3、SC4のみで使用可能です。 categoryに1を指定した場合に、本パラメータにDISABLEを指定した場合、ジェネレータはエラーを検出します。 SC3、SC4で本パラメータを省略した場合、ジェネレータはエラーを検出します。

ENABLE

有効

DISABLE

無効

attr char_t * resource

割込みが獲得するリソースを選択します(複数選択可能)。

シグニチャ
signature sHandlerBody

割込みハンドラを呼び出すためのシグニチャです。

void main(void)

カウンタ ― tCounter

カウンタは処理タイミング通知用のオブジェクトです。 ティックという単位で事象をカウントします。 カウンタは2種類あります。 ソフトウェアカウンタ

システムサービスでティックをインクリメントする

ハードウェアカウンタ

ハードウェア(タイマなど)がティックをインクリメントする

主にアラーム、スケジュールテーブルに接続して使用する。 .. todo:

to be filled in

使用方法

カウンタの生成

アプリケーション開発者は tCounter セルタイプのセルを生成することにより、カウンタを生成することができます。次の例では MyCounter という名前のカウンタセルを生成します。

app.cdl
cell tCounter MyCounter {
    *counterType = "SOFTWARE"
    minimumCycle = 10;
    maximumAllowedValue = "100";
};
tMyCellType.c
void eAlarmHandlerBody_main()
{
}

リファレンス

セルタイプ
celltype tCouter

カウンタの生成を行うココンポーネントです。

attr uint8_t id = C_EXP("$ID$")

カウンタのIDの識別子を指定します。

attr char_t * name = C_EXP("$cell$")

カウンタの名前を指定します。 指定しない場合、セルの名前が使用されます。

attr char_t   * counterType = "SOFTWARE"
カウンタのタイプを指定します。
HARDWARE

ハードウェアカウンタ

SOFTWARE

ソフトウェアカウンタ

attr uint32_t minimumCycle

接続されたアラームがカウンタに指定できる最小周期値を指定します。

attr uint32_t maximumAllowedValue

カウンタのティックの最大値を指定します。

シグニチャ
signature sCounter

カウンタを操作するためのシグニチャ

StatusType signal(void)

アラーム ― tAlarm

アラームは繰り返し処理用のオブジェクトです。 アラームはカウンタに接続して、カウンタの起動によって動作します。

課題

to be filled in

使用方法

アラームの生成

アプリケーション開発者は tAlarm セルタイプのセルを生成することにより、アラームを生成することができます。次の例では MyAlarm という名前のアラームセルを生成し、 MyCelleAlarmHandlerBody をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
    entry sHandlerBody eAlarmHandlerBody;
};

cell tMyCellType MyCell {};

cell tAlarm MyAlarm {
    alarmTime = 10;
    cycleTime = 10;
    cBody = MyCell.eAlarmHandlerBody;
};
tMyCellType.c
void eAlarmHandlerBody_main()
{
}

リファレンス

セルタイプ
celltype tAlarm

アラームの生成を行うココンポーネントです。

attr char_t * name = C_EXP("$cell$")

アラームの名前を指定します。 指定しない場合、セルの名前が使用されます。

attr uint8_t id = C_EXP("$ID$")

アラームのIDを指定します。

attr char_t * counter

アラームに接続するカウンタを指定します。

attr char_t * action

アラームアクションを指定します。

SETEVENT

イベントのセット。

ACTIVATETASK

タスクの起動。

ALARMCALLBACK

コールバックの呼び出し。

attr char_t * task = "OMISSIBLE"

アラームのアクションで起動するタスクを指定します。

attr char_t * event = "OMISSIBLE"

アラームのアクションでセットするイベントを指定します。

attr char_t * callbackName = "OMISSIBLE"

アラームのアクションで呼び出すコールバックを指定します。

attr bool_t autoStart

アラームの自動起動設定。

True

自動起動する。

False

自動起動しない。

attr uint32_t alarmTime = 0

アラーム自動起動時の初回満了時刻を指定します。

attr uint32_t cycleTime = 0

アラーム自動起動時の周期時間を指定します。0の場合は単発アラームとなります。

attr char_t * appMode [] = { "OMISSIBLE" }

自動起動するアプリケーションモードを指定します。

シグニチャ
signature sAlarm

アラームを操作するためのシグニチャ(Task,ISR2用)。

StatusType getBase([out]AlarmBaseRefType p_info)

アラームの情報を取得する。 アラーム情報は p_info で示す構造体(AlarmBaseRefType)に格納される。

StatusType setRelative([in]TickType incr, [in]TickType cycle)

アラームが現在のティックから incr で指定された相対時刻が経過した後に満了するよう設定する。 初回の満了後、cycle が 0 でない場合は、cycle の周期でアラームを満了させる。

StatusType setAbsolute([in]TickType start, [in]TickType cycle)

アラームが start で指定された絶対時刻に達した際に満了するよう設定する。 初回の満了後、cycle が 0 でない場合は cycle の周期でアラームを満了させる。

signature sAlarmHook

アラームを操作するためのシグニチャ(Hook用)。

StatusType getBase([out]AlarmBaseRefType p_info)

アラームの情報を取得する。 アラーム情報は p_info で示す構造体(AlarmBaseRefType)に格納される。

リソース ― tResource

課題

to be filled in

使用方法

リソースの生成

アプリケーション開発者は tResource セルタイプのセルを生成することにより、リソースを生成することができます。次の例では MyResource という名前のリソースセルを生成し、 MyCellcResource をメインルーチンとして結合しています。

app.cdl
celltype tMyCellType {
    call sResource cResource;
};

cell tMyCellType MyCell {};

cell tTask MyResource {
    property = "STANDARD";
    linkedResource = "OMISSIBLE";

    eResource = MyCell.cResource;
};
tMyCellType.c

リファレンス

セルタイプ
celltype tResource

リソースの生成を行うコンポーネントです。

attr int8_t id = C_EXP("$ID$")

リソースのIDの識別子を指定します。

attr char_t * name = "$cell$"

リソースの名前を指定します。

attr char_t * property

リソースの種類を指定します。

STANDARD

標準リソース

INTERNAL

内部リソース

LINKED

リンクリソース

attr char_t * linkedResource

リンクリソースにおけるリンク先リソースを指定します。

シグニチャ
signature sResource

リソースを操作するためのシグニチャ。

StatusType get(void)

リソースを獲得する。

StatusType release(void)

リソースを開放する。

mruby on ev3rt+tecs

以下からダウンロード可能です.

mruby-on-ev3rt+tecs

課題

to be filled in

目次:

mruby on ev3rt+tecs について

課題

to be filled in

バッテリ - Battery

バッテリに関するAPIです.

特異メソッド一覧

特異メソッド

Battery.mA -> Fixnum

バッテリの電流を取得する.

戻り値

バッテリの電流 (mA)


Battery.mV -> Fixnum

バッテリの電圧を取得する.

戻り値

バッテリの電圧 (mV)


battery_sample.rb

ボタン - Battery

ボタンに関するAPIです.

特異メソッド一覧

シンボル

  • button

    ボタンを表わすシンボル

    シンボル

    :left

    左ボタン

    :right

    右ボタン

    :up

    上ボタン

    :down

    下ボタン

    :enter

    中央ボタン

    :back

    戻るボタン

特異メソッド

Button[ button ].pressed? -> bool

ボタンの押下状態を取得する. 不正のボタン番号を指定した場合,常に false を返す (エラーログが出力される).

引数

なし

戻り値

true 押されている状態

false 押されていない状態


button_sample.rb

LEDライト - LED

LEDライトに関するAPIです.

特異メソッド一覧

シンボル

  • clr

    設定できるLEDライトのカラーを表わすシンボル

    シンボル

    :off

    オフにする

    :red

    :green

    :orange

    オレンジ

特異メソッド

LED.color = ( clr ) -> nil

LEDライトのカラーを設定する. 不正の設定値を指定した場合,LEDライトのカラーを変えない.

引数

clr LEDカラーの設定値 (シンボル)

戻り値

nil


LED.off -> nil

LEDをオフにする.

引数

なし

戻り値

nil


led_sample.rb

スピーカ - Speaker

音声 (スピーカ) に関するAPIです.

シンボル

  • frequency

    設定できる周波数のシンボル

    シンボル

    :c4

    ノートC4の周波数 (261.63)

    :cs4

    ノート#C4の周波数 (277.18)

    :d4

    ノートD4の周波数 (293.66)

    :ds4

    ノートD#4の周波数 (311.13)

    :e4

    ノートE4の周波数 (329.63)

    :f4

    ノートF4の周波数 (349.23)

    :fs4

    ノートF#4の周波数 (369.99)

    :g4

    ノートG4の周波数 (392.00)

    :gs4

    ノートG#4の周波数 (415.30)

    :a4

    ノートA4の周波数 (440.00)

    :as4

    ノートA#4の周波数 (466.16)

    :b4

    ノートB4の周波数 (493.88)

    :c5

    ノートC5の周波数 (523.25)

    :cs5

    ノートC#5の周波数 (554.37)

    :d5

    ノートD5の周波数 (587.33)

    :ds5

    ノートD#5の周波数 (622.25)

    :e5

    ノートE5の周波数 (659.25)

    :f5

    ノートF5の周波数 (698.46)

    :fs5

    ノートF#5の周波数 (739.9)

    :g5

    ノートG5の周波数 (783.99)

    :gs5

    ノートG#5の周波数 (830.61)

    :a5

    ノートA5の周波数 (880.00)

    :as5

    ノートA#5の周波数 (932.33)

    :b5

    ノートB5の周波数 (987.77)

    :c6

    ノートC6の周波数 (1046.50)

    :cs6

    ノートC#6の周波数 (1108.73)

    :d6

    ノートD6の周波数 (1174.66)

    :ds6

    ノートD#6の周波数 (1244.51)

    :e6

    ノートE6の周波数 (1318.51)

    :f6

    ノートF6の周波数 (1396.91)

    :fs6

    ノートF#6の周波数 (1479.98)

    :g6

    ノートG6の周波数 (1567.98)

    :gs6

    ノートG#6の周波数 (1661.22)

    :a6

    ノートA6の周波数 (1760.00)

    :as6

    ノートA#6の周波数 (1864.66)

    :b6

    ノートB6の周波数 (1975.53)

特異メソッド

Speaker.volume = ( vol ) -> nil

音量を調整する.

引数

vol ボリュームの値.範囲:0から+100.0はミュート.+100を超えた値を指定すると,実際の値は+100になる.小数点以下切り捨て

戻り値

nil


Speaker.tone ( frequency, duration ) -> nil

指定した周波数でトーン出力する. 今再生しているサウンドは停止される.

引数

frequency トーンの周波数.シンボルから選択.

duration 出力持続時間.単位はミリ秒.小数点以下切り捨て

戻り値

nil


speaker_sample.rb

LCD - LCD

LCDに関するAPIです. コンソールの幅は0~178,高さは0~128 (範囲外の数値も指定可能だが、コンソールには表示されない).

シンボル

  • color

    LCDカラーを表すシンボル

    シンボル

    :white

    :black

  • fnt

    フォントサイズを表わすシンボル

    シンボル

    :small

    小さいサイズのフォント

    :medium

    普通サイズのフォント

特異メソッド

LCD.font = ( fnt ) -> nil

デフォルトのフォントを設定する.

引数

fnt フォントサイズのシンボル

戻り値

nil


LCD.draw ( str, x, y ) -> nil

指定位置で文字列を描く.

引数

str 文字列

x 左上隅の水平方向の位置 (横方向にフォントサイズ*x文字分ずらした位置,小数点以下切り捨て)

y 左上隅の垂直方向の位置 (横方向にフォントサイズ*y文字分ずらした位置,小数点以下切り捨て)

戻り値

nil


LCD.fill_rect ( x, y, w, h, color ) -> nil

矩形を描いて色を塗る.

引数

x 左上隅の水平方向の位置 (小数点以下切り捨て)

y 左上隅の垂直方向の位置 (小数点以下切り捨て)

w 矩形の幅 (小数点以下切り捨て)

h 矩形の高さ (小数点以下切り捨て)

カラーセンサ - Color カラーのシンボル

戻り値

nil


LCD.draw_line ( x0, y0, x1, y1 ) -> nil

指定座標で線を引く.

引数

x0 始点の水平方向の位置 (小数点以下切り捨て)

y0 始点の垂直方向の位置 (小数点以下切り捨て)

x1 終点の水平方向の位置 (小数点以下切り捨て)

y1 終点の垂直方向の位置 (小数点以下切り捨て)

戻り値

nil


LCD.show_message_box ( title, msg ) -> nil

メッセージボックスにメッセージを表示する. ※メッセージボックスを表示中なmrubyのプログラムを一時停止し,中央(Enter)ボタンを押して再開する.

引数

title メッセージボックスのタイトル

msg メッセージ

戻り値

nil


LCD.error_puts ( msg ) -> nil

メッセージボックスにエラーを出力する.

引数

msg エラーメッセージ

戻り値

nil


LCD.print ( str ) -> nil

LCDコンソールに文字列を表示する(改行なし).

引数

str 文字列

戻り値

nil


LCD.puts ( str ) -> nil

LCDコンソールに文字列を表示する(改行あり).

引数

str 文字列

戻り値

nil


lcd_sample.rb

モータ - Motor

モータを制御するためのAPIです.

シンボル

  • port

    モータポートを表すシンボル

    シンボル

    :port_a

    ポートA

    :port_b

    ポートB

    :port_c

    ポートC

    :port_d

    ポートD

  • type

    サポートするモータタイプのシンボル

    シンボル

    :large

    サーボモータ L

    :medium

    サーボモータ M

インスタンスメソッド

initialize( port, type=:large ) -> object

モータポートを設定する.

モータポートに接続しているモータのタイプを設定する.既に設定した場合も新しいモータタイプを指定できる.

引数

port モータポート番号(シンボル)

type モータタイプ (シンボル)

戻り値

nil


type -> Symbol

モータポートのモータタイプを取得する.

引数

なし

戻り値

:large サーボモータL

:medium サーボモータM


power = ( pwm ) -> nil

モータのパワーを設定し,モータが回転する.

引数

pwm モータのフルパワーのパーセント値.範囲:-100から+100.マイナスの値でモータを逆方向に回転させることができる.範囲外の場合±100が適用される.

戻り値

nil


power -> Fixnum

モータのパワーを取得する.

引数

なし

戻り値

モータのパワー


stop( brake=true ) -> nil

モータを停止する.

引数

brake ブレーキモードの指定.true (ブレーキモード), false (フロートモード)

戻り値

nil


rotate( deg, spd, blk=false ) -> nil

モータを指定した角度だけ回転させる

引数

deg 回転角度,マイナスの値でモータを逆方向に回転させることができる(小数点以下切り捨て)

spd 回転速度,モータポートのフルスピードのパーセント値.範囲:-100から+100(小数点以下切り捨て).マイナスの場合回転が逆になる.範囲外の場合±100として扱われる.

blk モード指定.true (関数は回転が完了してからリターン),false (関数は回転操作を待たずにリターン)

戻り値

nil 正常終了


count -> Fixnum

モータの角位置を取得する.

引数

なし

戻り値

モータの角位置(単位は度),マイナスの値は逆方向に回転されたことを指す.


reset_count -> nil

モータの角位置をゼロにリセットする.

モータの角位置センサの値を設定するだけ,モータの実際のパワーと位置に影響を与えない.

引数

なし

戻り値

nil


motor_sample.rb
include EV3RT_TECS
begin
  LCD.font=:medium
  LCD.draw("motor sample", 0, 0)
  # Sensors and Actuators
  left_port= :port_a
  right_port= :port_b
  ultrasonic_port= :port_3
  LCD.draw("left motor:#{left_port} ", 0, 2)
  LCD.draw("right motor:#{right_port} ", 0, 3)
  LCD.draw("ultrasonic :#{ultrasonic_port}", 0, 4)
  $left_motor= Motor.new(left_port)
  $right_motor= Motor.new(right_port)
  $ultrasonic_sensor= UltrasonicSensor.new(ultrasonic_port)include EV3RT_TECS
  loop{
    distance= $ultrasonic_sensor.distance
    LCD.draw("distance = #{distance} ", 0, 6)
    if distance < 15 then
      $left_motor.stop
      $right_motor.stop
    else
      $left_motor.power=30
      $right_motor.power=30
    end
  }
rescue=> e
  LCD.error_putse
end

RTOS機能 - RTOS

RTOS機能に関するAPIです.

特異メソッド一覧

特異メソッド

RTOS.delay ( msec ) -> nil

指定された時間遅延する (指定された時間後に実行が再開される).

引数

msec 遅延時間 (ミリ秒)

戻り値

nil


RTOS.usec -> Fixnum

性能評価用システム時刻の参照.

引数

なし

戻り値

性能評価用システム時刻の現在値 (マイクロ秒)


RTOS.msec-> Fixnum

システム時刻の参照.

引数

なし

戻り値

システム時刻の現在値 (ミリ秒)


rtos_sample.rb

カラーセンサ - Color

カラーセンサに関するAPIです.

インスタンスメソッド一覧

シンボル

  • color

    カラーセンサで識別できるカラーのシンボル

    シンボル

    :black

    :blue

    :green

    :yellow

    :red

    :white

    :brown

    :none

    識別できなかった

  • port

    センサポートを表わすシンボル

    シンボル

    :port_1

    ポート 1

    :port_2

    ポート 2

    :port_3

    ポート 3

    :port_4

    ポート 4

インスタンスメソッド

initialize ( port ) -> object

カラーセンサポートを設定する.

引数

port センサポートのシンボル

戻り値

nil


color -> Symbol

カラーセンサでカラーを識別する.

引数

なし

戻り値

識別したカラーのシンボルを返す.


reflect -> nil

カラーセンサで反射光の強さを測定する.

引数

なし

戻り値

反射光の強さ(0〜100)


ambient -> Fixnum

カラーセンサで環境光の強さを測定する.

引数

なし

戻り値

環境光の強さ(0〜100)


rgb -> Fixnum

カラーセンサでRGB値を測定する.

引数

なし

戻り値

レッド(R)値,グリーン(G)値,ブルー(B)値


color_sample.rb

ジャイロセンサ - Gyro

ジャイロセンサに関するAPIです.

インスタンスメソッド一覧

シンボル

  • port

    センサポートを表わすシンボル

    シンボル

    :port_1

    ポート 1

    :port_2

    ポート 2

    :port_3

    ポート 3

    :port_4

    ポート 4

インスタンスメソッド

initialize ( port ) -> object

ジャイロセンサポートを設定する.

引数

port センサポートのシンボル

戻り値

nil


angle -> Fixnum

ジャイロセンサで角位置を測定する.

引数

なし

戻り値

角位置 (単位は度)


rate -> Fixnum

ジャイロセンサで角速度を測定する.

引数

なし

戻り値

角位置 (単位は度/秒)


reset -> nil

ジャイロセンサの角位置をゼロにリセットする.

引数

なし

戻り値

nil


calibrate ( n=200 ) -> Float | Symbol

ジャイロセンサのキャリブレーション. 複数回測定した値の平均値

引数

n 測定回数:デフォルトは200(小数点以下切り捨て)

戻り値

offset 測定回数の平均値

:E_OBJ 測定値の最大・最小の値が5以上の場合


gyro_sample.rb

超音波センサ - Ultrasonic

超音波センサに関するAPIです.

インスタンスメソッド一覧

シンボル

  • port

    センサポートを表わすシンボル

    シンボル

    :port_1

    ポート 1

    :port_2

    ポート 2

    :port_3

    ポート 3

    :port_4

    ポート 4

インスタンスメソッド

initialize ( port ) -> object

超音波センサポートを設定する.

引数

port センサポートのシンボル

戻り値

nil


distance -> Fixnum

超音波センサで距離を測定する.

引数

なし

戻り値

距離 (単位はセンチ)


listen-> bool

超音波センサで超音波信号を検出する.

引数

なし

戻り値

true 超音波信号を検出した

false 超音波信号を検出しなかった


ultrasonic_sample.rb

タッチセンサ - Touch

タッチセンサに関するAPIです.

インスタンスメソッド一覧

シンボル

  • port

    センサポートを表わすシンボル

    シンボル

    :port_1

    ポート 1

    :port_2

    ポート 2

    :port_3

    ポート 3

    :port_4

    ポート 4

インスタンスメソッド

initialize ( port ) -> object

タッチセンサポートを設定する.

引数

port センサポートのシンボル

戻り値

nil


pressed? -> bool

タッチセンサの状態を検出する.

引数

なし

戻り値

true 押されている状態

false 押されていない状態


touch_sample.rb

共有変数 - SharedMemory

各VM間で共有変数を扱うAPIです.

インスタンスメソッド一覧

インスタンスメソッド

putVal ( index, val ) -> nil

共有変数に値を入力する

引数

index 共有変数のインデックス

val  値

戻り値

nil

a[index] = val でも可


getVal ( index ) -> Fixnum

共有変数の値を出力する

引数

index 共有変数のインデックス

戻り値

共有変数の値

b = a[index] でも可


sharedmemory_sample.rb

バランサ - Balancer

バランス制御に関するAPIです.

特異メソッド一覧

特異メソッド

Balancer.control(forward,turn,gyrosensor,gyro_offset,angle_l,angle_r,batteryvoltage) -> [Int]

左右モータPWM出力値を取得する.

引数

forward 前進/後退命令。100(前進最大値)~-100(後進最大値)

turn 旋回命令。100(右旋回最大値)~-100(左旋回最大値)

gyrosensor ジャイロセンサ値

gyro_offset ジャイロセンサオフセット値

angle_l 左モータエンコーダ値

angle_r 右モータエンコーダ値

batteryvoltage バッテリ電圧値(mV)

backlashhalf バックラッシュの半分の値(rd)。0であればバックラッシュキャンセル処理を行わない

戻り値
  1. 左モータPWM出力値

  2. 右モータPWM出力値


ev3way_sample.rb

mruby on GR-PEACH+TECS

mruby on GR-PEACH+TECS は,組込み向けスクリプト言語 mruby をルネサス社製マイコンボード GR-PEACH 上で動作させることができる開発プラットフォームです.

本フレームワークは,TECS(TOPPERS Embedded Component System)を使用しているため,コンポーネントベース開発が可能です.

mrubyの各VMには,TOPPERS/ASP3カーネルのタスクを割り当てており,マルチVM機能をサポートしています. また,mrubyメソッド p, puts, print は,シリアル出力されます.

課題

to be filled in

目次:

ビルド方法

  1. 準備 (環境構築):

    以下のものをインストールしてください.

    • Cygwin
      • Ruby

      • GNU Make

      • bison

    • GNUARM-NONE v16.01 Windows Toolchain (ELF)
      • クロスコンパイラ

      • PATHを通しておいてください.(arm-none-eabi-gcc等が実行できる状態)

    • (ターミナルソフトウェア)
      • シリアル経由で文字を出力する場合に使用します.

      • Tera Term等をインストールしてください.

    Note: Mac や Linux でも開発可能と思いますが,まだ動作確認できていません.

  2. パッケージのダウンロード:

    以下のURLから,mruby-on-gr-peach-tecs-package をダウンロードしてください.

    または,Githubからもダウンロード可能です.

    $ git clone https://github.com/robotan0921/mruby_on_GR-PEACH-TECS.git
    
  3. mrubyのビルド

    パッケージをダウンロードしたら,まず mruby のビルドを行います. mruby-1.3.0 のディレクトリに移動し,ビルドしてください.

    $ cd mruby-1.3.0
    $ make
    
  4. アプリ・プラットフォームのビルド:

    次に,アプリケーションを含むプラットフォーム部分のビルドを行います. asp3/workspace/build へ移動し,ビルドしてください.

    $ cd ../asp3/workspace/build    (mruby-1.3.0からの相対ディレクトリ)
    $ make
    

    アプリケーションは,デフォルトで led_sample.rb が指定されています.

  5. バイナリのコピー・起動:

    ビルドが終わると, asp3/workspace/build の中に asp.bin というバイナリが出来上がります. このバイナリを GR-PEACH にコピーします. (PCとGR-PEACHをUSBケーブルで接続すると, MBED というドライブが立ち上がります) エクスプローラーを開いてドラッグ&ドロップしてください. Cygwin上のコマンドでコピーする場合は,以下のコマンドを叩いてください.

    $ cp asp.bin /cygdrive/d/               (自環境でのMBEDドライブ名を指定してください)
    

アプリケーションの開発方法

ここでは, mruby アプリケーションの開発方法について説明します. 開発環境やビルド方法については,ビルド方法 を参照してください.

サンプルアプリケーション

asp3/workspace/mruby_app に mruby のサンプルプログラムが入っています. 基本的に,このディレクトリでプログラムを書いていきます.

デフォルトは,led_sample.rb となっています.

アプリケーションファイルの指定

mruby on GR-PEACH+TECS では,アプリケーションファイルの指定をCDLというファイルによってコンフィグレーションを行います. TECS CDL については,TECS コンポーネント記述言語 (TECS CDL) を参照してください.

asp3/workspace/build の VM1.cdl にてアプリケーションを指定しています. アプリケーションを変更する場合は,$(MRUBY_APP_DIR)/led_sample.rb の行を,任意のアプリケーション名に修正し, make を実行してください.

例えば, $(MRUBY_APP_DIR)/rtos_sample.rb とすると,rtos_sample.rb が実行されます.

VM1.cdl
      import(<bridge.cdl>);

      cell nMruby::tMruby Mruby {
              mrubyFile =
                      "$(MRUBY_LIB_DIR)/RTOS.rb "
                      "$(MRUBY_LIB_DIR)/LED.rb "
                      "$(MRUBY_APP_DIR)/led_sample.rb";       <---(アプリケーションの指定)

              cInit = VM_TECSInitializer.eInitialize;
              cSerialPort = SerialPort1.eSerialPort;
      };

      cell tTask MrubyTask1 {
              cTaskBody = Mruby.eMrubyBody;
              attribute = C_EXP("TA_ACT");
              priority  = 10;
              stackSize = 4096;
      };

RTOS機能 - RTOS

RTOS機能に関するAPIです.

特異メソッド一覧

特異メソッド


RTOS.delay ( msec ) -> nil

指定された時間遅延する (指定された時間後に実行が再開される).

引数

msec : 遅延時間 (ミリ秒)

戻り値

nil


RTOS.usec -> Fixnum

性能評価用システム時刻の参照.

引数

なし

戻り値

性能評価用システム時刻の現在値 (マイクロ秒)


RTOS.msec-> Fixnum

システム時刻の参照.

引数

なし

戻り値

システム時刻の現在値 (ミリ秒)


rtos_sample.rb

LED - LED

LEDに関するAPIです.

特異メソッド一覧

シンボル

  • clr

    設定できるLEDライトのカラーを表わすシンボル

    シンボル

    :user

    :red

    :green

    :blue

特異メソッド


LED.color = ( clr ) -> nil

LEDライトのカラーを設定する. 不正の設定値を指定した場合,LEDライトのカラーを変えない.

引数

clr : LEDカラーの設定値 (シンボル)

戻り値

nil


LED.off -> nil

LEDをオフにする.

引数

なし

戻り値

nil


led_sample.rb

TINET+TECS

TINET+TECSは,「TINET」をTECSでコンポーネント化した組込み向けTCP/IPプロトコルスタックです. コンポーネント化することで,TINETのコンフィグラビリティを向上させています.

TINET+TECSは,TCP/IPプロトコルの各層をコンポーネント化しており,コンポーネントをそれぞれ結合することでコンフィグレーションを行なっています.

課題

開発中(未リリース)

目次:

TLSF+TECS

TLSF+TECSは,「TLSF」をTECSでコンポーネント化した動的メモリアロケータです.

TLSFコンポーネントは,内部変数として独自のヒープ領域を保持しているため,タスク毎に独立してメモリ管理を行えます.

ただし,複数のタスクで同時に同じTLSFコンポーネントを使用する場合は,排他制御が必要です.

使用例:

mrubyのマルチVM機能 ( mruby-on-ev3rt+tecs-package-beta2.0.1 ~)

リンク:

TLSF (Two-Level Segregate Fit) -Memory Allocator for Real-Time-

課題

to be filled in

目次:

プラグインリファレンスマニュアル

各種カーネル対応プラグイン

  • ATK1Plugin プラグインリファレンス (to be written)

  • HRP2Pugin プラグインリファレンス (to be written)

  • ASP3 (NotifierPlugin) プラグインリファレンス (to be written)

mruby ブリッジプラグイン

トレースプラグイン

  • TracePlugin プラグインリファレンス (to be written)

  • TLVTracePlugin プラグインリファレンス (to be written)

RPC プラグイン

  • TransparentRPcPlugin プラグインリファレンス (to be written)

  • OpaqueRPcPlugin プラグインリファレンス (to be written)

  • SharedRPCPlugin プラグインリファレンス (to be written)

  • SharedOpaqueRPcPlugin プラグインリファレンス (to be written)

C 言語インタフェースプラグイン

  • C2TECSPugin リファレンス (to be written)

  • TECS2CPugin リファレンス (to be written)

参考リンク