C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: ポーリング処理


(過去ログ 53 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■29450 / inTopicNo.1)  ポーリング処理
  
□投稿者/ 初心者 (198回)-(2008/12/09(Tue) 21:32:01)

分類:[C#] 

2008/12/09(Tue) 22:06:45 編集(投稿者)
すみません、行き詰ってます。

前に質問した者ですが、現在、C#でGPIBインターフェイスで制御しようとしています。

使用しているインターフェイスボードはInterface社の物です。



現在、機器が動作中より停止した際に発するSRQを取得しようとしています。

その際にポーリングを行わなければならないのですが、やり方を読んでもよくわかりません。




GpibSetSrqEvent……指定番号のボードからのSRQコールバックイベントを登録します。

GpibWaitSrqEvent……指定番号のボードからのSRQコールバックイベントを待ちます。

GpibKillSrqEvent……指定番号のボードからのSRQコールバックイベントの登録を解除します。



インターフェイス社の物では、上記の順番で行われるようなのですが、最初のGpibSetSrqEventから詰まってしまっています。
これにはC言語の解説しかなく、


***********************************************

●C言語

#include "GPC43042.H" 
int GpibSetSrqEvent( 
 ULONG ulBoardNo, // ボード番号 
 LPSRQCALLBACK lpOnSrqProc, // コールバック関数のアドレス 
 DWORD dwUser // ユーザパラメータ 
); 

 
lpOnSrqProc コールバック関数のアドレスを指定します。説明「コールバック関数」を参照ください。
dwUser コールバック関数に渡す任意の32ビットデータを指定します。 


***********************************************



まずここで疑問が…何を基準に任意のビットデータを指定すればよいのかわかりません。
また、コールバック関数は、




***********************************************

●C言語

  void CALLBACK lpOnSrqEvent( 
       ULONG ulBoardNo,  // ボード番号
       DWORD dwUser       // ユーザデータ
  );



コールバックルーチンの関数型 LPSRQCALLBACK は下記のように定義されます。
#define LPSRQCALLBACK    VOID WINAPI
typedef void (WINAPI *PLPSRQCALLBACK)(ULONG ulBoardNo, DWORD dwUser);

【パラメータ】

パラメータ
 説  明
 
ulBoardNo
 イベントが発生したボード番号が格納されます。 
dwUser ユーザデータを指定します。 


【戻り値】
   この関数に戻り値はありません。


***********************************************



このようにコールバック関数でもユーザーデータが必要となります。

最初にコールバック関数を宣言するのですが、C言語ではvoidで宣言されていて、C#ではどのように宣言したらいいのかわかりません。


GPIBという特殊な環境ではありますが、何か手がかりになるようなことなんでも結構ですのでアドバイスいただけたらと思います。

また、仕様など、なにかご不明な点がございましたら、わかる範囲で答えます。


よろしくお願いします。

引用返信 編集キー/
■29454 / inTopicNo.2)  Re[1]: ポーリング処理
□投稿者/ chobi (10回)-(2008/12/09(Tue) 23:10:23)
GPIBの動作の流れとしては
(1) SRQがLOWに下がる(定期的にスキャンするのかな、WM(ウインドウメッセージ)でも掴まえるのかな・・ボードの仕様が全く分からない)
(2) コントローラはシステム内のどのトーカがSRQを発したのかステータスバイトを送らせて調べる。(ポーリング処理)
(3) 発見したら必要な処理を施す。(多分SRQを発信したトーカをリセットするのかな?専用のAPIがあるんじゃないですか?)

で、(3)の処理を同期処理するか、非同期処理をするかで
同期処理の場合、"GpibWaitSrqEvent"で(3)の処理が終わるまで、他の処理は止めてひたすら待つ
非同期処理の場合、(3)の処理が終わるまで他の処理は継続して、(3)が終了した時点で"CALLBACK lpOnSrqEvent"が呼ばれる
という感じではないでしょうか。(GpibSetSrqEventを登録するか否かで"CALLBACK"が呼ばれるかどうかが決まる)

>まずここで疑問が…何を基準に任意のビットデータを指定すればよいのかわかりません。

多分、コールバック関数に渡したいデータがないのならばダミーデータでも入れといて使わなければ良いだけでしょう

>最初にコールバック関数を宣言するのですが、C言語ではvoidで宣言されていて、C#ではどのように宣言したらいいのかわかりません

C#でもVOIDで良いでしょう。コールバック関数の戻り値を受け取れる人はいませんから・・・
通常コールバック関数では、(3)でリセットされたトーカの初期設定でもするのではないでしょうか?

とういような推論はいかがでしょうか?
引用返信 編集キー/
■29457 / inTopicNo.3)  Re[2]: ポーリング処理
□投稿者/ 初心者 (200回)-(2008/12/10(Wed) 00:27:14)
No29454 (chobi さん) に返信
> GPIBの動作の流れとしては
> (1) SRQがLOWに下がる(定期的にスキャンするのかな、WM(ウインドウメッセージ)でも掴まえるのかな・・ボードの仕様が全く分からない)
> (2) コントローラはシステム内のどのトーカがSRQを発したのかステータスバイトを送らせて調べる。(ポーリング処理)
> (3) 発見したら必要な処理を施す。(多分SRQを発信したトーカをリセットするのかな?専用のAPIがあるんじゃないですか?)
>



