2015-04-03 58 views
0

我试图运行该程序使用libusb发送数据。我无法找到我的USB端口的端点。该参数在libusb_bulk_transfer函数中是必需的。无法通过libusb传输数据

#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; 
} 

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

#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); 
    } 
} 

请帮忙。 在此先感谢。

回答

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,我们使用的的lsusb verbo使用SE模式-v选项,并指定只有我们感兴趣的是与该ID -d选项设备:

lsusb -v -d 0483:3748 

我们会得到这个领域的大名单。拓扑结构大致是:

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

所以找到你想使用(通常0)接口:

  • 定位接口描述

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

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

在这种情况下,我们在终点批量使用的0×81地址:

bEndpointAddress  0x81 EP 1 IN 

而另还有更远:

bEndpointAddress  0x02 EP 2 OUT 

而另一端点:

bEndpointAddress  0x83 EP 3 IN 

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

总线001的设备020:ID 0483:3748意法半导体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 

(总线供电)