5.USB详解(鼠标)

1.简介

  今天来介绍下usb鼠标,属于USB五类设备的人机交互设备(hid:Human Interface Devices),在4种基本传输方式中使用中断传输,这里的中断传输并不是指从机可以随意发送给主机,因为usb只能有主机发起数据传输,实际上是由主机来不断查询从机的方式。

2.鼠标

2.1描述符

用软件看看鼠标的描述符组成如下所示,HID类设备描述符除了标准的之外还有类特殊描述符(包括报告描述符和物理描述符)。
在这里插入图片描述

2.1.1标准描述符

来看看usb文档是怎么描述Class、SubClass、Protocol Codes(主要这三个重要):
The bInterfaceClass member of an Interface descriptor is always 3 for HID class devices,Consequently, the HID class does not use subclasses to define most protocols,The bInterfaceProtocol member of an Interface descriptor only has meaning if the bInterfaceS-ubClass member declares that the device supports a boot interface, otherwise it is 0,所以我们只需要设置Class = HID.

2.1.2类特殊描述符

类特殊描述符有报告描述符和物理描述符,这个HID Descriptor类设备描述符跟在接口描述符后面,用来描述类描述符(报告描述符和物理描述),报告描述符用来描述主机和从机之间进行通信的协议,物理描述符描述有关激活设备上的的控件的信息(可选,一般不用)。

2.2.1 HID Descriptor

描述符含义如下所示:
在这里插入图片描述

2.2.2 Report Descriptor

报告描述符的组成比较复杂,我先介绍报告描述符组成,然后用HID文档上的一个鼠标例子来说明。

2.2.2.1 Report Descriptor

  报告描述符是由几块数据组成的,每块数据叫条目(item),条目第一字节有三个区域组成item type、item tag、item size,当条目是短条目的时候item size可以是0、1、2、3(一般都是用短条目,所以这里只讨论短条目)用来定义后面数据大小,有三种类型的item type:Main,Global,Local,主条目有5种类型的item tag(Input、Output、Feature、Collection、End Collection),主条目(Input、Output、Feature)指示数据控制方式、数据是相对还是绝对的,全局和本地用来描述数据范围和其他等等,一般全局和本地条目用来在主条目前面用来修饰,全局定义后对后面的数据属性都有效除非重新定义全局属性。
在这里插入图片描述
  hid驱动的解析器会遍历报告描述符,然后把它们存在项目状态表中(item state table),当遇到主条目的时候就会创建一个项目状态表,然后用Global和Local加入状态表(主条目用来新建一个项目状态表,而Global和Local可以改变它,其中Collectiong用来关联主项目),他们之间的关系就像如下所示:
在这里插入图片描述

2.2.2.2 MAIN

在这里插入图片描述

2.2.2.3 Global

在这里插入图片描述
在这里插入图片描述

2.2.2.4 Local

在这里插入图片描述

2.2.2.5 鼠标例子

定义一个3字节的鼠标报告:
在这里插入图片描述

2.2.2.6 伪代码

hid类的请求有标准的和类特殊的,类的请求都是到接口的,接上两节枚举程序控制传输流程添加代码:

//控制传输流程
void usb_control_transmit()
{
	usb_ctl_req req;
	static int state;
	
	if(state == 建立过程){
		//读8个字节长度请求
		usb_read_ep0(&req, 8);
		
		switch(req.bmRequestType & 0x1f){
//******************************到设备的请求**************************************//
			case DEVICE:
				SET_ADDRESS:
					结束流程,没有数据过程;
					break;					
				
				GET_DESCRIPTOR:
					设备、配置、接口描述符;
					state = 数据过程;
					break;
			
//*********************************到接口的请求*********************************//
			case INTERFACE:
			//要根据接口号来判断请求是不是到hid接口的if(req->index == HID_INTERFACE)
				switch(req.bmRequestType & 0x60){
                    //获取描述符,wValue为描述符类型,wIndex为接口号
                    case Standard:
                    	switch(req->wValue){
							case Report://获取报告描述符
							break;
							
							case HID://获取接口描述符
							break;
							
							default:
							break;
						}
					break;
					
					case Class:
					//................................
					break;	

					default:
					break;	
                }
				break;
			
//*******************************到端点的请求***************************************************//
			case ENDPOINT:
			break;
				
			default:
			break;
//************************************************************************************************
		}	
	}else if(数据过程){
		发送数据/接收数据;
		数据发送完成/接收完成结束;
	}
}

2.2 发送报告

  hid主机每间隔一段时间(在端点描述符中)就会查询从机是否有数据发送,从机只要将相应报告数据回复主机

3.参考文档

USB官网:https://www.usb.org/
HID1_11.pdf
hut1_12v2.pdf

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值