每个USB设备有一个或多个配置来控制其行为;每个配置中都含有一个或多个接口;设备的接口具有一个或多个端点,每个USB设备在主机看来就是一些端点的结合,提取一个端点的地址、缓冲区长度、数据传输方向、类别等信息,就把一个端点封装成一个管道,利用这个管道句柄就可以实现主机与一个内存缓冲区和设备多个端点之间的数据传输。
USB通信模型,它表明了端点和管道所扮演的角色。整个模型分为3级结构:在最低一级,USB电缆把主控制器与设备的总线接口连接起来;在第二级,一个控制管道把系统软件与逻辑设备连接起来;在第三级,一捆数据管道把客户软件与一组接口连接起来,这些接口组成设备的功能.
Descriptor是描述符,并存储在USB设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令(即URB)要求设备发送这些信息. 描述附共有如下:
1——设备描述符
2——配置描述符
struct _CONFIGURATION_DEscriptOR_STRUCT
{
BYTE bLength; //描述符的长度
BYTE bDescriptorType; //描述符类型编号
WORD wTotalLength; //配置所返回的所有数量的大小
BYTE bNumInterface; //此配置所支持的接口数量
BYTE bConfigurationVale; //Set_Configuration命令需要的参数值
BYTE iConfiguration; //描述该配置的字符串的索引值
BYTE bmAttribute; //供电模式的选择
BYTE MaxPower; //设备从总线提取的最大电流
}
3——字符描述符
4——接口描述符
struct _INTERFACE_DESCRIPTOR_STRUCT
{
BYTE bLength; //长度
BYTE bDescriptorType; //描述符类型编号
BYTE bInterfaceNunber; //接口的编号
BYTE bAlternateSetting;//备用的接口描述符编号
BYTE bNumEndpoints; //该接口使用端点数,不包括端点0
BYTE bInterfaceClass; //接口类型
BYTE bInterfaceSubClass;//接口子类型
BYTE bInterfaceProtocol;//接口所遵循的协议
BYTE iInterface; //描述该接口的字符串索引值
}
5——端点描述符;
struct _ENDPOIN_DESCRIPTOR_STRUCT
{
BYTE bLength; //长度
BYTE bDescriptorType; //描述符类型编号
BYTE bEndpointAddress; //端点地址
BYTE bmAttribute; //端点的传输类型属性
WORD wMaxPacketSize; //端点收、发的最大包的大小
BYTE bInterval; //主机查询端点的时间间隔
}
描述符之间的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。
WDM驱动程序模型中的每个硬件设备都有两个驱动:功能驱动和总线驱动。功能驱动了解使硬件工作的所有细节,负责初始化I/O操作,处理I/O操作完成时所带来的中断事件,为用户提供一种设备适合的控制方式; 总线驱动程序(USB Driver,USBD)负责管理硬件与计算机的连接,实现繁琐的底层通信。总线驱动包括主控制器驱动程序(OPENHCI.SYS或者UHCD.SYS),hub驱动程序(USBHUB.SYS),一个由控制器驱动程序使用的类驱动程序(USBD.SYS)和发现USB主控制器并会装入相关功能驱动程序。
USB设备驱动程序通过发送URB(USB Request Block)和IRP(I/O Request Packet)来使用总线驱动并完成对物理硬件的操作。设备驱动会创建一个URB并提交到总线驱动程序USBD.SYS,这样,向USBD的调用被转化为带有主功能代码为IRP_MJ_INTERNAL_DEVICE_CONTROL的IRP。然后USBD再调度总线时间,发出URB中指定的操作,完成收发数据包请求。
USB 驱动程序是绑定到USB 接口上,而不是绑定到整个USB设备上。
驱动程序对象与设备对象的关系:
一方面, 驱动程序对象通常有多个与它相关的设备对象,因此它利用DeviceObject指针指向一个设备对象列表,该列表表示驱动程序可以控制的物理设备;
另一方面, 设备对象反过来指向它自己的驱动程序对象, 这样I/O管理器就知道在接收一个I/O请求时应该调用哪个驱动程序。每个功能码都对应一个驱动程序的入口点.