记录自己的开发经验以便日后查看。
环境是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);
}
过程中遇到的问题
- libusb_open失败,返回值为-3。是因为没有权限导致的,直接
sudo chmod -R 777 /dev/bus/usb/
- 具体的端点号,其实就是usb端点描述符的值.可以通过
lsusb -v
查看 - libusb的下载编译移植,在我其他文章有写