大白123zz 2021-07-01 11:30 采纳率: 50%
浏览 106
已结题

libusb库使用问题

有一款摄像头,需要用到libusb库。 配置信息如下: vid=525,pid=a4a0,bInterfaceClass=ff,bInterfaceSubClass=f0,bmAttributes=2, bInEndpointAddress=82,bOutEndpointAddress=2,bInterfaceNumber=0 在使用libusb_bulk_transfer函数时,返回出错,返回值为-11;

nt rlen;
unsigned char buf[64];
int len = libusb_bulk_transfer(usb_handle, BULK_SEND_EP, buf, len, &rlen, TRANSFER_TIMEOUT);

请问是什么原因引起的? 不能上传文件:下面是完整的demo

#include "stdio.h"
#include "libusb.h"
#include "usb.h"
#define BULK_RECV_EP    0x82
#define BULK_SEND_EP    0x02
#define INT_RECV_EP     0x81
#define INT_SEND_EP     0x01

#define TRANSFER_TIMEOUT 0

#define PID 0xa4a0
#define VID 0x0525

typedef struct {
    unsigned int pid;
    unsigned int vid;
    unsigned char bInterfaceClass;
    unsigned char bInterfaceSubClass;
    unsigned char bmAttributes;
    unsigned char bInEndpointAddress;
    unsigned char bOutEndpointAddress;
    unsigned char bInterfaceNumber;
    libusb_device *dev;
    libusb_device **devs;
} usb_dev;

static libusb_device_handle* usb_handle;
static usb_dev udev;



/*
    根据PID与VID检查指定设备是否挂载。
*/
static int get_device_descriptor(struct libusb_device_descriptor *dev_desc, usb_dev* user_device)
{
    int rv = -2;
    int i = 0;

    libusb_device **devs;
    libusb_device *dev;
    rv = libusb_get_device_list(NULL, &devs);
    if (rv < 0)
        return rv;

    //遍历USB设备
    /*
    while ((dev = devs[i++]) != NULL) {
        rv = libusb_get_device_descriptor(dev, dev_desc);
        if(rv == 0) {
        }
    }
*/
    i = 0;
    while ((dev = devs[i++]) != NULL) {
        rv = libusb_get_device_descriptor(dev,dev_desc);
        if(rv < 0) {
            //printf("321\n");
            return -1;
        }
        printf("pid=%x,vid=%x\n",dev_desc->idProduct,dev_desc->idVendor);
        if(dev_desc->idProduct == user_device->pid && dev_desc->idVendor == user_device->vid)
        {
            user_device->dev = dev;
            user_device->devs = devs;
            return 0;
        }
    }
    return -2;
}

int match_with_endpoint(const struct libusb_interface_descriptor * interface,usb_dev *user_device)
{
    int i;
    int ret=0;
    printf("bNumEndpoints:%d\n", interface->bNumEndpoints);
    for(i=0; i<interface->bNumEndpoints; i++)
    {     printf("interface->endpoint[i].bmAttributes&0x03:%d,user_device->bmAttributes=%d\n", interface->endpoint[i].bmAttributes&0x03,user_device->bmAttributes);
        if((interface->endpoint[i].bmAttributes&0x03)==user_device->bmAttributes) //transfer type :bulk ,control, interrupt
        {    printf("interface->endpoint[i].bEndpointAddress:%d\n", interface->endpoint[i].bEndpointAddress);
            if(interface->endpoint[i].bEndpointAddress&0x80) //out endpoint & in endpoint
            {
               ret|=1;
               user_device->bInEndpointAddress = interface->endpoint[i].bEndpointAddress;//82
            }
            else
            {
               ret|=2;
               user_device->bOutEndpointAddress = interface->endpoint[i].bEndpointAddress;//02
            }
        }
     }
     if(ret==3)
     {
       return 1;
     }
     else
     {
         return 0;
      }
}
static int get_device_endpoint(struct libusb_device_descriptor *dev_desc, usb_dev* user_device)
{
    int rv = -2;
    int i,j,k;
    struct libusb_config_descriptor *conf_desc;
    unsigned char isFind = 0;
    
    for (i = 0; i < dev_desc->bNumConfigurations; i++)
    {
        if(user_device->dev != NULL)
            rv = libusb_get_config_descriptor(user_device->dev, i, &conf_desc);
        
        if(rv < 0) {
            return -1;
        }
        
        for (j = 0; j < conf_desc->bNumInterfaces; j++)
        {
            for (k=0; k < conf_desc->interface[j].num_altsetting; k++)
            {
                if(conf_desc->interface[j].altsetting[k].bInterfaceClass == user_device->bInterfaceClass)
                {
                    if(match_with_endpoint(&(conf_desc->interface[j].altsetting[k] ), user_device))
                    {
                        user_device->bInterfaceNumber = conf_desc->interface[j].altsetting[k].bInterfaceNumber;
                        libusb_free_config_descriptor(conf_desc);
                        rv = 0;
                        return rv;
                    }
                }
            }
        }
    }
    
    return -2;  //don't find user device
}