(1)
その流れは読んでみたのですがわかりませんでした。
他に詳しく書いてあるかもしれませんが、また探して見つかり次第、載せます。
情報が少なくて申し訳ありません。


********************************************************
ここで、サービス要求をしている機器を探す方法として、シリアル・ポーリングとパラレル・
ポーリングがあります。
シリアル・ポーリングは、コントローラがサービス要求元と思われる機器を1台ずつ順番に呼び
出して、その時の機器の状態を示すステータス・バイトと呼ばれる1バイトの情報を送らせ、こ
の内容を調べることで、サービス要求元とその要因を取得します。 規格上、ポーリング機能と
SR機能は別の機能なので、SR機能のない機器でもポーリングは可能です。そうすればコント
ローラは好きな時にステータス・バイトを読むことで、現在の機器の状態を知ることができ、
それに応じた処理を行うことができます。

********************************************************






> >まずここで疑問が…何を基準に任意のビットデータを指定すればよいのかわかりません。
>
> 多分、コールバック関数に渡したいデータがないのならばダミーデータでも入れといて使わなければ良いだけでしょう
>


ダミーデータですか!何か仮に数値を入れてみればよいのですかね…
ありがとうございます。
コールバック関数には特に必要な数がないので、どうすればいいのか困っていました。





調べていたら、コールバック関数からの一連の流れをC#で説明してくれている資料がありました。
手際が悪くてすみません。

ここではデリゲートを利用しているのですが、順序は、




List 4-28 コールバック用デリゲート宣言
public delegate void PLPSRQCALLBACK(int nBoardNo, uint dwUser);




List 4-29 GpibSetSrqEvent関数宣言
public static extern int GpibSetSrqEvent(uint ulBoardNo, PLPSRQCALLBACK lpOnSrqProc,
uint dwUser);




・Step2:コールバック関数の作成
lpSrqProcというコールバック関数を宣言します。
引数パラメータの数、型を、デリゲートPLPSRQCALLBACKと合わせます。
List 4-30 コールバック関数
void lpOnSrqProc(int dwBoardNo , uint dwUser)
{


}




・Step3:DLL関数呼び出し
デリゲートPLPSRQCALLBACKのオブジェクト保存先を定義します。
コールバック関数の呼び出しが繰り返される期間中に解放されないクラスの変
数などにします。


List 4-31 デリゲートオブジェクト保存先変数定義
IFCGPIB.PLPSRQCALLBACK osp;
関数lpOnSrqProcをコールバック関数として、PLPSRQCALLBACKデリゲートオブジ
ェクトを生成します。デリゲートオブジェクトを、GpibSetSrqEvent関数の第2パラメ
ータに指定して呼び出します。


List 4-32 GpibSetSrqEvent関数呼び出し
osp = new IFCGPIB.PLPSRQCALLBACK (lpOnSrqProc);
nRet = IFCGPIB.GpibSetSrqEvent(1, osp, 0x55);
以上でコールバック関数の登録は完了です。






これを読んでも色々とわからないところが出てくるのですが、

通常デリゲートは宣言してあげた後に、メソッド(今回はlpOnSrqProcを使用?)を宣言してその間に作業を書くと思うのですが、作業に
「ボード番号」と「ユーザーパラメータ」を設定すればいいんですかね。。。
なぜこんな作業をするのでしょうか…
引用返信 編集キー/
■29464 / inTopicNo.4)  Re[1]: ポーリング処理
□投稿者/ .SHO (345回)-(2008/12/10(Wed) 10:16:21)
2008/12/10(Wed) 10:19:36 編集(投稿者)

No29450 (初心者 さん) に返信

> まずここで疑問が…何を基準に任意のビットデータを指定すればよいのかわかりません。

必要なければ使わなくて大丈夫です。
DWORD なので「0」でも入れておけばOKです。

> このようにコールバック関数でもユーザーデータが必要となります。

必要となるのではなく、上で設定した「0」が入ってきます。
引用返信 編集キー/
■29465 / inTopicNo.5)  Re[1]: ポーリング処理
□投稿者/ .SHO (346回)-(2008/12/10(Wed) 10:24:38)
No29450 (初心者 さん) に返信

> その際にポーリングを行わなければならないのですが、やり方を読んでもよくわかりません。

自分でポーリングする必要はないです。

> GpibSetSrqEvent……指定番号のボードからのSRQコールバックイベントを登録します。
> GpibWaitSrqEvent……指定番号のボードからのSRQコールバックイベントを待ちます。
> GpibKillSrqEvent……指定番号のボードからのSRQコールバックイベントの登録を解除します。

GpibSetSrqEvent でイベント登録して、GpibWaitSrqEvent で待ってれば
GpibWaitSrqEvent の中で勝手にポーリングしてくれて、SRQ を捕まえたら
GpibSetSrqEvent で登録した関数に飛んできます。
引用返信 編集キー/
■29466 / inTopicNo.6)  Re[3]: ポーリング処理
□投稿者/ .SHO (347回)-(2008/12/10(Wed) 10:29:56)
No29457 (初心者 さん) に返信

> 「ボード番号」と「ユーザーパラメータ」を設定すればいいんですかね。。。
> なぜこんな作業をするのでしょうか…

「ボード番号」:複数のボードを使用している時に1つの処理ルーチンで済ませるためです。
「ユーザパラメータ」:ユーザへの拡張性を持たせてくれてるだけです。
           必要ないなら無視していいです。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -