HOME > サポート > FAQ-ZIPC > 手法編
サポート
FAQ - ZIPC
  手法編
Q1 STM のセルで、/(無視)やX(不可)を設定した場合、/やXに処理が移行した時にある決まった処理を行うことは可能ですか?
A1 可能です。
具体的には、ZIPCのメニュー[プロジェクト]-[プロジェクト設定]-[Cコード生成設定]の[STM設定]ページにて、STM一覧からSTMを選択し、[無視、不可セル関数コール]の設定をします。
無視又は不可の関数コールを設定すると、無視や不可を処理するときに、設定した関数がコールされます。
例)
v 無視関数コール書式 ign_func() //チェックをし、関数コール書式を設定
上記のように設定した場合、無視コール時にign_func関数がコールされます。
不可も同様に設定します。
無視関数と不可関数を同じ関数でコールする場合には無視or不可の設定をした後無視不可共通関数コールをチェックします。
Q2 STM 中で下記のような記述をした場合は状態遷移先番号の状態に移行するのでしょうか?
A2 このような場合には、実際の遷移先は、2 となります。
これは、アクションセルの処理が終わった後、トランジションセルの処理が行われ、そこで遷移先が 2 に書き換わるためです。
Q3 STM の階層化をする場合、レベル番号はどのように付ければよいのでしょうか?
A3 STMのレベル番号は親子関係を指定するものになります。
親子関係のSTMの場合、子のレベル番号は親の "番号.x" と付けます。
  例)
         親STM       子STM      孫STM
         □0  ─┬─ □0.1 ── □0.1.1
                └─ □0.2
親子関係のSTMにするためにはルールがあります。
STM書式設定の内容で
(1) STM種別が一致している
(2)リターン型が一致している
(3)クローン数が一致している
(4)引数が一致している
という条件の場合に親子関係にすることができます。
親子関係のSTMでは生成コードが共通にまとめられます。

上記の条件に当てはまらない場合にはレベル番号の整数部分を新規に割り当てます(それぞれに親子STMを作成することは可能です)。
  例)
    親STM  子STM
    □0 ── □0.1   E型通常STM リターン型(void)

    □1 ── □1.1   E型通常STM リターン型(int)

    △2 ── △2.1   E型通常サブルーチン
この場合、生成コードはそれぞれ別ファイルとなりますが、異なる型のSTMを作成することができます。
事象階層化では□0から□1をコールしたり、□1.1から△1をコールすることも可能です。

なおレベル番号0のSTMは特別なSTMであり、main関数が生成されます。このレベル番号を付けられるのはE型通常STM、又はS型通常STMのみです。
Q4 ルート所属関係の STM とは何ですか?
A4 STMのレベル番号を指定したとき、整数部分が一致するものがルート所属関係のSTMとなります。
  例)
   □0 ─┬─ □0.1 ─ □0.1.1
            └─ □0.2
   □1 ─── □1.1
