Baurine's Blog

对 libusb-win32 的理解

November 16, 2013

最近的一个项目用到了 libusb-win32,因此花时间了解了 libusb-win32 的思想。这种驱动不同于传统的 usb 功能驱动,它是一种通用驱动,适用于所有 usb 设备,而且一个驱动既能做功能驱动,又能做过滤驱动。它是如何实现的呢。

先来看一下 usb 驱动的层次结构:

应用层软件
------------
usb 功能驱动
------------
usb 控制驱动 (OHCI, EHCI, XHCI)
------------
usb 硬件设备

usb 控制驱动由操作系统提供,需要自己实现的是 usb 功能驱动。
在 usb 硬件设备这边,上面运行着 usb 固件程序,存储着 usb 设备的各种描述符,包括配置描述符,接口描述符,端点描述符。

传统的 usb 功能驱动,必须对 usb 硬件设备信息非常了解,它和 usb 固件程序配合工作。而顶层的应用层软件无须知道底层的实现细节,它使用功能驱动定义的各种 IO 控制码和底层通信。每种 IO 控制码用于实现一种功能。

如果应用层有新的需求,需要实现新的功能。那么有两种做法,一种是修改现有的功能驱动,添加新的 IO 控制码;一种方法是保持现有的功能驱动不变,新写一个过滤驱动用于实现新的 IO 控制码,运行在功能驱动之上。

在这种传统模式下,每种 usb 设备都必须有自己单独的驱动。

我们都知道,驱动难写,难调试,驱动人才更难求。要写好或改一个驱动,从来都不是那么轻松的事情。
所以 libusb 的做法是,把功能驱动的一些实现挪到应用层来做。
具体的做法是,功能驱动仅做为一个通道,应用层传来来什么指令我就往下面发什么指令。这时硬件接收到的指令将直接来自应用层。
这就要求应用层必须知道底层的实现细节,比如硬件有几个配置,几个接口,输入输出端点是什么。

因为功能驱动只是一个通道的作用了,所以可以适用于所用 usb 设备。
但如果使用 libusb 提供的驱动,那么应用层也必须使用 libusb 提供的 api 编写。

libusb 作为功能驱动使用时,将取代设备原来自己独有的功能驱动。
libusb 作为过滤驱动使用时,设备原来自己独有的功能驱动将保留,libusb 过滤驱动附加在其上层。
PS: 我们在实验的时候发现使用过滤驱动方案时不稳定,容易导致 usb 设备复位,也不知道问题出在哪。

微软后来自己也实现了类似的一套方案,叫 WinUSB,应用层的 api 封装在 winusb.dll 中,功能驱动叫 winusb.sys。
新版本 libusb 在 windows 将会直接使用 winusb 来实现。

但目前为止我所知道的只有 Android 的 ADB 驱动在 windows 上采用了 WinUSB 的方案。


Comments