バーチャルマシンのフック関数内からIXLサービスをコールするサンプル


バーチャルマシンのフック関数内でIXLサービスをコールするプログラムの例です。

毎サイクル、システム変数の情報を表示します。
フック関数の追加方法についてはこちらのページをご覧下さい。
このサンプルを実行する前に、ワークベンチのプロジェクト管理で、リソースのプロパティを表示し、「ターゲット/コード」タブの「完全なテーブル」および「組み込みシンボルテーブル」のオプションをチェックしておく必要があります。

/***************************************************************************************
*
* ISaGRAF Ver.4/5ターゲットのフック関数内からコールするIXLクライアント
* このサンプルではシンボルにアクセスするサービスのみ使用しています。
* StartDialog, Read, Write等のIXLリクエストは使用していません。
* これらを使用する場合は、通知サービスを使う必要があります。
*
* 使用しているフック関数:
* - kerHookRStart() : リソースのスタート時に1回だけコールされるフックで、以下の関数をコールしています
* - ixcInit(), ixlExit()
* - ixlConnect(), ixlDisconnect()
* - ixlSymLoad(), ixlSymUnload()
* - ixlSymInfoFromName()
* - kerHookEndOut() : 毎サイクルコールされるフックで、変数値などの表示を行っています。
* - kerHookRStop() : リソースのストップ時にコールされるフックで、IXLの切断を行っています。
* 以下の関数をコールしています。
* - ixlSymUnload()
* - ixlDisconnect()
* - ixlExit()
*
* 【このサンプルの注意事項】
* 文字列型変数はサポートしません。
* システム変数のみを使用しています。ただ、アプリケーションの変数に置き換えて使うこともできます。
*
* 上記のフックを利用可能とするために、"dsys0def.h" ファイルを変更し、
* 以下の定義を追加してください。
* #define ITGTDEF_KERHOOK_RSTART
* #define ITGTDEF_KERHOOK_ENDOUT
* #define ITGTDEF_KERHOOK_RSTOP
*
* 注意: ワークベンチ上で、リソースプロパティの「ターゲット/コード」タブで
* 「シンボルテーブルの組込み」と「完全なテーブル」オプションが設定されていることを
* 確認してください。
*
* Made by TCD
* Date August 8th 2001
* Copyright CJ International 2001.
****************************************************************************************/


#include <dsys0def.h>
#include <dixl0pro.h>
#include <dker0def.h>
#include <dker0res.h>
/* グローバル変数 */
static uchar _cuSTATUS =0; /* フラグ:0 未初期化, 1 初期化OK, 2 接続OK, 3 変数の読みこみ準備OK */
static uchar _CRCcheckresult; /* resRdbCrcCheck()関数の実行結果 */
static uint16 _huClient; /* クライアント番号 ディフォルトは4001 */
typIxlId _IXLId; /* IXL クライアントの識別子 typIXLIdへのポインタ */
strIxlCnxInfo _IXLConnectInfo; /* ixlConnect()に渡す接続情報の構造体 */
typIxlCnxId _IXLCnxId; /* ixlConnect()が返す接続ID */
strIxlVarDesc _IXLVar[5]; /* ixlSymInfoFromName()が返す変数記述の配列 */
strIxlResInfo _IXLSymInfo; /* ixlSymResInfo()が返すシンボル情報構造体 */

void IXL_ErrorManager
( uchar huErrorNum /* 終了時に実行すべき関数を特定するためのエラー番号 */
)
{
    switch(huErrorNum)
    {
      case 3:
        ixlSymUnload(_IXLCnxId);
      case 2:
        ixlDisconnect(_IXLCnxId);
      case 1:
        ixlExit(&_IXLId);
      default:
        break;
    }
}

