結論
入出力実行(USBデバイスに制御データ・データを送る)前にis_kernel_driver_activeがTrueならdetach_kernel_driverする。
入出力実行後に、usb.util.dispose_resourcesしてからattach_kernel_driver
例。これは手元にあるデバイス用なので、各自適宜変更してください。
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
dev.detach_kernel_driver(intf.bInterfaceNumber)
writes = dev.ctrl_transfer(bmRequestType=0x21,
bRequest=0x09,
wValue=0x0200,
data_or_wLength=[1 << 6])
data = dev.read(endp.bEndpointAddress, 1)
usb.util.dispose_resources(dev)
dev.attach_kernel_driver(intf.bInterfaceNumber)
経緯
djangoつかっていて実際の入出力をしようとすると、
USBError: [Errno 16] Resource busy
と怒られる。kernelが先にドライバーを登録しちゃってるからだそうで、
dev = usb.core.find(idVendor=0xa81, idProduct=0x0701)
(※手元にあるデバイス用なので適宜変更して下さい。)
したときのdevで
cfg = dev[0]
intf = cfg[(0, 0)]
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
dev.detach_kernel_driver(intf.bInterfaceNumber)
をすると動く。
これで解決!
…ならばここに来てないと思う。
1度目はこれで動くのだが、2度目のurlリクエストでは、is_kernel_driver_activeもFalseなのに
USBError: [Errno 16] Resource busy
って怒られる。1回目の処理のインスタンスでくわえ込んだままになってる?
でわ、各自入出力した後は一旦kernelに戻してやればよいではないか!
入出力実行した後で detach_kernel_driver()である!
しかしなぜかこれも怒られる。
USBError: [Errno 16] Resource busy
どうも自分自身でもで実行したら実行した後も続けて実行するときのために
PyUSB内部でくわえこんでるようなのである。それがattach/detachを妨げる。
そこで、探してきたのが
usb.util.dispose_resources(dev)
PyUSBがくわえこんでるのを一旦開放しちゃう!
すると、
dev.attach_kernel_driver(intf.bInterfaceNumber)
が成功するようになる。
次回また実行してもうまくいく。
なお、別プログラム(別プロセス)でPyUSBしてる時に自分のところでも同じデバイスに対してPyUSB入出力すると
USBError: [Errno 16] Resource busy
になる。
テスト時等には注意されたし。