LINUX.ORG.RU

libusb


0

1

Доброго времени суток. INTRO

Работаю под Ubuntu 11.04 (ядро 2.6.35-28-generic-pae ). Пишу программу, в функционал которой входит работа с USB устройством. В первых версиях программы использовалась libusb-0.1-4. Тогда я столкнулся с 2 проблемами: 1) Мое устройство по умолчанию захватывал HID драйвер. Приходилось «отсоединять» устройство при помощи «usb_detach_kernel_driver_np», а для этого нужно было запускать программу от имени суперпользователя. 2) После завершения программы, libusb не освобождала интерфейс( т.е. usb_release_interface не отрабатывала). В результате, приходилось вынимать устройство из USB порта и подключать обратно. Код был перенесен под windows. Никаких проблем не возникло. В интернет рекомендовали перейти на libusb-1.0, не совместимую с предыдущей версией. После перехода на новую библиотеку проблемы не решились(((.

Я написал тестовую программу:

==========================================================================

#include <stdio.h>
#include <libusb-1.0/libusb.h>

#define TIMEOUT 500

int main( int argc, char **argv)
{
    int i=0,
        rv=0,
        bTransfer=0;

    unsigned short VID = 0xXXXX; //vendor id
    unsigned short PID = 0xXXXX; //product id
    unsigned char EP_out = 0x82; // write into usb  end point
    unsigned char EP_in  = 0x01; // read from usb end point

    unsigned char TX[] = {0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}; //reqwest
    unsigned char RX[521]; //answer

    struct libusb_device_descriptor desc; //description of device structure

    libusb_device_handle *dev_handle = NULL;   //a device handle
    libusb_context       *ctx = NULL;           //a libusb session
    libusb_device        *dev = NULL;          //pointer to device
    libusb_device        **devs = NULL;        //pointer to pointer of device


    //init libusb
    libusb_init(ctx);

    // get device list
    rv = libusb_get_device_list( ctx, &devs); //get the list of devices
    printf("Number of devices: %d\n",rv);

    //get need device descriptor and number
    while ((dev = devs[i++]) != NULL) //take all connected device one by one
    {
        rv = libusb_get_device_descriptor(dev, &desc); // look in deckritption of current device
        if(rv == 0)
            printf("\tGet descriptor of device\n");

        //test device vendor and product identify
        if( desc.idVendor == VID && desc.idProduct == PID ) // if VID & PID is positive
        {
            // open device
            rv = libusb_open(dev, &dev_handle);
            if(rv == 0)
            printf("Open my device\n");
            break;
        }
    }

    // free device list
    libusb_free_device_list(devs, 1);

    // test to enable device
    if ( dev_handle == NULL )
    {
        printf("Not device found\n");

        //exit work with usb
        libusb_exit(ctx);
            printf("Exit libusb\n");

        return 0;
    }

    // test to device to grubed by kernel
    if(libusb_kernel_driver_active(dev_handle, 0) == 1)
        if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
            printf("Detach device\n");

    // config  device
        rv = libusb_set_configuration(dev_handle, 1);
        if(rv == 0)
            printf("Set configuration\n");

    // claim interface
        rv = libusb_claim_interface(dev_handle, 0);
        if( rv == 0 )
            printf("Claim 0 interface\n");

    // send data block to device
    rv = libusb_bulk_transfer(dev_handle, EP_in, TX, sizeof(TX), &bTransfer, TIMEOUT);
    printf("Write to device.\n\tReturn value = %d\n\tSend bytes = %d\n",rv,bTransfer);

    // read answer
    rv = libusb_bulk_transfer(dev_handle, EP_out, RX, sizeof(RX), &bTransfer, TIMEOUT);
    printf("Read from device.\n\tReturn value = %d\n\tAccept bytes = %d\n",rv,bTransfer);

    //release the claimed interface
    rv = libusb_release_interface(dev_handle, 0);
    if( rv == 0 )
        printf("Release 0 interface\n");

    // close usb device
    libusb_close(dev_handle);
        printf("Close device\n");

    //exit work with usb
    libusb_exit(ctx);
        printf("Exit libusb\n");

    //erase dev_handle
    dev_handle = NULL;

    return 0;
}

==========================================================================

Результаты ее работы: 1 запуск

Number of devices: 7
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
Open my device
Detach device
Set configuration
Claim 0 interface
Write to device.
    Return value = 0
    Send bytes = 8
Read from device.
    Return value = 0
    Accept bytes = 521
Release 0 interface
Close device
Exit libusb

2 запуск

Number of devices: 7
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
    Get descriptor of device
Open my device
Set configuration
Claim 0 interface
Write to device.
    Return value = 0
    Send bytes = 8
Read from device.
    Return value = -7
    Accept bytes = 0
Release 0 interface
Close device
Exit libusb

Ошибка, которую возвращает функции передачи - превышено время ожидания. Подскажите в чем дело? Спасибо.

lsusb выдает следующее:

Bus 004 Device 028: ID XXXX:XXXX  
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            2 Communications
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0xXXXX 
  idProduct          0xXXXX 
  bcdDevice            1.10
  iManufacturer           0 
  iProduct                0 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           67
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      0 None
      iInterface              0 
      CDC Header:
        bcdCDC               1.10
      CDC ACM:
        bmCapabilities       0x00
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      CDC Call Management:
        bmCapabilities       0x00
        bDataInterface          1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0xXX  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0xXX  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0xXX  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
cossette ()

Это ж модем, зачем с ним работать через usb, стандартный драйвер cdc не подходит?

А ошибка похоже просто говорит о том, что никаких данных за TIMEOUT не пришло, вроде бы и не ошибка совсем, а просто устройство не отвечает (но могу ошибаться, с libusb не работал, как-то через ioctl обычно). Так что дело вряд ли здесь в libusb, скорее в том, как правильно работать с устройством. Но если есть сомнения - usbmon в помощь.

vga ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.