上記の例では□0 □0.1 □0.2 □0.1.1がルート所属関係、□1 □1.1がルート所属関係となります。
ルート所属関係の内、一番上位(親)のSTMをルートSTMと呼びます。
例では□0と□1がルートSTMとなります。
ルート所属関係のSTMは型が一致しているため(FAQ Q3を参照)生成コードが共通にまとめられます。
ジェネレータの設定で「ルート設定」とあるのはルート所属単位の設定になります。
Q5 STM の呼び出し記述(記号)について。
同じルートに所属する STM の呼び出しには通常型(□)を使い、ルートの異なる STM の呼び出し にはサブルーチン型(△)を使う旨、拡張階層化状態遷移表設計手法 Ver.2.0 に記述があるのですが、 実際には、ルートの異なる STM の呼び出しにも「□」が使えて、生成コードを見ても違いがない ように思えます。
「□」と「△」の違いは形式的なものなのでしょうか?
A5 サブルーチンSTMは、通常STMとほとんど変わりませんが、1つだけ通常STMと違う点があります。
それは、サブルーチンSTMの場合のみ状態管理をユーザ指定の引数でも行える事です。
呼ばれたサブルーチンSTMは、指定された状態でエントリーする事が出来ます。
上記の機能を使用されない限り、△と□の違いはありません。
*サブルーチンについての詳細な内容がZIPCガイド(状態遷移表手法書入門のPDFファイル)P89〜に記載されています。ご参照ください。
Q6 インメイル機能で他のプロセスで実行されている STM にインメイルは発行できますか?
A6 インメイルは、同一のルート所属内のSTM間で通信を行う機能です。
したがって、他プロセスや他ルート所属のSTMへのインメイル発行は行えません。
Q7 インメイルの実行タイミングについて教えて下さい。 STM1 の処理セルから STM0 に対してインメイルを発行した場合に、この STM0 に対するインメイルが 実際に実行されるタイミングはどのようになるのでしょうか?
*STM1 の処理セルに、
処理1;
STM0 にインメイル発行;
処理2;
のように記述したとすると、処理の順序としては、
(1) STM1 からインメイル発行
(2) STM1 の残りの処理2;を実行
(STM1 を抜ける)
(3)STM0 のインメイルが解析されて実際の処理が行われる
の順序で実行されますか?
A7 この通りに実行する事も出来ます。
実際には、設定によってインメイルの処理タイミングを変える事が出来ます。
設定には以下の種類があります。
1) イベントがヒットした際にインメイル実行関数をコールする。
2) イベント解析後にインメイル実行関数をコールする。
設定方法は以下の手順で行います。
ZIPCのメニュー[プロジェクト]-[プロジェクト設定]-[Cコード生成設定]から表示されるダイアログの[ルートSTM設定]ページからインメイル実行関数コール箇所を選択します。

このように指定した場合の処理タイミングを以下に示します。
1) イベントがヒットした際にインメイル実行関数をコール にした場合。
具体的には、イベント解析関数(xxxif.c)内で、
  ....
  if( e1 ) {
      .... (イベントヒットによるアクション呼び出し生成部分)
      /*インメイル実行関数コール部分*/
      zt1_0_InmailExec((char*)&GetInm);
  }
  else if( e2 ) {
      .... (イベントヒットによるアクション呼び出し生成部分)
      /*インメイル実行関数コール部分*/
      zt1_0_InmailExec((char*)&GetInm);
  }
  ....
のように、アクション呼び出し処理終了毎に、インメイル実行関数がコールされます。
2) イベント解析後にインメイル実行関数をコールする。
具体的には、イベント解析関数(xxxif.c)内で、
  ....
  if( e1 ) {
      .... (イベントヒットによるアクション呼び出し生成部分)
  }
  else if( e2 ) {
      .... (イベントヒットによるアクション呼び出し生成部分)
  }
  ....
  /*インメイル実行関数コール部分*/
  zt1_0_InmailExec((char*)&GetInm);
  ....
