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

RTLinuxモジュールの動き

第 4 章  より高度な処理を行おう 37

4.4  複数のGP-IB機器を制御するプログラムの解説

4.4.1  RTLinuxモジュールの動き

RTLinuxモジュール(pm_transtask.o)は、Linuxプロセスからの作業依頼に従って、ドライバを使っ

てデータの送受信を行います。

(262〜348行目:RT-FIFO,RTLinuxスレッドの生成やドライバの初期化)

RTLinuxモジュールが組み込まれる時、最初に262行から始まるinit_module関数が呼び出されます。

ここでは、RT-FIFOやRTLinuxスレッド,ハンドラ等のリソースを生成しています。

項  目  内  容 

RT-FIFO(FIFO_COMMAND) 272行目のrtf_create関数>

Linuxプロセスからの指示を受けるためのRT-FIFOです。指示

は、ハンドラmy_handlerに渡されます。

RT-FIFO(FIFO_HP_THRU_CMD) 277行目のrtf_create関数>

ハンドラにて、Linuxプロセスから受け取った情報を、HP用ス レッド(hp34401a_task)に渡すためのRT-FIFOです。

RT-FIFO(FIFO_YK_THRU_CMD) 285行目のrtf_create関数>

ハンドラにて、Linuxプロセスから受け取った情報を、YK用ス レッド(yk7561_task)に渡すためのRT-FIFOです。

RT-FIFO(FIFO_HP_RESULT) 281行目のrtf_create関数>

HP用スレッドにて受け取ったAgilent34401Aからの電圧値を Linuxプロセスに渡すためのRT-FIFOです。

RT-FIFO(FIFO_YK_RESULT) 289行目のrtf_create関数>

コールバック関数(srq_callback関数)にて受け取った

YOKOGAWA 7561からの電圧値をLinuxプロセスに渡すための

RT-FIFOです。

項  目  内  容  ミューテックス(sync_obj) 340行目のpthread_mutex_init関数>

GP-IBのバスの占有に対する同期をとるための同期オブジェク

トです。

ハンドラ(my_handler) 273行目のrtf_create_handler関数>

Linuxプロセスからの指示を受け取るための処理の入り口です。

RT-FIFO経由で送られた情報は、一旦このハンドラが受け取り、

然る処理に回されます。

Agilent用スレッド (hp34401a_task)

343行目のpthread_create関数>

Agilent34401Aに対する周期的なデータ送受信処理を実行する RTLinuxスレッドです。

Linuxプロセスから送られるAgilent34401Aに対する指示は、最

終的にここに送られ、送受信処理を行います。

YK用スレッド (yk7561_task)

347行目のpthread_create関数>

YOKOGAWA 7561に対するオートサンプリング開始/停止を実

行するRTLinuxスレッドです。

Linux

プロセスから送られるYOKOGAWA 7561に対する指示

は、最終的にここに送られ、オートサンプリングの開始/停止を 行います。

★ミューテックス

ミューテックスとは、同期オブジェクトのひとつで、相互排除(MUTual EXclusion)を意味します。

GP-IB は、ひとつの処理を行っている途中で、さらに別の処理を並行して行うことはできません。それ

は、GP-IB 1 本のバスであるため、ひとつの処理でバスを占有されてしまうからです。つまり、ある 機器に対して送信処理を行っているときに、別の機器に対する受信処理を行ったりすることはできない ことになります。

ここでの複数機器の制御では、SRQイベントからデータ受信を行っていますが、いつSRQイベントが発 生するかは分かりません。そのため、Agilent34401Aに対して、データ送信やデータ受信を行っていると

きに、YOKOGAWA7561からSRQイベントが発生するかもしれません。その場合、すでにAgilent34401A

に対する処理でバスが占有されているため、YOKOGAWA7561に対する処理が行えなくなってしまいま す。

こういった場合、Agilent34401Aに対する処理が終わるのを待って(同期をとって)、YOKOGAWA7561 処理を行えばよいことになります。そこで使用するのが、このミューテックスです。ミューテックスは、

何かの処理を行う前にロックしておき、処理が終わればアンロックするというふうに使用します。すで にロックしているミューテックスを別のスレッドがロックしようとすると、すでにロックされているミ ューテックスがアンロックされるまで待つようになります。

こうすることにより、1本のバスを同時に使用することなく処理を行えます。

★pthread_mutex_init関数

pthread_mutex_init関数はミューテックスの初期化を行います。第1引数にはミューテックス変数へのポ

インタ、第2引数にはミューテックスの属性を指定します。ここではデフォルトの属性を使用するため、

0を指定しています。

292〜304行では、受信バッファの確保を行っています。