void kerHookRStart(void)
{
    typSTATUS errorRetinit; /* ixlInit()が返すエラー変数 */
    typSTATUS errorRetSymLoad; /* ixlSymLoad()が返すエラー変数 */
    typSTATUS errorRetSymGetFromName;/* ixlSymFetFromName()が返すエラー変数 */
    typSTATUS errorRetSymGetInfo; /* ixlSymGetInfoが返すエラー変数 */
    short i;
    _huClient=4001; /* クライアント番号識別子 */

    /*
    * このフックは接続や他のリクエストの初期化のために1回のみ実行ます。
    * 以下の関数は最初のサイクルで実行されます。
    */

    /*
    * ixlInit クライアントの識別番号を渡して接続を初期化
    */

    errorRetinit = ixlInit(&_IXLId,_huClient,0,0,0);

    if (errorRetinit==BAD_RET)
    {
      printf("ERROR NUMBER(%x) : Initialization FAILED \n",(uint32)dsysFctErrnoGet());
      IXL_ErrorManager(1);
      return;
    }
    _cuSTATUS = 1; /* 初期化完了をフラグに記録 */
    printf("Initilisation succeeded\n");

    /*
    * IXL 接続: 下記の情報を構造体で渡す
    * - グローバル変数 KSYS.huSlaveNumから取得したスレーブ番号
    * - ドライバ名: HSD (ローカル接続)
    * - メソッド: ウェイトモード、ブロッキング
    */

    _IXLConnectInfo.huSlaveNum=KSYS.huSlaveNum;
    _IXLConnectInfo.psDriverName=0;
    _IXLConnectInfo.luMethod= 0;
    _IXLConnectInfo.luTimeOut=10000;
    _IXLConnectInfo.luAppClassKey=0;
    _IXLCnxId = ixlConnect(&_IXLId, &_IXLConnectInfo,0,0);
    if (_IXLCnxId ==0)
    {
      printf("ERROR NUMBER(%x) : Connection to VM FAILED\n",(uint32)dsysFctErrnoGet());
      IXL_ErrorManager(2);
      return;
    }
    _cuSTATUS = 2; /* 接続完了をフラグに記録 */
    printf("Connection to resource %d succeeded\n",_IXLConnectInfo.huSlaveNum);

    /*
    * ixlSymLoad : アプリケーションの全シンボルをロード
    * - typIxlCnxId CnxId : ixlConnectが返す接続識別子
    * - strIxlResInfo* pResInfo : リソース情報の格納先。不要ならば0。リソースとシンボルとの間のチェックは行わない。
    * - char* psFileName : シンボルファイル名。0の場合は補助記憶装置にあるファイル IDSxxx01 を取得する。
    */

    errorRetSymLoad = ixlSymLoad(_IXLCnxId, 0, 0);
    if (errorRetSymLoad==BAD_RET)
    {
      printf("ERROR NUMBER(%x): Symbols Load Failed\n", (uint32)dsysFctErrnoGet());
      IXL_ErrorManager(3);
      return;
    }
    printf("Loading symbols succeeded\n");

    /*
    * ixlSymResInfo : リソースのCRCをチェックするための情報を取得し、
    * シンボルのCRCと比較します。リソースのCRCはresRdbCrcChek()関数で取得します。
    * CRCが正しければ、変数値を読み込めるようになります。
    * - typIxlCnxId CnxId : ixlConnect()が返す接続識別子
    * - strIxlResInfo* pResInfo : リソース名、CRC等の全ての必要な情報を保存している構造体
    */

    errorRetSymGetInfo = ixlSymResInfo(_IXLCnxId, &_IXLSymInfo);
    _CRCcheckresult = resRdbCrcCheck(_IXLSymInfo.luRDtaBaseCrc,FALSE);
    if (_CRCcheckresult==TRUE)
      printf("CRC match\n");
    else if (_CRCcheckresult==FALSE)
    {
      printf("ERROR NUMBER(%x): Check of data CRC on resource failed\n",(uint32)dsysFctErrnoGet());
      IXL_ErrorManager(3);
      return;
    }

    /*
    * ixlSymInfoFromName : 変数名を元に変数情報を取得する関数
    * IXLVar :構造体 strIxlVarDesc の配列
    * IXLクライアントの構造を簡単にするために、アクセスする変数名を直接記述しています。
    * 文字列型以外の任意の変数名をここに設定することができます。
    * ディフォルトでは5変数のみスパイできますが、数は増やしても構いません。
    */

    _IXLVar[0].psVaName = "__SYSVA_SCANCNT";
    _IXLVar[1].psVaName = "__SYSVA_RESMODE";
    _IXLVar[2].psVaName = "__SYSVA_TCYMAXIMUM ";
    _IXLVar[3].psVaName = "__SYSVA_TCYCYCTIME";
    _IXLVar[4].psVaName = "__SYSVA_TCYOVERFLOW";
    /* _IXLVar[5].psVaName = "VARIABLE_NAME1"; アプリケーション変数を追加した例です */

    for (i=0;i<5;i++)
    {
      errorRetSymGetFromName = ixlSymInfoFromName(_IXLCnxId, &(_IXLVar[i]), 1);
      if (_IXLVar[i].Va == 0) /* 指定した名前の変数が見つからない */
      {
        printf("Variable %s not found in symbol table\n", _IXLVar[i].psVaName);
        errorRetSymGetFromName = BAD_RET;
        IXL_ErrorManager(3);
        return;
      }
      if (errorRetSymGetFromName == BAD_RET)
      {
        printf("ERROR NUMBER(%x) :: Symbols could not be loaded \n", (uint32)dsysFctErrnoGet());
        IXL_ErrorManager(3);
        return;
      }
    }
    _cuSTATUS = 3; /* シンボルのロードとその他全ての処理が成功したことをフラグに記録 */
}

kerHookEndOut(void)
{
    int i;
    if (_cuSTATUS == 3) /* 全部準備OK */
    {
      for (i=0;i<5;i++)
      {
        printf(" %s\t",_IXLVar[i].psVaName); /* 変数名表示 */
        printf(" VA=%x\t",_IXLVar[i].Va); /* 変数アドレス表示 */
        printf(" Type=%d\t",_IXLVar[i].cuVaType); /* 変数タイプ表示 */
        switch(_IXLVar[i].cuVaType) /* 変数タイプ別に値を表示 */
        {
          case 1:
            printf ("Value = %d\n", KBF_BOOL(_IXLVar[i].Va));
            break;
          case 2:
            printf ("Value = %d\n", KBF_SINT(_IXLVar[i].Va));
            break;
          case 3:
            printf ("Value = %d\n", KBF_DINT(_IXLVar[i].Va));
            break;
          case 4:
            printf ("Value = %ld ms\n", KBF_TIME(_IXLVar[i].Va));
            break;
          case 5:
            printf ("Value = %f\n", KBF_REAL(_IXLVar[i].Va));
            break;
        }
        dsysTimeWait(200);
      }
      printf("\n");
    }
}

void kerHookRStop(void)
{
    IXL_ErrorManager(_cuSTATUS);
    printf("Closing succeeded. BYE BYE\n");
}
最終更新:
2008-07-31 11:16
改訂:
1.1
評価点数:0 (0 件の投票)
Chuck Norris has counted to infinity. Twice.