libusb学习-2

来源:互联网 发布:免费x站最新域名升级 编辑:程序博客网 时间:2024/06/16 19:12

Libusb简介及例子
Libusb据说在Mac,Linux,Windows跨平台的。目前为止我还没有在除Linux平台外的其它平台测试 :(。回归重点,用通俗语言介绍一下我最近了解的,一般的usb设备驱动是在按照通常的在内核中基于usb通信,为用户空间展示一个设备节点的方式实现。这个确实是遵守了unix世界的“一切皆为文件”的理论。这个看起来是皆大欢喜的事情,其实则不然,在有USB子系统行业标准(说人话就是usb协议中已经统一的通信方式)的时候一切都好办,这种情况如printer etc。但是正如你所了解的一样,标准协议一般要比一个新自定义协议出现要晚好几年,甚至有可能永久都出现不了。所以如果要实现这种协议一般会在USB设备的已经接口0额外的接口1(注:此处的接口并非物理上的接口)用于实现自己的协议。
说的这么绕,就是为了说明这种情况存在的必然性。对于这种新的问题,有两种方案解决1是写内核驱动为用户空间提供一个设备节点;2就是在用户空间直接进行usb通信,抛开设备节点。当然这两种情况不能同时存在,使用2方法的时候,设备节点会自然消失。
这种新的协议的问题一般是采用后者来实现,因为内核主线是不会采纳不通用的驱动代码的。所以为了不一直为所有的版本内核都添加自己的驱动,可以在用户空间直接USB通信。这才是大家都好的结局。
这个时候大家猛然发现已经在内核中实现的基于printer协议的打印驱动程序也可以采用这个方法直接在用户空间USB通信实现,这样就可以完全和系统无关了,内核只要有usb通信协议就好了。上半场已经捋顺了,下面说说下半场。
方向明确了,如何实现,这时候大家发现了libusb,libusb可以实现用户空间直接和usb设备直接通信。这样大家都采用了基于libusb的免驱模式,如实说就是免掉内核中的驱动模式。
另外关于开源问题,以上说的和开源没有太大关系,重点是一段代码可以在多个平台运行的便利性和且不会对Linux内核的版本变化纠结。比如有名的例子主是hp公司的开源的hplip--linux平台的打印机驱动程序,它正是我说的情况。
不过,用户支持libusb的usbfs在内核中的配置项被加上了一个DEPRECATED标识,这说明了什么,暂时还不行而知。(20141228更新:原因是安全见这里Enable support for Linux systems without either usbfs or udev,不过也有相对的解决方案)
铺垫完了,回归正题。

1.介绍

官网: http://www.libusb.org/
Lisbusbx之前是lisbusb一个分支,现在已经合并到Libusb上了。

2.使用方法

Ubuntu上安装方法:sudo apt-get install libusb-1.0-0-dev
头文件

3.例子

如果如下例子可以编译过,说明环境没有问题了

#include <unistd.h>  #include <stdio.h>  #include <libusb-1.0/libusb.h>  // First, use "lsusb" see vid and pid.  // there is my printer(hp deskjet 1010) vid and pid.  #define VID 0x03f0  #define PID 0xb511  static int device_satus(libusb_device_handle *hd)  {      int interface = 0;      unsigned char byte;      libusb_control_transfer(hd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,              LIBUSB_REQUEST_CLEAR_FEATURE,              0,              interface,              &byte, 1, 5000);      printf("status:0x%x\n", byte);  /**  * byte  * normal:0x18  * other :0x10  */      return 0;  }  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) {          perror("Init Error\n"); //there was an error          return 1;      }      libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_INFO); //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) {          perror("Get Device Error\n"); //there was an error          return 1;      }      printf("%d Devices in list.\n", cnt);      dev_handle = libusb_open_device_with_vid_pid(ctx, VID, PID); //these are vendorID and productID I found for my usb device      if(dev_handle == NULL)          perror("Cannot open device\n");      else          printf("Device Opened\n");      libusb_free_device_list(devs, 1); //free the list, unref the devices in it      if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached          printf("Kernel Driver Active\n");          if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it              printf("Kernel Driver Detached!\n");      }      r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)      if(r < 0) {          perror("Cannot Claim Interface\n");          return 1;      }      printf("Claimed Interface\n");      device_satus(dev_handle);      libusb_close(dev_handle); //close the device we opened      libusb_exit(ctx); //needs to be called to end the      return 0;  }  

以上是一个简单的程序。获取打印机部分状态。
另外,PC上的lsusb命令也是基于libusb-1.0的一个应用程序:

$ ldd /usr/bin/lsusb      linux-gate.so.1 =>  (0xb76fc000)      libusb-1.0.so.0 => /lib/i386-linux-gnu/libusb-1.0.so.0 (0xb76ca000)                    ......  $  

源码:http://dist.momonga-linux.org/pub/momonga/2/SOURCES/libusb-0.1.10.tar.gz
http://sourceforge.net/projects/libusb/files/libusb-1.0/
关于libusb for Android见:https://github.com/libusb/libusb/blob/master/android/README

0 0