Scientific Linux で GPIB を Python 経由で使う

Scientific Linux 5.5 で、National Instruments の NI GPIB-USB-HS を使うための記録。多分、RHEL でも CentOS でも同じやり方でいけるはず。「linux-gpib の設定メモ: PythonでGPIB機器を制御するための環境構築 - 旧”Sei’s Insight @ スタンフォード大学大学院 航空宇宙工学科 in シリコンバレー」を参考にしましたが、Linux が SL5.5 であること、GPIB-USB-B ではなく GPIB-USB-HS を使う点が異なるため、設定が少し違います。

Kernel source が必要なので、yum で入れておきます。

$ sudo yum install kernel-devel

ちゃんと kernel source があることを確認。また、現在起動している kernel と、kernel の revision が対応していることを確認する。yum update した後に再起動しないままやると、kernel の revision が一致しない場合があります。

$ ls /lib/modules/
2.6.18-194.3.1.el5  2.6.18-194.32.1.el5
$ uname -r
2.6.18-194.32.1.el5

Linux GPIB を使うことによって、GPIB を Python で使えるようになります。まずは、ここ (直リン) から linux-gpib-3.2.15.tar.gz を落とします。

$ tar zxvf linux-gpib-3.2.15.tar.gz
$ cd linux-gpib-3.2.15
$ ./configure
$ make

多分、途中で error を吐くはずです。

/home/oxon/sw/linux-gpib-3.2.15/drivers/gpib/agilent_82357a/agilent_82357a.c:24:29: error: linux/semaphore.h: No such file or directory

これは、linux/semaphore.h が無いよということなので、drivers/gpib/agilent_82357a/agilent_82357a.c と drivers/gpib/ni_usb/ni_usb_gpib.c で、

#include <linux/semaphore.h>

#include <asm/semaphore.h>

に書き換えます。

/usr/sbin に PATH が通ってないかもしれないので、先に gpib という group を作っておきます。そうしないと、make install でこける。また、自分を group gpib に追加します。

$ sudo /usr/sbin/groupadd gpib
$ sudo usermod -G gpib oxon

make install。LD_LIBRARY_PATH の設定をしているのは、Python 2.6.6 を /usr/local に入れているためです*1。SL 5.5 に最初から入っている Python 2.4 を使うのであれば、単に make install で良いはずです。

$ sudo LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH make install

次に、/etc/udev/rules.d/99-oxon.rules を編集し*2、以下の行を足します。

# For Linux GPIB
KERNEL=="gpib[0-9]*", MODE="0660", GROUP="gpib"

また、/etc/gpib.conf に以下の内容を書きます。make install したときに置かれる file なので、元の内容を参考にして適宜修正します。正直、全部の変数を理解していないので、もとのままコピペしています。device のほうは、Agilent Technologies の MSO6054A を使うようにしてあります。特に大事なのは、pad (Primary ADdress) だけです。オシロ側で選択して下さい。

interface {
        minor = 0
        board_type = "ni_usb_b"
        name = "NI GPIB-USB-HS"
        pad = 0
        sad = 0
        timeout = T3s
        eos = 0x0a
        set-reos = yes
        set-bin = no
        set-xeos = no
        set-eot = yes
        base = 0
        irq  = 0
        dma  = 0
        master = yes
}

device {
        minor = 0
        name = "MSO6054A"
        pad = 7
        sad = 0
        eos = 0xa
        set-reos = no
        set-bin = no
}

最後に、USB に NI GPIB-USB-HS を接続すれば、/var/log/messages に以下のような log が吐かれるはずです。Linux GPIB の ni_usb_b module が install されました。

Feb  2 18:45:45 localhost kernel: usb 1-1: new high speed USB device using ehci_hcd and address 2
Feb  2 18:45:45 localhost kernel: usb 1-1: configuration #1 chosen from 1 choice
Feb  2 18:45:46 localhost kernel: Linux-GPIB 3.2.15 Driver
Feb  2 18:45:46 localhost kernel: ni_usb_gpib driver loadingni_usb_gpib: probe succeeded for path: usb-0000:02:03.0-1
Feb  2 18:45:46 localhost kernel: usbcore: registered new driver ni_usb_gpib
Feb  2 18:45:46 localhost kernel: gpib: registered ni_usb_b interface

lsmod で確認すると、ni_usb_gpib と gpib_common が存在します。

$ /sbin/lsmod | grep gpib
ni_usb_gpib            63104  0 
gpib_common            67464  1 ni_usb_gpib

そして、root 権限で gpib_config を実行します。

$ sudo gpib_config

/var/log/messages に、以下のような log が出ると思います。

Feb  2 18:46:38 localhost kernel: gpib: (debug) request module returned 256
Feb  2 18:46:38 localhost kernel: ni_usb_gpib: attach
Feb  2 18:46:38 localhost kernel: 	attached to bus interface 0, address 0xffff81002336d000
Feb  2 18:46:39 localhost kernel: 	product id=0x709b
Feb  2 18:46:39 localhost kernel: ni_usb_hs_wait_for_ready: board serial number is 0x130f62a

最後に、Python で通信を確認してみます。

>>> import Gpib
>>> g = Gpib.Gpib("MSO6054A")
>>> g.write("*IDN?")
>>> g.read()
'AGILENT TECHNOLOGIES,MSO6054A,SG48260104,05.25.0000\n'

本当は gpib_config を手動で打たなくても良いなずなのですが、恐らく、SL 5.5 では USB hotplug が動作しない仕様なため、USB 接続時に /etc/hotplug/usb/ni_usb_gpib が実行されません。また、udev rules に gpib_config を走らせるように記述したところ、VMware が途中で死ぬという現象が発生したため、諦めました。

*1:sudo では原則として環境変数が引き継がれるものの、LD_LIBRARY_PATH は引き継がないようになっている。Security のため?

*2:"oxon" の部分は何でもいい。