のように、イベント解析を終了した後で、インメイル実行関数がコールされます。
なお、1)/2) 両方共に指定した場合は、イベントヒット後及びイベント解析後の両方で、インメイル処理が実行されます。
*この設定についての詳細な内容がZIPCガイドに記載されております。
・Ver.6.0をご使用の場合 --> ZIPCバイブルのPDFファイルP539を
・2000をご使用の場合 --> ZIPCバイブル-第14章 ジェネレータ-のPDFファイルP14-86を
ご参照ください。
Q8 インメイルの処理タイミングで複数個のインメイルが到着していた場合、その処理は一気に行われるのでしょうか?
それとも、そのタイミングで処理されるのは1イベントで、また次のループに処理は委ねられるのでしょうか?
A8 インメイルの処理は一気に行われます。
インメイル処理タイミングでは、キューイングされている全てのインメイルが無くなるまで続けて処理されます。
Q9 インメイルの個数やサイズに制約はありますか?
A9 個数、サイズ共に制約があります。
個数は、インメイルキューのサイズで管理され、最大値はshortで表せる値(32767)となります。
サイズは、インメイルのデータサイズで管理され、同じく最大値はshortで表せる値となります。
設定方法は、ZIPCのメニュー[プロジェクト]-[プロジェクト設定]-[Cコード生成設定]の[ルートSTM設定]ページから、設定するルートSTM名を選択した状態でインメイルキュー数及びインメイルデータサイズに数値を記述します。
Q10 事象の階層化でグローバル遷移をする場合、どのように記述すればよいでしょうか?
注)グローバル遷移とは、他の STM の状態を遷移させる事。それに対し、自STMの状態を遷移させる事をローカル遷移と言う。
A10 ローカル遷移の場合、状態名称、又は状態番号を指定して遷移しますが、グローバル遷移の場合にはSTM名称>遷移名称または遷移番号STMレベル番号>遷移名称または遷移番号のようにSTMを指定して遷移します。
またローカル遷移や複数のグローバル遷移を混在させる場合にはそれぞれの遷移指定を "/" で区切ります。
  例)
   ┌──────┐  遷移セルでの記述
   │0/0.1>1/子>2│  自STMを0に遷移、□0.1を1に遷移
   └──────┘  □子を2に遷移

   =>2/1>2       処理セルでの記述
             自STMを2に遷移、□1を2に遷移

      また、STM記号(□、△等)を用いた記述も行えます。
   =>2/□1>2      処理セルでの記述
                          自STMを2に遷移、□1を2に遷移
Q11 固定遷移、記憶遷移、深層記憶遷移の違いについて教えてください。
A11 階層された状態への遷移は、親状態を指定して遷移する事が出来ますが、その際、どの子状態がアクティブとなるかが、上記の3つの遷移方法で異なります。
固定遷移とは:
指定された状態の子状態は、全てデフォルト状態となります。
デフォルト状態とは、番号の若い状態または、デフォルトマークが指定されている場合は、その状態となります。
記憶遷移とは:
指定された状態の1階層下の子状態は記憶(前回アクティブだった状態)された状態がアクティブとなり、それ以降の階層についてはデフォルト状態となります。
深層記憶とは:
指定された状態の子状態は全階層において状態を記憶しており、記憶された子状態がアクティブとなります。
参考までにそれぞれのSTMは、以下の通りとなります。
■ 固定遷移の STM

■ 記憶遷移の STM

■ 深層記憶遷移の STM

詳細説明については、ZIPC2000に付属している「状態遷移表手法書入門」のP86を御参照下さい。
Q12 STM に引数を渡すにはどうしたらいいでしょうか?
A12 引数定義は、STMエディタの[書式]-[STM設定]で起動するダイアログの引数エリアに、C言語の関数宣言時の引数指定と同様の形で指定します。
  例) char p1, char p2
上記の指定によりイベント解析関数、STM操作関数、処理関数にそれぞれ引数が追加され、アクション処理で引数を参照することができます。

引数指定のSTMをコールする場合の指定方法は
   □1(引数1,引数2);
のように引数を渡してコールします。
  例) □1(1,2);
Q13 □0 で引数指定をした場合、main 関数からどのように引数を渡せばよいのでしょうか?
A13 □0の場合、main関数からif解析関数コール部分には引数指定された変数を渡していますが、通常は変数定義がないためエラーになります。
  main(void)
  {
    ....
    while {
      xxxxif( a );     //引数定義で指定された引数を渡しているが
    }         //この変数の定義がないためエラーになる。
  }
この場合、ユーザーが手作業でmain関数に手を加える必要があります。
手を加えた場合には再生成したときに上書きされるため、注意が必要となります(ジェネレータのルートSTMオプションでmain関数を生成しないようにすることは可能です。)。

上記の場合、手順が複雑であるため、main関数から引数を渡す方法としては下記をお勧めします。

レベル番号を0以外に変更(1〜)する。レベル番号を0以外にすることでmain関数は生成されなくなります。
次にFNC設計書でmain関数を作成します(CファイルでもOKです)。
 main(int a)
  {
    STM初期化関数();  //注1
  while(1) {
      //イベント取得処理
      revent();       //注2
      if解析関数(a);  //注1
    }
  }
