1
0

More than 3 years have passed since last update.

PyUSB USBError: [Errno 16] Resource busy への対処療法かもしれないメモ

Last updated at Posted at 2021-09-05

結論

入出力実行(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

になる。
テスト時等には注意されたし。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0