4

USB デバイスと通信してデータを送信したい。デバイスを見つけることができますが、デバイスをカーネルドライバーに接続しているときにUSB Error: Resource Busy. 以下は私のコードです:

import usb

dev = usb.core.find(idVendor=0x0403, idProduct=0x6001)
dev.set_configuration()

cfg = dev.get_active_configuration()

dev.attach_kernel_driver(interface)

interface_number = cfg[(0, 0)].bInterfaceNumber
alternate_settting = usb.control.get_interface(interface_number)
intf = usb.util.find_descriptor(
    cfg, bInterfaceNumber=interface_number,
    bAlternateSetting=alternate_setting)

ep = usb.util.find_descriptor(
    intf, custom_match=lambda e:
    usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT)

dev.detach_kernel_driver(interface)

ep.write("\r" + linea1[:19] + "\n\r" + " " * (20 - len(linea2)) + linea2)
4

1 に答える 1

7

Linux をのバックエンド ライブラリlibusb-1.0として使用していると仮定します。PyUSB

libusbのドキュメントによると:

// Detach a kernel driver from an interface.
// If successful, you will then be able to claim the interface and perform I/O.
int libusb_detach_kernel_driver (libusb_device_handle *dev, 
                                 int interface_number)  

// Re-attach an interface's kernel driver, which was previously 
// detached using libusb_detach_kernel_driver().
int libusb_attach_kernel_driver(libusb_device_handle *dev,
                                int interface_number)

したがって、基本的には、detach_kernel_driver 最初に呼び出して、既に接続されているカーネル ドライバー (存在する場合) をデバイスのインターフェイスから切り離す必要があります。これにより、コードでそれと通信できます (コードまたはデバイスのインターフェイスと通信するカーネル ドライバーのいずれかです)。完了したら、呼び出しattach_kernel_driverてカーネル ドライバーを再度アタッチすることをお勧めします。

特定のデバイスに対してカーネルドライバーがロードされていないことを確認できる場合 (またはコードを実行する前に手動でアンロードする場合)、これらの C 関数/Python メソッドを呼び出す必要はないと思います。

編集:

このコード(サンプルに基づく)が機能するようになりました。detach_kernel_driver注: 簡単にするために、 andのインターフェイス番号として 0 をハードコーディングしましたattach_kernel_driver。よりスマートにする必要があると思います。

import usb

dev = usb.core.find(idVendor=0x0403, idProduct=0x6001)

reattach = False
if dev.is_kernel_driver_active(0):
    reattach = True
    dev.detach_kernel_driver(0)

dev.set_configuration() 
cfg = dev.get_active_configuration() 

interface_number = cfg[(0,0)].bInterfaceNumber 
alternate_settting = usb.control.get_interface(dev, interface_number) 
intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number, 
                            bAlternateSetting = alternate_settting) 

ep = usb.util.find_descriptor(intf,custom_match = \
      lambda e: \
    usb.util.endpoint_direction(e.bEndpointAddress) == \
    usb.util.ENDPOINT_OUT) 
ep.write("test\n\r")

# This is needed to release interface, otherwise attach_kernel_driver fails 
# due to "Resource busy"
usb.util.dispose_resources(dev)

# It may raise USBError if there's e.g. no kernel driver loaded at all
if reattach:
    dev.attach_kernel_driver(0) 
于 2012-09-22T10:59:01.853 に答える