20120216

detach_kernel_driverしまくってやればset_configurationが上手くいく



久々に真面目な話。
現在進行中の作業を公にすれば途中で投げ出すこともなかろうと。
それと、作業中にリファレンスが少なくてうがぁぁぁぁ!!となったので、このログが誰かの参考になれば幸い。


ここ最近、新しい実験システムの構築に取り組んでおります。
”出来るだけ安く”を目標にUbuntu+Pythonで作ろうとしているのですが、データ取り込み・A/Dコンバータ操作でハマり気味。
因みに現在はWindows XP+MATLABで実験しています。
MATLABなんて大体の研究室にあるんじゃないの?なんて考えていますが、今後それのない研究室にも移ることの出来るように、先にフリーのプログラミング環境であるPythonの勉強をしておこうかと。
それと趣味。
まあいくら金をかけたくなくてもPCだったり、アンプだったり、モニタだったり、今詰まってるA/Dコンバータだったりは必要なわけですが。
そもそも、今後移る先が電気生理の研究室では無い可能性もありますが。
そんな時でも、どんな時でも、出来る事は多いに越したことはあるまい。


さて本題。
開発環境はUbuntu 11.10 64bit。
使用するA/DコンバータはMeasurement Computing USB-1608FS
USB接続のこいつには公式のUbuntu(というかLinux)用ドライバが存在しないので、PythonからUSBを操作するPyUSBを用いて

import usb
USB1608FS = usb.core.find(idVendor = 0x09db, idProduct = 0x007d)
USB1608FS.set_configuration()

なんてやるとまずはPermission Deniedになりましたので、/etc/udev/rules.d/に中身が以下の60-mcc-usb1608fs.rulesなるファイルを作ってやりました。

BUS=="usb", SYSFS{idVendor}=="09db", SYSFS{idProduct}=="007d", MODE="0666"

Measurement Computing社(SYSFS{idVendor}=="09db")のUSB規格(BUS=="usb")のUSB-1608FS(SYSFS{idProduct}=="007d")が接続されたら、そいつの読み書きを許可(MODE="0666")しますよ、ということらしいです。
この会社の装置用の、Linux向けドライバを作ってるところ(ココ)を参考、というか必要部分だけをわざわざ抜き出しただけなのであまり理解出来ておりません。
まあでも一応こういうサイトは読みました。
SYSFS{idVendor}=="09db", SYSFS{idProduct}=="007d"だけで装置は一意に定まるのでBUS=="usb"は不要な気はしますが試していません。

さて、このファイルを作ったらTerminalで

/sbin/udevadm control --reload-rules

をやって、rulesファイルを読み込ませてやって、再度

import usb
USB1608FS = usb.core.find(idVendor = 0x09db, idProduct = 0x007d)
USB1608FS.set_configuration()

で今度は

USBError: Resource busy

と言われ、数日ハマってしまいました。
ググッてみるとdetach_kernel_driver()すればいいということは分かったのですが、引数がよく分からない。
interfaceってそれなんぞや?
とりあえず適当に0を入れてみたら

USB1608FS.detach_kernel_driver(0)

回りはしたのですが、それでも依然Resource Busy。
set_configuration()と同じ引数(装置依存のbConfigurationValueなる値、USB-1608FSの場合は1だが、指定しなければ内部で適当な値を見繕ってくれる)を入れて回してもResource Busy。

じゃあ色々な値を引数に取り得るので、片っ端からdetachしてやろうじゃないかと。

for i in range(100):
    if USB1608FS.is_kernel_driver_active(i):
        USB1608FS.detach_kernel_driver(i)

0-99の引数でdetach。
この値のレンジに特別意味はありません。
if USB1608FS.is_kernel_driver_active(i):で元々detachされてる数字は除外。
これでResource Busyにならなくなりました!
因みに、どの引数でdetachされるのかを見るためにprint iをつけてみると

0
1
2
3
4
5
6

が出力されましたので、forループはrange(7)で良さ気?
そもそも、この中のどの値のせいでResource Busyだったのかは調べていません。
たぶんどれか一つでいいのでしょうね〜

さて、これで早速記録可能か!?と喜びも束の間、なかなか先に進めずにまたもや数日ハマっているのが現在の状況です…
うがぁぁぁぁ!!

No comments:

Post a Comment