通libusb我们可以在应用层对USB设备进行读写操作。本文以读取USB鼠标数据为例讲述libusb的使用流程。

通过源码安装libusb:

最新的版本为:libusb-1.0.24,GitHub上免费下载地址:

https://github.com/libusb/libusb/releases/tag/v1.0.24

ps: CSDN上很多人用这个公共的开源资源来赚积分,而且下载分还贼高,真不怎么地道。

解压源码:tar xjvf libusb-1.0.24.tar.bz2

在解压跟目录下输入命令:

./configure

注意:如果报以下错误

configure: error: udev support requested but libudev header not installed

不要慌,这是由于没安装libudev库,可以通过以下方式解决:

1、输入命令apt-get install libudev-dev安装libudev

2、运行configure脚本时输入:./configure  --disable-udev(这种方法本人还没验证)

编译:make

安装:make install

默认安装在/usr/local/lib目录下

以上是源码编译安装流程,在线通过以下命令安装也很简单:

a、apt-get install libudev-dev

b、apt-get install libusb-dev

c、apt-get install libusb-1.0-0-dev

安装完libusb库后就可以开发应用层程序对USB设备进行读写操作了,下面是参考libusb例子中的testlibusb.c文件编写的鼠标数据读取程序test_rw.c:

​
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <getopt.h>
#include <ctype.h>
#include <signal.h>#include "libusb.h"int verbose = 1;static volatile sig_atomic_t rcv_exit;static void print_endpoint_comp(const struct libusb_ss_endpoint_companion_descriptor *ep_comp)
{printf("      USB 3.0 Endpoint Companion:\n");printf("        bMaxBurst:           %u\n", ep_comp->bMaxBurst);printf("        bmAttributes:        %02xh\n", ep_comp->bmAttributes);printf("        wBytesPerInterval:   %u\n", ep_comp->wBytesPerInterval);
}static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint)
{int i, ret;printf("      Endpoint:\n");printf("        bEndpointAddress:    %02xh\n", endpoint->bEndpointAddress);printf("        bmAttributes:        %02xh\n", endpoint->bmAttributes);printf("        wMaxPacketSize:      %u\n", endpoint->wMaxPacketSize);printf("        bInterval:           %u\n", endpoint->bInterval);printf("        bRefresh:            %u\n", endpoint->bRefresh);printf("        bSynchAddress:       %u\n", endpoint->bSynchAddress);for (i = 0; i < endpoint->extra_length;) {if (LIBUSB_DT_SS_ENDPOINT_COMPANION == endpoint->extra[i + 1]) {struct libusb_ss_endpoint_companion_descriptor *ep_comp;ret = libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);if (LIBUSB_SUCCESS != ret)continue;print_endpoint_comp(ep_comp);libusb_free_ss_endpoint_companion_descriptor(ep_comp);}i += endpoint->extra[i];}
}static void print_altsetting(const struct libusb_interface_descriptor *interface)
{uint8_t i;printf("    Interface:\n");printf("      bInterfaceNumber:      %u\n", interface->bInterfaceNumber);printf("      bAlternateSetting:     %u\n", interface->bAlternateSetting);printf("      bNumEndpoints:         %u\n", interface->bNumEndpoints);printf("      bInterfaceClass:       %u\n", interface->bInterfaceClass);printf("      bInterfaceSubClass:    %u\n", interface->bInterfaceSubClass);printf("      bInterfaceProtocol:    %u\n", interface->bInterfaceProtocol);printf("      iInterface:            %u\n", interface->iInterface);for (i = 0; i < interface->bNumEndpoints; i++)print_endpoint(&interface->endpoint[i]);
}static void print_2_0_ext_cap(struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext_cap)
{printf("    USB 2.0 Extension Capabilities:\n");printf("      bDevCapabilityType:    %u\n", usb_2_0_ext_cap->bDevCapabilityType);printf("      bmAttributes:          %08xh\n", usb_2_0_ext_cap->bmAttributes);
}static void print_ss_usb_cap(struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap)
{printf("    USB 3.0 Capabilities:\n");printf("      bDevCapabilityType:    %u\n", ss_usb_cap->bDevCapabilityType);printf("      bmAttributes:          %02xh\n", ss_usb_cap->bmAttributes);printf("      wSpeedSupported:       %u\n", ss_usb_cap->wSpeedSupported);printf("      bFunctionalitySupport: %u\n", ss_usb_cap->bFunctionalitySupport);printf("      bU1devExitLat:         %u\n", ss_usb_cap->bU1DevExitLat);printf("      bU2devExitLat:         %u\n", ss_usb_cap->bU2DevExitLat);
}static void print_bos(libusb_device_handle *handle)
{struct libusb_bos_descriptor *bos;uint8_t i;int ret;ret = libusb_get_bos_descriptor(handle, &bos);if (ret < 0)return;printf("  Binary Object Store (BOS):\n");printf("    wTotalLength:            %u\n", bos->wTotalLength);printf("    bNumDeviceCaps:          %u\n", bos->bNumDeviceCaps);for (i = 0; i < bos->bNumDeviceCaps; i++) {struct libusb_bos_dev_capability_descriptor *dev_cap = bos->dev_capability[i];if (dev_cap->bDevCapabilityType == LIBUSB_BT_USB_2_0_EXTENSION) {struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension;ret = libusb_get_usb_2_0_extension_descriptor(NULL, dev_cap, &usb_2_0_extension);if (ret < 0)return;print_2_0_ext_cap(usb_2_0_extension);libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension);} else if (dev_cap->bDevCapabilityType == LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {struct libusb_ss_usb_device_capability_descriptor *ss_dev_cap;ret = libusb_get_ss_usb_device_capability_descriptor(NULL, dev_cap, &ss_dev_cap);if (ret < 0)return;print_ss_usb_cap(ss_dev_cap);libusb_free_ss_usb_device_capability_descriptor(ss_dev_cap);}}libusb_free_bos_descriptor(bos);
}static void print_interface(const struct libusb_interface *interface)
{int i;for (i = 0; i < interface->num_altsetting; i++)print_altsetting(&interface->altsetting[i]);
}static void print_configuration(struct libusb_config_descriptor *config)
{uint8_t i;printf("  Configuration:\n");printf("    wTotalLength:            %u\n", config->wTotalLength);printf("    bNumInterfaces:          %u\n", config->bNumInterfaces);printf("    bConfigurationValue:     %u\n", config->bConfigurationValue);printf("    iConfiguration:          %u\n", config->iConfiguration);printf("    bmAttributes:            %02xh\n", config->bmAttributes);printf("    MaxPower:                %u\n", config->MaxPower);for (i = 0; i < config->bNumInterfaces; i++)print_interface(&config->interface[i]);
}static void print_device(libusb_device *dev, libusb_device_handle *handle, uint16_t vid, uint16_t pid)
{struct libusb_device_descriptor desc;unsigned char string[256];const char *speed;int ret;uint8_t i;switch (libusb_get_device_speed(dev)) {case LIBUSB_SPEED_LOW:       speed = "1.5M"; break;case LIBUSB_SPEED_FULL:        speed = "12M"; break;case LIBUSB_SPEED_HIGH:     speed = "480M"; break;case LIBUSB_SPEED_SUPER:   speed = "5G"; break;case LIBUSB_SPEED_SUPER_PLUS:    speed = "10G"; break;default:            speed = "Unknown";}ret = libusb_get_device_descriptor(dev, &desc);if (ret < 0) {fprintf(stderr, "failed to get device descriptor");return;}if (!handle)libusb_open(dev, &handle);if((desc.idVendor == vid) && (desc.idProduct == pid)){printf("Dev (bus %u, device %u): %04X - %04X speed: %s\n",libusb_get_bus_number(dev), libusb_get_device_address(dev),desc.idVendor, desc.idProduct, speed);if (handle){if (desc.iManufacturer) {ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string));if (ret > 0)printf("  Manufacturer:              %s\n", (char *)string);}if (desc.iProduct) {ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string));if (ret > 0)printf("  Product:                   %s\n", (char *)string);}if (desc.iSerialNumber && verbose) {ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string));if (ret > 0)printf("  Serial Number:             %s\n", (char *)string);}}if (verbose) {for (i = 0; i < desc.bNumConfigurations; i++) {struct libusb_config_descriptor *config;ret = libusb_get_config_descriptor(dev, i, &config);if (LIBUSB_SUCCESS != ret) {printf("  Couldn't retrieve descriptors\n");continue;}print_configuration(config);libusb_free_config_descriptor(config);}if (handle && desc.bcdUSB >= 0x0201)print_bos(handle);}      }if(handle){libusb_close(handle);}
}static int test_wrapped_device(const char *device_name, uint16_t vendor_id, uint16_t product_id)
{libusb_device_handle *handle;int r, fd;fd = open(device_name, O_RDWR);if (fd < 0) {printf("Error could not open %s: %s\n", device_name, strerror(errno));return 1;}r = libusb_wrap_sys_device(NULL, fd, &handle);if (r) {printf("Error wrapping device: %s: %s\n", device_name, libusb_strerror(r));close(fd);return 1;}print_device(libusb_get_device(handle), handle, vendor_id, product_id);close(fd);return 0;
}static void sig_handler(int signum)
{switch (signum) {case SIGTERM:rcv_exit = 1;break;case SIGINT:rcv_exit = 1;break;case SIGUSR1:break;}
}static void usage(char *program)
{printf("%s - test usb data transfers to/from usb device\n",program);printf("Usage:\n");printf("  %s [options]\n", program);printf("options are:\n");printf("Common:\n");printf("  --help (or -h)\n");  printf("  -v vendor_id\n");printf("  -p product_id\n");printf("  -d device name\n");
}static int interrupt_data_rw(uint16_t vendor_id, uint16_t product_id)
{int kernelDriverDetached = 0;unsigned char data_in[64]={0};int length = 0;int r,j;libusb_device_handle *handle;handle = libusb_open_device_with_vid_pid(NULL, vendor_id, product_id);if (handle == NULL) {printf("libusb_open() failed\n");return -1;;}/*驱动必须解绑定,否则数据由驱动程序处理*/  if(libusb_kernel_driver_active(handle, 0)){printf("Kernel Driver Active\n");r = libusb_detach_kernel_driver(handle, 0);if (r == 0){printf("Detach Kernel Driver\n");kernelDriverDetached = 1;}else{fprintf(stderr, "Error detaching kernel driver.\n");return -1;;}}/* 指定当前接口 */r = libusb_claim_interface(handle, 0);if (r != 0){fprintf(stderr, "Error claiming interface.\n");goto exit;}while(!rcv_exit){memset(data_in, 0, sizeof(data_in));/*中断方式读取断点数据,由端点描述符可知端点地址 0x81 为鼠标输入端点读取长度为5字节,超时时间为1000ms*/   r = libusb_interrupt_transfer(handle, 0x81, data_in, 5, &length, 1000);if ((r < 0) || (length == 0)){printf("bulk recive error,r:%d length:%d\n",r,length);}else{printf("receive data:\n");for(j=0; j<length; j++){printf("0x%x ",data_in[j]);}printf("\n");}usleep(500000);}/* 释放指定的接口 */r = libusb_release_interface(handle, 0);if (0 != r){fprintf(stderr, "Error releasing interface.\n");}exit:if(kernelDriverDetached){//恢复驱动绑定,否则鼠标不可用libusb_attach_kernel_driver(handle, 0);}libusb_close(handle);return r;}int main(int argc, char *argv[])
{char *program = argv[0];int option;const char *device_name = NULL; //"/dev/bus/usb/001/005"libusb_device **devs;ssize_t cnt;int r, i;uint16_t vid=0, pid=0;libusb_device_handle *handle = NULL;static const struct option options[] = {{ "vendid", required_argument, NULL, 'v' },{ "productid",  required_argument, NULL, 'p' },{ "devicename",   required_argument, NULL, 'd' },{ "help",   no_argument, NULL, 'h' },};/* Parse command line options, if any */while ((option = getopt_long_only(argc, argv,"hv:p:d:",options, NULL))){if (option == -1)break;switch (option) {case 'v':vid = strtoul(optarg, NULL, 0);break;case 'p':pid = strtoul(optarg, NULL, 0);break;case 'd':device_name = optarg;break;case 'h':usage(program);exit(EXIT_SUCCESS);break;default:printf("ERROR: Invalid command line option\n");usage(program);exit(EXIT_FAILURE);}}printf("vid:0x%x pid:0x%x devicename:%s\n",vid,pid,device_name);r = libusb_init(NULL);if (r < 0)return r;if (device_name) {printf("test_wrapped_device\n");r = test_wrapped_device(device_name,vid,pid);} else {cnt = libusb_get_device_list(NULL, &devs);if (cnt < 0) {libusb_exit(NULL);return 1;}for (i = 0; devs[i]; i++)print_device(devs[i], handle,vid,pid);libusb_free_device_list(devs, 1);}signal(SIGINT, sig_handler);signal(SIGTERM, sig_handler);//read mouse datainterrupt_data_rw(vid,pid);libusb_exit(NULL);return r;
}​

编译命令:

gcc -o test_rw test_rw.c -I/usr/local/include/libusb-1.0/ -I../ -lusb-1.0

lsusb查看鼠标设备信息如下:

根权限运行程序,读取鼠标信息:./testrw -v 0x046d -p 0xc045,读取过程需要移动鼠标,否则会提示读取失败。

libusb读取鼠标数据相关推荐

  1. 使用libusb读取鼠标数据

    使用libusb读取鼠标数据 文章目录 使用libusb读取鼠标数据 1. HID协议 1.1 描述符 1.2 数据格式 1.2.1 键盘 1.2.2 LED 1.2.3 鼠标 1.2.4 扫描码 2 ...

  2. python读数据-如何用Python读取开放数据?

    当你开始接触丰富多彩的开放数据集时,CSV.JSON和XML等格式名词就会奔涌而来.如何用Python高效地读取它们,为后续的整理和分析做准备呢?本文为你一步步展示过程,你自己也可以动手实践. 需求 ...

  3. 树莓派 rfid_树莓派工控机做Modbus RTU主站读取RFID数据

    KUNBUS Revpi Core 3是工业级的树莓派,可作为小型的工业PC用,外观十分小巧,操作简单,DIN导轨模块化安装,RevPi core 3能与RevPi IO连接,能实时对这些IO的控制. ...

  4. 如何在QT中读取串口数据

    总是能在别人的博客中学到太多太多,谢谢各位对知识的无私共享,谢谢大家 前言 去年我使用Qt编写串口通信程序时,将自己的学习过程写成了教程(Qt编写串口通信程序全程图文讲解),但是由于时间等原因,我只实 ...

  5. stm32读取驾驶模拟器数据 stm32F407读取joystick数据

    需求 实习工作,老板要求用单片机读取驾驶模拟器(Joystick)返回的数据,驾驶模拟器usb输出,输出信息包括:方向盘转角.左右拨杆.按键等. 硬件 采用正点原子探索者开发板,即插即用,硬件不需要改 ...

  6. 【TensorFlow学习笔记】完美解决 pip3 install tensorflow 没有models库,读取PTB数据

    安装tensorflow 我使用的是最最最简单的容易的 pip3 install <TensorFlow学习笔记> 一. 安装win10下python3.6的tensorflow的CPU版 ...

  7. [Rx86OS-IX] 解读鼠标数据 移动鼠标

    平台 处理器:Intel Celeron(R) Dual-Core CPU 操作系统:Windows7 专业版 x86 阅读书籍:<30天自制操作系统>-川合秀实[2015.03.23 ] ...

  8. TensorFlow csv读取文件数据(代码实现)

    TensorFlow csv读取文件数据(代码实现) 大多数人了解 Pandas 及其在处理大数据文件方面的实用性.TensorFlow 提供了读取这种文件的方法. 前面章节中,介绍了如何在 Tens ...

  9. SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...

    转:http://blog.csdn.net/miragesky2049/article/details/7204882 SharePoint2010沙盒解决方案基础开发--关于TreeView树形控 ...

  10. Kinect V1读取图像数据(For Windows)

    Kinect V1读取图像数据(For Windows) 这篇博客 Kinect V1介绍 数据读取的基本流程 运行代码和注释 结尾 这篇博客  刚好有一台现成的Kinect V1相机,所以就拿过来学 ...

最新文章

  1. fanuc机器人四边形编程_FANUC机器人示教编程:原始路径恢复功能介绍与使用方法...
  2. 压测接口线程数设置_ZAT掌门性能压测巡检系统实战和落地
  3. python中的装饰器有哪些-python中的装饰器详解
  4. 火星今天飞抵西非国家寻找埃博拉疫情
  5. 产品入门首月成长报告 | PMcaff-干货
  6. windows下配置opencv
  7. [NBUT 1458 Teemo]区间第k大问题,划分树
  8. int和Integer的比较
  9. pacman吃豆人_通过Tensorflow和强化学习实现自动化吃豆人PacMan
  10. dart调用python_Dart - Isolate 并发
  11. 在固态硬盘上安装win7后没有声音
  12. python中confIgparser模块学习
  13. 【Python】AxisError: axis 0 is out of bounds for array of dimension 0
  14. 计算机视觉教程3-1:全面详解图像边缘检测算法(附Python实战)
  15. Datagrid的deleteRow多行移除问题
  16. 求单链表的交集和并集
  17. 我的世界红石计算机教程1,《我的世界》红石电脑制作原理及使用教程
  18. 云安全类型及预防方法
  19. Hard Voting 与 Soft Voting 的对比
  20. Ubuntu下安装rar软件,解压rar压缩文件方法

热门文章

  1. 一个QQ用户名/密码钓鱼分析
  2. 二维码扫码登陆过程分析
  3. android转发短信到邮箱,Android手机使用Tasker转发短信及来电
  4. 【计算机网络】Stanford CS144 学习笔记
  5. 5.5 Go语言项目实战:多人聊天室
  6. 添加个人博客音乐外链
  7. ue4之将Sequence嵌入蓝图
  8. 如何将PDF的单页页面分割成多个页面,如何将PDF页面的四周空白部分裁剪掉
  9. apache-ant-1.7 下载
  10. Tightvncserver 连接树莓派的方法及步骤