• 検索結果がありません。

GP-IB機器からのサービスリクエスト(SRQ)を捉えるプログラム

第 3 章  GP-IB I/O モジュール制御の第一歩 20

3.5  GP-IB機器からのサービスリクエスト(SRQ)を捉えるプログラム

srqevent.oを組み込むと、コンソールに以下のメッセージが出力され、 Agilent34401Aからのサービ

スリクエストの検知とコールバック処理が行われたことがわかります。

# insmod srqevent.o init_module called

Board open success!! [0]

send_task called arg=0 send_data called [*RST]

send_data success!! [ret=0]

send_data called [*CLS]

send_data success!! [ret=0]

send_data called [*SRE 16]

send_data success!! [ret=0]

send_data called [MEASure:VOLTage:DC?]

send_data success!! [ret=0]

srq_callback called [0x4000000, 0]

Serial poll success!!

no.0 status byte=50 addrss=22

PciGpibExRecvData [0, 15, +5.98390000E-05]

次に、組み込んだRTLinuxモジュールを取り外しは、rmmodコマンドで行います。

# rmmod srqevent

(121〜141行目:GP-IBの初期化)

ここでは、

GP-IB I/Oモジュールのオープンと初期化、 IFCの送出と RENの設定が行われています。

この処理は定形的なものです。

(144行目:コールバック関数の登録とイベントマスクの設定)

PciGpibExSetEventMask関数により、コールバック関数の登録とイベントマスクの設定を行います。

ここでは、SRQイベントをとらえるために、イベントマスクを設定する第2引数に、

GPIB_DETECT_SRQを指定しています。

★イベントマスクについて

ここでは SRQ イベントのみを使用するため、GPIB_DETECT_SRQ のみを指定しましたが、複数のイベ ントを使用する場合は、各識別子をPciGpibExSetEventMask関数の第2引数にORで指定します。

SRQ検出とIFC検出を指定する場合>

PciGpibExSetEventMask( GPIB_BOARDNO,

GPIB_DETECT_SRQ | GPIB_DETECT_IFC, srq_callback, GPIB_BOARDNO);

第3引数はコールバック関数のアドレス値を、第4引数にはコールバック関数が呼び出させた際に 渡すユーザ定義の値を指定します。

ここでは、デバイス番号をユーザ定義の値として渡しています。

(154行目:pthread_create関数)

pthread_create関数では、GP-IB機器へのデータ送信を行うRTLinuxスレッド(send_task)を生成して

います。

(87〜98行目:電圧測定の指示)

81行目から始まるsend_task関数は、Agilent34401Aに対して電圧測定を行わせるためのコマンドを

順次送信しています。

Agilent34401Aはデータ送信された内容に従って、何らかの処理を行います。

行  送信内容  処理内容 

87行目

"*RST"

Agilent34401Aを電源投入時の状態にリセットします。

90行目

"*CLS"

Agilent34401A内の各レジスタをクリアします。

93行目

"*SRE 16"

SRQ割り込みを有効にします。

ここでは、ステータスバイトレジスタの、メッセージアベイラ ブルビットを有効にしています。

98行目

"MEASure:VOLTage:

DC?"

Agilent34401Aに対し、電圧測定を行うよう指示します。

各行のsend_data関数は、データ送信を行うサブルーチン(64〜78行目)です。プログラムの記述を簡 素化するために定義しています。

List3-1のデータ送信部分のコードと比較してみてください。

98行目のデータ("MEASure:VOLTage:DC?")を送信すると、Agilent34401Aは電圧の計測を行います。

計測が完了すると、Agilent34401Aは内部バッファに測定したデータを格納します。

この時、

93行目の指示("*SRE 16")により有効にされた、割り込みマスク(ステータスバイトレジス

タのメッセージアベイラブルビット)により、Agilent34401AはSRQを発行します。

(動作の詳細は、Agilent34401A付属のマニュアル「SCPIステータスモデル」を参照してください)

Agilent34401Aの動き

電圧の計測

出力バッファへ 計測データを格納

ステータスバイトの メッセージアベイラブル

ビットをチェック

サービスリクエスト発行 ON

OFF

Agilent34401Aの電圧計測時の動き

(16〜61行目:発生したイベントの判別,シリアルポール実行,データ受信)

Agilent34401AからSRQが発行されると、ドライバモジュールは登録されたコールバック関数 (srq_callback)を呼び出します。

コールバック関数の第1引数にはコールバック関数が呼び出されたイベント要因を示す値が、第2 引数にはPciGpibExSetEventMask関数で指定したユーザ定義の値(このプログラムでは、デバイス番 号の値)が引き渡されます。

28行目は、第1引数で渡されたイベント要因が、SRQ割り込みによるものかチェックしています。

30行目のPciGpibExExecSpoll関数は、どのGP-IB機器がSRQを発行したかチェックを行うシリアル

ポールを行っています。SRQを発行したGP-IB機器は、シリアルポールを行った後、第3引数のス テータスバイト中の第6ビット

(リクエストサービスビット)が、必ず1になります。

★PciGpibExExecSpoll関数について

PciGpibExExecSpoll関数によりシリアルポールを行います。PciGpibExExecSpoll関数の第2引数には、

PciGpibExSendData関数と同じように、シリアルポールの対象となる機器のアドレスを、int型(整数型)

の配列で指定します。この第2引数には、複数の機器アドレスが指定できます。配列の終端には必ず-1 を付加してください。

取得したステータスバイトは、第 3 引数で指定する配列に格納され、有効なステータスバイトを持って いた機器のアドレスは、第4引数に格納されます。

GP-IB 機器アドレスが、それぞれ1,2,3の機器が接続されていて、アドレス2の機器からSRQが発行さ

れた場合は、以下のようになります。

呼び出し例>

int ret;

int adrs̲tbl[4] = {1, 2, 3, ‑1}; /* アドレスが 1、2、3 の 3 つの機器を指定します */

int stb̲tbl[4];

int stb̲adrs[4];

ret = PciGpibExExecSpoll(0, adrs̲tbl, stb̲tbl, stb̲adrs);

if(ret == 0){ /* 関数正常終了時 */

    /* アドレス 2 の機器から SRQ が発行されていた場合、配列要素の内容は stb̲tbl[0] = アドレス 2 の機器のステータスバイト

stb̲tbl[1] = ‑1 (終端)

stb̲adrs[0] = 2 (SRQ を発行した機器のアドレス) stb̲adrs[1] = ‑1 (終端)

となります。

    */

}

53行目のPciGpibExRecvData関数は、Agilent34401Aの測定データを受信しています。

58行目の処理は、受信データの最後に終端記号を入れることで、文字列として扱えるようにして

います。