【问题标题】:Not able to transfer data through libusb无法通过 libusb 传输数据
【发布时间】:2015-04-03 08:27:58
【问题描述】:

我正在尝试运行此程序以使用 libusb 发送数据。我无法找到我的 USB 端口的端点。 libusb_bulk_transfer 函数中需要此参数。

#include <iostream>
#include <libusb.h>

using namespace std;

int main() {
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
    libusb_device_handle *dev_handle; //a device handle
    libusb_context *ctx = NULL; //a libusb session
    int r; //for return values
    ssize_t cnt; //holding number of devices in list
    r = libusb_init(&ctx); //initialize the library for the session we just declared
    if(r < 0) {
        cout<<"Init Error "<<r<<endl; //there was an error
        return 1;
    }
    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation

    cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
    if(cnt < 0) {
        cout<<"Get Device Error"<<endl; //there was an error
        return 1;
    }
    cout<<cnt<<" Devices in list."<<endl;

    dev_handle = libusb_open_device_with_vid_pid(ctx, 5118, 7424); //these are vendorID and productID I found for my usb device
    if(dev_handle == NULL)
        cout<<"Cannot open device"<<endl;
    else
        cout<<"Device Opened"<<endl;
    libusb_free_device_list(devs, 1); //free the list, unref the devices in it

    unsigned char *data = new unsigned char[4]; //data to write
    data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values

    int actual; //used to find out how many bytes were written
    if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
        cout<<"Kernel Driver Active"<<endl;
        if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
            cout<<"Kernel Driver Detached!"<<endl;
    }
    r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
    if(r < 0) {
        cout<<"Cannot Claim Interface"<<endl;
        return 1;
    }
    cout<<"Claimed Interface"<<endl;

    cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd
    cout<<"Writing Data..."<<endl;
    r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data, 4, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
    if(r == 0 && actual == 4) //we wrote the 4 bytes successfully
        cout<<"Writing Successful!"<<endl;
    else
        cout<<"Write Error"<<endl;

    r = libusb_release_interface(dev_handle, 0); //release the claimed interface
    if(r!=0) {
        cout<<"Cannot Release Interface"<<endl;
        return 1;
    }
    cout<<"Released Interface"<<endl;

    libusb_close(dev_handle); //close the device we opened
    libusb_exit(ctx); //needs to be called to end the

    delete[] data; //delete the allocated memory for data
    return 0;
}

以下是我的主机PC上接收数据的程序。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{

read_port();
//return 0;
}


read_port(void)
{
    int fd = open("/dev/ttyACM0", O_RDONLY | O_NOCTTY);
    if (fd == -1)
    {
    /* Could not open the port. */
    perror("open_port: Unable to open /dev/ttyACM0) - ");
    }

    char buffer[32];
    for(;;)
   {
    int n = read(fd, buffer, sizeof(buffer));
   if (n < 0)
      fputs("read failed!\n", stderr);
   printf("\n %d", n);
  }
}

请帮忙。 提前致谢。

【问题讨论】:

    标签: linux usb endpoint data-transfer libusb


    【解决方案1】:

    在回答您的实际问题时,如果您想了解设备连接了哪些实际端点,lsusb 是您的朋友

    如果您不确定设备的供应商和设备 ID 是什么,请输入:

    lsusb
    

    你会得到这样的东西:

    Bus 001 Device 005: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
    Bus 001 Device 015: ID 413c:2003 Dell Computer Corp. Keyboard
    Bus 001 Device 020: ID 0483:3748 STMicroelectronics ST-LINK/V2
    Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    

    假设我们想知道 ST-LINK/V2 上存在哪些端点,我们使用 -v 选项在详细模式下使用 lsusb,并使用 -d 选项仅指定我们感兴趣的设备编号:

    lsusb -v -d 0483:3748
    

    我们将从这里得到一个很大的字段列表。拓扑大致是:

    device->configuration->interface->endpoints
          |                interface->endpoints
          |                interface->endpoints
          |
          ->configuration->interface->endpoints
                           interface->endpoints
                           ...
    

    所以定位你要使用的接口(常为0):

    • 找到接口描述符

    • 封装在里面你可以看到端点描述符

    • 然后查找术语 bEndpointAddress 以获取实际值

    在这种情况下,我们有一个地址为 0x81 的大容量端点:

    bEndpointAddress     0x81  EP 1 IN
    

    再往下一点:

    bEndpointAddress     0x02  EP 2 OUT
    

    另一个端点:

    bEndpointAddress     0x83  EP 3 IN
    

    为了完整起见,这里是完整的转储:

    总线 001 设备 020:ID 0483:3748 STMicroelectronics ST-LINK/V2

    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               2.00
      bDeviceClass            0 (Defined at Interface level)
      bDeviceSubClass         0 
      bDeviceProtocol         0 
      bMaxPacketSize0        64
      idVendor           0x0483 STMicroelectronics
      idProduct          0x3748 ST-LINK/V2
      bcdDevice            1.00
      iManufacturer           1 STMicroelectronics
      iProduct                2 STM32 STLink
      iSerial                 3 000000000001
      bNumConfigurations      1
        Configuration Descriptor:
          bLength                 9
          bDescriptorType         2
          wTotalLength           39
          bNumInterfaces          1
          bConfigurationValue     1
          iConfiguration          0 
          bmAttributes         0x80
          (Bus Powered)
          MaxPower              100mA
            Interface Descriptor:
               bLength                 9
               bDescriptorType         4
               bInterfaceNumber        0
               bAlternateSetting       0
               bNumEndpoints           3
               bInterfaceClass       255 Vendor Specific Class
               bInterfaceSubClass    255 Vendor Specific Subclass
               bInterfaceProtocol    255 Vendor Specific Protocol
               iInterface              4 ST Link
                 Endpoint Descriptor:
                    bLength                 7
                    bDescriptorType         5
                    bEndpointAddress     0x81  EP 1 IN   *!eg end point address!*
                    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     0x02  EP 2 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     0x83  EP 3 IN
                    bmAttributes            2
                    Transfer Type            Bulk
                    Synch Type               None
                    Usage Type               Data
                    wMaxPacketSize     0x0040  1x 64 bytes
                    bInterval               0
      Device Status:     0x0000
    

    (总线供电)

    【讨论】:

      猜你喜欢
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 2010-11-23
      • 2016-11-12
      • 2021-09-08
      相关资源
      最近更新 更多