注1) STM初期化関数、if解析関数はジェネレータオプションのルートSTM設定ページで関数名称を指定すると、指定された関数名称でコールすることができます。
設定方法は、ZIPCのメニュー[プロジェクト]-[プロジェクト設定]-[Cコード生成設定]の[ルートSTM設定]ページで、ツリー上のSTMを指定した状態で、初期化関数名称エリアとコール関数名称エリアに記述します。
注2) イベントを取得する処理を記述してください。
シミュレーションフェーズでイベント名称シミュレーションを行う場合にはrevent()をコール(記述)します。
Q14 階層化について教えてください。
A14 ZIPC では STM を、親−子−孫・・・と下図のように階層化することができますが、これによって、複雑で巨大なSTMを解りやすい小さなまとまりで表現することができます。

ルート(親)STM 以下に階層化されるSTMをまとめて「ルートSTM所属」と呼びますが、ルートSTM所属下では、ルートSTMで設定したクローン/引数/リターンを下位階層のSTMでも引き継がれる仕組みになっています。
すなわち、下位階層のSTMではクローン/引数/リターンの設定はルートと同様に行います。
Q15 STMのE型とS型について教えてください。
A15 ZIPCでは、イベントドリブンな動作をE型駆動と呼び、ステートドリブンな動作をS型駆動と呼びます。

<E型駆動>
イベントドリブンとは、プログラムの1ヶ所でイベントを待ちます。
待ち方はRTOSを搭載していればRTOS機構を用いてもよいし、プログラムでフラグセンス(ポーリング)で行っても構いません。
肝心なのは「1ヶ所で事象を待つ」ということで、あらゆる状態下であらゆる事象を受け付けることになります。
受け付けられた事象は、イベント解析でSTM毎に割り振られた事象Noが算出され、現在の状態Noとクロスする部分のアクションが呼び出されることになります。
この基本動作フローは以下のようになります。


<S型駆動>
ステートドリブン型は、それぞれの状態でイベントを受け付ける構造となります。
それぞれの状態でイベントを受けるということは、それぞれの状態にイベント解析が存在するということです。
ただし、グルーピングされた上位の状態セルはイベント解析関数をもちません。
Q16 STMのE型(事象)階層化とS型(状態)階層化について教えてください。
A16 <E型階層化>
E型階層化とは、上位のSTMでは概要の事象としてとらえ、上位のSTMはその事象を下位のSTMに伝達し、下位のSTMで詳細な事象としてとらえることです。
事象に関する概要から詳細という関係を構築し、解りやすい小さなSTMで複雑で巨大なシステムを構成できます。
例えば、自転車を簡単な仕様で階層化を使って作成してみると次の様になります。


これを簡単に説明すると・・・
自転車のギアの部分が階層化されています。 「ギア」イベントが発生すると、ルートSTM(レベル番号0)から階層STM(レベル番号0.1)をコールしています。
E型階層STMのコール書式は、
 □レベル番号; または □STM名称;
となり、上記ルートSTMの場合は
 □0.1; または □ギア;
を処理セルに記述します。
注意: セミコロンは、ジェネレータでCソースコードを生成する際に必要となります。

<S型階層化>
S型階層化とは、S型STMのみで使用できる機能です。
S型階層STMは状態からコールされます。
コールといっても、E型STMのようなコールではなく、状態ツリーの一部としての階層となります。
したがって、状態フレームを使用した場合と、状態階層を使用した場合も状態スケジュール方法は変わりません。
S型階層STMは、ルートSTM所属内のSTMを指定します。
他のルート所属のSTMは状態階層として指定できません。
S型階層STMの指定方法は、「■STM名称、または、■レベル番号」を状態名称の下(改行して)に記述します。

上記から状態をツリーで表現すると、次のようになります。


状態を状態ツリーで表現すると上記のような構成になります。
S型スケジュール駆動時の状態スケジュールはこの状態ツリーで管理しているため、動作も同様になります。

