このサンプルはWindows NTの場合です。
仕様
VMのカレントディレクトリ(通常はターゲットのCMDSディレクトリ)に"STOP"という名前のファイルが生成されると、ターゲットはストップします。
また、"START"という名前のファイルが生成されると、ターゲットはスタートします。
アルゴリズム
ターゲットをストップさせる簡単な方法は、エラーモードに移行させることです(アプリケーションで0除算が発生した場合などにもこのモードになります)。このモードになってもI/Oドライバはコールされますが、アプリケーションは実行されません。そのため、この例ではこのモードでI/Oドライバの使用も禁止する方法についても説明します。
まず、下記の関数は"stop" ファイルを検出するためのもので、ターゲットのフック関数で使用します。コードは "SmpHooks.c" に追加します。
なお、フックを実装する方法については「ターゲットにフック関数を実装する方法」をご覧ください。
/************************************************************************** File: SmpHooks.c Author: GGR - CJ International Creation date: 27-Jun-2001 --- 4.10 Released --- *************************************************************************** ドキュメント: *************************************************************************** 説明: メッセージを表示するための関数 *************************************************************************** Modifications: (who / date / description) ***************************************************************************/ #include <dsys0def.h> #include <dker0def.h> #include <dker0uhk.h> #include <sys/stat.h> /* I/Oドライバを禁止するための関数 */ __declspec(dllimport) void FlagStopDriverSet(uchar FlagStopRequest); /****************************************************************************** function : kerHookBegCycExec description : 各サイクルの最初にコールされるフック関数 テキストファイル start/stopが存在するかどうかをチェックする warning : ******************************************************************************/ void kerHookBegCycExec(void) {
if (_stat("START", &StatFile) == 0) /* STARTファイルが存在する */ {
KBF_SINT(ISA_SYSVA_RESMODE) = ISA_RESMODE_RT; /* システム変数にリアルタイムモードで実行するよう書きこむ */ remove("START");
{
KBF_SINT(ISA_SYSVA_RESMODE) = ISA_RESMODE_RS; /* システム変数に致命的なエラーが起きたことを書きこむ */ remove("STOP");
{
else {
/*****************************************************************************/ |
ここで、エラーモードの場合にI/O処理を禁止させたい場合は、各I/Oドライバに以下のコードを追加します。
まず、ISaVM プロジェクトに「追加ライブラリのパス」でドライバのライブラリのパス名と、ライブラリ名を追加します (この例では CjIOSmpl.lib とします)。
追加するコードは次の通り。
/* このファンクションは毎サイクルの最初フック関数(ISA_KERHOOK_BEGCYCEXEC)からコールされます。 */ static uchar _cuSTOPFLAG; __declspec(dllexport) void FlagStopDriverSet(uchar FlagStopRequest) {
|
これで、ドライバ側のread/writeの各関数内で _cuSTOPFLAG の値をチェックできるようになります。
(_cuSTOPFLAG == 0) ならば、読み込みまたはI/O出力を更新するようにします。
注意事項
アプリケーションで0除算などの致命的なエラーが発生した場合は、この変更を施したI/Oドライバはコールされなくなりますので注意してください。
また、トリガーイベントの検出は、サイクルタイム毎の間隔となります。