recv_buff_size変数の値に従い、vmalloc関数を用いて動的にバッファを確保しています。

バッファは、Agilent34401Aの受信バッファ(hp_recv_buff)と、YOKOGAWA 7561の受信バッファ

(yk_recv_buff)の2つが確保されます。

307〜327行目は、 I/Oモジュールの初期化(307行目のPciGpibExInitBoard関数),IFCの送出(316行目の PciGpibExSetIfc関数),RENの設定(323行目のPciGpibExSetRen関数)を行っています。これは定型的

な処理です。

330行目は、PciGpibExSetEventMask関数により、コールバック関数の登録とイベントマスクの設

定を行います。ここでは、

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

GPIB_DETECT_SRQを指定しています。

(238〜257行目:ハンドラの処理)

ハンドラ(my_handler)の役目は、

LinuxプロセスからRT-FIFOを経由して送られる指示を、 Agilen用

スレッド(hp34401a_task)およびYK用スレッド(yk7561_task)に渡すことにあります。

指令の振り分けの判別は、CMD_STRUCT構造体のtypeメンバ変数の値により行います。

FIFO_COMAND

ハンドラ(my_handler) 指令  Linuxプロセス

RTLinuxスレッド Agilent用スレッド

RTLinuxスレッド YK用スレッド FIFO_YK_THRU_CMD FIFO_HP_THRU_CMD

LinuxプロセスからRTLinuxスレッドへのデータの流れ

(110〜178行目: Agilent34401Aに対するデータ送受信の処理)

Agilent34401Aに対するデータ送受信処理は、110行目からのhp34401a_task関数にて行われます。

処理の流れは、先のList4-2 pt_transtask.cのtrans_task関数の処理と、ほぼ同じです。

違いは、データの送受信を行うドライバモジュールのAPIを呼び出す際に、ミューテックスオブジ ェクトのロック/アンロックを行っている点です。

これにより、複数のスレッドが同時にドライバモジュールのAPIを呼び出してしまわないように、

同期処理を行っています。

pthread̲mutex̲lock(&sync̲obj);

pthread̲mutex̲unlock(&sync̲obj);

ドライバモジュールのAPI呼び出し処理

←ロック処理

←アンロック処理

サンドイッチのように挟んでいる

★pthread_mutex_lock関数,pthread_mutex_unlock関数

ミューテックスをロックする場合は pthread_mutex_lock 関数,ミューテックスをアンロックする場合は

pthread_mutex_unlock関数を使用します。どちらも、引数にはミューテックス変数へのポインタを指定し

ます。

(181〜227行目:YOKOGAWA 7561に対するデータ送受信の開始/停止処理)

YOKOGAWA 7561に対するデータ送受信は、 Agilent34401Aと異なり、計測完了時に発生するSRQ

イベントを用いて行っています。

電圧の計測は、YOKOGAWA 7561内で定周期で行われるよう設定されているため、一定時間ごと に電圧計測が行われ、SRQが発行されます。

181行からのyk7561_task関数は、この計測処理の開始と停止を行うRTLinuxスレッドです。

処理の決定は、CMD_IDS列挙体の定数値により決定されます。

列挙定数値  内  容 

ID_START

204行目のsend_data関数で送るデータ"F1R0M0SI1000MS1"により、YOKOGAWA 7561に対して500ms周期ごとに、電圧計測を行うよう指示を出します。

ID_STOP

217行目のsend_data関数で送るデータ"MS0"により、YOKOGAWA 7561に対して 電圧計測を停止するよう指示を出します。

ID_STARTの設定により、YOKOGAWA 7561は一定周期ごとに電圧を計測し、計測が完了すると SRQを発行します。

(26〜85行目:SRQイベントの処理)

26行からのsrq_callback関数は、GP-IB機器からSRQが発行された際、ドライバモジュールが検知し、プ

ログラムに通知するために呼び出されるコールバック関数です。

処理の流れを以下に示します。

37行目のif文でコールバック関数が呼び出されたイベント要因がSRQによるものかチェックしていま す。

41行目のPciGpibExExecSpoll関数でシリアルポールを行い、どのGP-IB機器がSRQを発行したのか チェックを行っています。

63行目のif文で、SRQを発行したGP-IB機器がYOKOGAWA 7561であるか?と、SRQの発生要因が電圧 計測によるものかチェックしています。

stb_adrs配列変数にてGP-IB機器のチェックを行い、stb_tbl配列変数にてSRQの発生要因をチェックして

います。

チェックに成功すれば、66行目のPciGpibExRecvData関数でYOKOGAWA 7561から計測したデータを取 得しています。

77行目のrtf_put関数で、取得したデータをRT-FIFOを使ってLinuxプロセスに送っています。