したがって、状態階層STMとは、状態をまとめて設計書を見やすく、まとまりのある設計書にするための機能になります。
Q17 クローンについて教えてください。
A17 クローンSTMは、1つのSTMから複数の状態管理が可能なSTMです。
複数の状態管理ができるということは、例えば通信プロトコルタスクが複数の相手局やチャンネルの管理を同一プロトコルで管理する場合などに便利です。

(1)ルートSTMがクローンSTMの場合
ルートSTMがクローンの場合、イベント解析の前にクローンを指定してSTMを駆動します。
STMを階層化している場合、子STMはルートSTMの管理下にあるため、子STMも同じクローンで動作します。


(2)クローンでないルートSTMから、クローンSTMをコールする場合
階層化している場合に、子STMでは親と同じ管理になります。
親にクローンが存在しない場合は子のクローンは存在しません。
このような場合、親と異なるルートSTMを作るか、サブルーチンにする方法があります。


クローン定義は、STMエディタの[書式]-[STM設定]メニューからオープンされるダイアログのSTM名称エリアに、STM名称の右横にC言語の配列と同様に "[?]" の形で指定します。
クローンSTMは、クローンの管理をRAM変数で管理しています。
このクローン管理変数は、ルートSTM所属ごとに生成されます。
unsigned short zXXXX_clone ; (XXXZRA.Cに生成される)
各ルートSTM所属のSTMは、このクローン管理変数の値により動作します。
Q18 ライブラリSTMとサブルーチンSTMについて教えてください。
A18 <ライブラリ>
ライブラリSTMは、イベント入力部を指定した関数で設計するSTMになります。
関数はイベントセルに記述しますが、STMのコール形式も、イベントセルに記述した関数でコールします。
関数記述方法は、C言語での関数宣言と同様に、リターン型、引数を定義します。

STM種別は、E型ライブラリのみ使用できます。
S型は状態下でイベントを検出するステートドリブンな動作のため、関数コールで動作するライブラリでは使用できません。

<サブルーチン>
サブルーチンSTMは、通常STMとほとんど変わりません。
サブルーチンのルートレベル番号は0を指定することはできません。
0以外の整数を指定します。(1〜)

サブルーチンSTMは、どの種別のSTMからもコールできますが、コールできるのは、E型サブルーチンのみです。
S型通常STMで、状態階層STMをサブルーチンSTMにすることは出来ません。
状態階層STMはルート所属内のSTMしかできません。
E型サブルーチンSTMのコール方法は、『△』のSTM名称又は レベル番号で指定します。
△STMA;  △2;
Q19 グローバルトランジションの遷移方法について教えてください。
A19 STMを階層化している場合、自STM以外のSTMの状態を遷移させたい場合があります。
この時の、他のSTMの状態を遷移させること「グローバルトランジション」と呼びます。
それに対して、自STMの状態を遷移させること「ローカルトランジション」と呼びます。

グローバルトランジションの記述は、

・・・と、なります。
注) 「 > 」は1バイト文字となります。
グローバルトランジション、ローカルトランジションをあわせて複数の遷移を記述する場合は、遷移と遷移を「/ 」でつないで記述します。(/は1バイト文字となります。)

[ 例 ]
 0/0.1>2
この場合は、自STMを状態0へ、0.1レベルのSTMを状態2への遷移となります。
 状態1/子STM>状態3
この場合は、自STMを状態1へ、子STMを状態3への遷移となります。
Q20 既存の関数からSTMに引数を渡すにはどうしたらいいでしょうか?
A20 引数定義は、STMエディタの[ 書式 ]-[ STM設定 ]メニューからオープンされるダイアログの引数エリアに、C言語の関数宣言時の引数指定と同様の形で指定します。
ZIPCジェネレータで生成されたソースで説明すると、指定された引数はイベント解析関数に定義され、イベント解析関数からコールされるSTM操作関数、処理関数に引数が渡ります。
したがって、STMに引数を指定した場合はSTMの処理関数でも参照できる仕組みになっています。

また、引数指定のSTMをコールする場合は、C言語の関数コールと同様に「 ( ) 」で引数を指定します。
例) □0.1(引数1,引数2);
▲ ページTOPへ