int main()
{
    //printf("1111111111\n");

    usb_handle = NULL;

    struct libusb_device_descriptor udev_desc;
    
    //1. load user data.
    udev.pid = PID;
    udev.vid = VID;
    udev.bInterfaceClass = LIBUSB_CLASS_VENDOR_SPEC;// ff 
    udev.bInterfaceSubClass = 0xf0;//f0
    udev.bmAttributes = LIBUSB_TRANSFER_TYPE_BULK;//c0  00  02
    udev.dev = NULL;
  //  //2. init libusb.
    int ret = libusb_init(NULL);
    if(ret < 0)
    {
        return -1;
    }
    //printf("333333333\n");
    //3. search for specified usb device.
    ret = get_device_descriptor(&udev_desc, &udev);
    if(ret < 0) {
        return -2;
    }
    ret = get_device_endpoint(&udev_desc, &udev);
    if(ret < 0) {
        return -3;
    }
    /*4.open device and start communication by usb*/
    //open the usb device
    usb_handle = libusb_open_device_with_vid_pid(NULL, udev.vid, udev.pid);
    if(usb_handle == NULL) {
        return -4;
    }
    ret = libusb_claim_interface(usb_handle, udev.bInterfaceNumber);
    if(ret < 0) {
        ret = libusb_detach_kernel_driver(usb_handle, udev.bInterfaceNumber);
        if(ret < 0) {
            return -5;
        }
        ret = libusb_claim_interface(usb_handle, udev.bInterfaceNumber);
        if(ret < 0)
        {
            return -6;
        }
    }
    printf("vid=%x,pid=%x,bInterfaceClass=%x,bInterfaceSubClass=%x,bmAttributes=%x,bInEndpointAddress=%x,bOutEndpointAddress=%x,bInterfaceNumber=%x\n", 
            udev.vid,udev.pid,udev.bInterfaceClass,udev.bInterfaceSubClass,udev.bmAttributes,udev.bInEndpointAddress,udev.bOutEndpointAddress,udev.bInterfaceNumber);
    //5,通信。
    //接收
    int rlen;
    unsigned char buf[64];
    int len = libusb_bulk_transfer(usb_handle, BULK_SEND_EP, buf, len, &rlen, TRANSFER_TIMEOUT);
    printf("len:%d,buf=%s\n", len,buf);
    //发送
    /*
    printf("88888888\n");
    int wlen;
    unsigned char data[64];
    len = libusb_bulk_transfer(usb_handle, INT_SEND_EP, data, len, &wlen, TRANSFER_TIMEOUT);
    */
    //6,注销
    libusb_close(usb_handle);
    libusb_release_interface(usb_handle, udev.bInterfaceNumber);
    libusb_free_device_list(udev.devs, 1);
    libusb_exit(NULL);
    usb_handle = NULL;
    
    return 0;
}
  • 写回答

1条回答 默认 最新

  • 大白123zz 2021-09-30 09:18
    关注

    已解决

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 10月8日
  • 已采纳回答 9月30日

悬赏问题

  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作