使用libusb读写scsi设备

记录自己的开发经验以便日后查看。

环境是ubuntu18.04,libusb是c库,理论任何平台都可以使用。代码中很多不严谨的地方,例子仅仅是可以读写设备。

函数实现



#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <libusb.h>
#include <string.h>

#define VID 0X0945
#define PID 0X0677

static libusb_device *  find_mydevice(libusb_device **list)
{
        int i = 0;

        libusb_device *my_device =NULL;
        //while(list[i++] != NULL)
        while ((my_device = list[i++]) != NULL)
        {
                struct libusb_device_descriptor desc;
                //my_device = list[i];
                int err = libusb_get_device_descriptor(my_device, &desc);
                if(err <0)
                {
                        printf("get_descriptor_err_code = %d\n",err);
                        return NULL;
                }
                printf("vid = %04x  pid = %04x\n",desc.idVendor,desc.idProduct);
                if((desc.idVendor == VID) && (desc.idProduct == PID))
                {
                        return my_device;
                }
                if(i > 50)
                        break;
        }
        return NULL;
}
int main ()
{
        libusb_context *usb_context = NULL;
        libusb_device **dev_list;
        libusb_device *mydevice;
        struct libusb_device_descriptor desc;
        libusb_device_handle *dev_handle = NULL;
        struct libusb_config_descriptor *config_descriptor_in = NULL, *config_descriptor_out = NULL;
        unsigned char data[200] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
                                   0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
                                   0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88
                                   ,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
                                   0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
                                   0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};

        unsigned char* send_data;
        unsigned char* recv_data;

        int err = -1;
        int config = 0,length,i;

        if(err = libusb_init(&usb_context)<0)
        {
                printf("init_code = %d",err);
                exit(1);
        }
        if(err = libusb_get_device_list(usb_context,&dev_list)<0)
        {
                printf("get_list_err = %d",err);
                libusb_exit(usb_context);
                exit(1);
        }
        //找到指定vid  pid设备,这里也可以用libusb_open_device_with_vid_pid函数代替
        mydevice = find_mydevice(dev_list);
		//获得libusb_device_handle
        err = libusb_open(mydevice,&dev_handle);
        if(dev_handle == NULL)
        {
                printf("dev_open_err = %d\n",err);
                libusb_free_device_list(dev_list, 1);
                libusb_exit(usb_context);
                exit(1);
        }
        //查看指定接口的内核驱动程序是否已经激活
        err = libusb_kernel_driver_active(dev_handle, 0);
        if (err == 1)
        {	
        		//如果激活了,那就卸载掉(不卸载掉libusb_claim_interface函数无法成功)
                libusb_detach_kernel_driver(dev_handle, 0);
                printf("Uninstall_driver\n");
        }
        //声明接口
        if (err = libusb_claim_interface(dev_handle, 0) < 0)
        {
                printf("claim interface error:%d\n",err);
                libusb_free_device_list(dev_list, 1);
                libusb_exit(usb_context);
                exit(1);
        }
		
        libusb_get_configuration(dev_handle, &config);
		
		//获取端点描述符(可省)
        libusb_get_config_descriptor(mydevice, 0, &config_descriptor_in);
        libusb_get_config_descriptor(mydevice, 1, &config_descriptor_out);

        send_data = malloc(2048);
        recv_data = malloc(2048);
        memmove(send_data,data,0x85);
        if (config_descriptor_in)
        {
        		//发送数据,第二个参数为端点地址
        		libusb_bulk_transfer(dev_handle, 0x04,ucData, uiLen, &length, 0);
        		//接收数据
                libusb_bulk_transfer(dev_handle, 0x83,ucData, uiLen, &length, 0);
      
        }
        else
        {
                printf("get config_descriptor error\n");
        }

        free(send_data);
        free(recv_data);
        libusb_attach_kernel_driver(dev_handle, 0);
        libusb_free_device_list(dev_list,1);
        libusb_exit(usb_context);
}

过程中遇到的问题

  1. libusb_open失败,返回值为-3。是因为没有权限导致的,直接sudo chmod -R 777 /dev/bus/usb/
  2. 具体的端点号,其实就是usb端点描述符的值.可以通过lsusb -v查看
  3. libusb的下载编译移植,在我其他文章有写
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值