玩转USB HID系列:USB先导知识简明

12 篇文章 0 订阅
4 篇文章 3 订阅

先记住几个重要知识

USB device 不能主动发送信息给USB host

usb与串口有所不同,它是主机端驱动的方式,设备(device)必须在主机(host)询问后才能返回数据。
device想要定时定量数据到主机就需要主机不断查询,只要主机询问的足够快,就相当于数据可以实时传输了。

端点(End Point)的IN 和OUT是相对谁而言的?

注意!无论是device还是host,IN和OUT是都相对host来说的,IN就是设备发主机收,OUT反之。
也就是说:
device从OUT端点读取端点数据,向IN端点写入数据
host从IN端点读取端点数据,向OUT端点写入数据

USB 2.0的速度

过去我们称USB分USB2.0,USB1.1,USB1.0
现在这种说法取消了,都划为USB2.0中:
USB2.0 High Speed <–>过去所说的USB2.0
USB2.0 Full Speed <–>也就是USB1.1
USB2.0 Low Speed <–>也就是USB1.0

这里面也不是只由HS,FS和LS决定,还由传输方式决定
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(对这个表格有些存疑,待考正)

开始阅读

导读:usb(Universal Serial Bus) 串行总线协议是一种常见的计算机协议,几乎所有的个人电脑都配有 usb 接口,像优盘和手机也多是 usb 接口,还有一些打印机,鼠标和键盘等也是使用 usb 接口。usb 协议支持插拔,即插即用非常方便。这篇文章不是详解 usb 协议,只是对一些 usb 协议的知识点进行简单概括。在此推荐基本非常不错的 usb 学习书籍《圈圈教你玩USB》的第二版,如果真的要精通 usb 协议的话,还是去阅读 usb 协议的规范。

usb 协议从原来的 1.0 发展到现在的 3.x,速度从1.5Mb/s 到480Mb/s再到 10Gb/s ,发生了很大的变化。usb 1.0 显然已经无法满足现在的需求,USB 3.0 推广了也有七八年了,现在新买的电脑上都会有 USB 3.0 接口,但是也没全面替代 USB 2.0。USB 3.0 显著的一个特征就是接口是蓝色的(找一个 USB 3.0 的优盘看看),并且里面除了原来的 4根线 ,又多了几根(毕竟更快的传输速度)。由于手中的 开发板 上配置的 是 USB 2.0的接口,所以还是以 USB 2.0来总结,熟悉了 USB 2.0 再看 USB3.0 也会容易很多。
一、usb 接口类型

在这里插入图片描述

从上面图片来看,usb 的接口类型众多,像主机端,主要用 USB A-Type 和 USB B-Type (看看电脑端USB接口),设备端常见的 USB C-Type 和 Micro-USB B (看看自己手机是不是其中一种)。根据不同的设备选择不同的类型接口,如手机上放 USB A-Type 显然不合适。

USB 2.0 接口包含了四根线,5V电源线、差分数据线D-、差分数据线D+和地线。在 USB OTG中多一根身份识别线。其中差分线D+和D-接15k的下拉电阻到地,当没有插入设备的时候,D- 和 D+为低电平。而设备端的D+或者D-接1.5k的上拉电阻到3.3V电源,这样设备插入的时候,1.5K和15k电阻分压,得到3V左右的电压,为高电平,会被hub检测到,也就检测到设备插入。1.5k电阻接在D+还是D-上,由设备的速度来决定。
在这里插入图片描述
二、USB 控制器

USB控制器有以下几种规格:OHCI(Open Host Controller Interface) 、 UHCI(Universal HostController Interface) 、 EHCI(Enhanced Host Controller Interface) 和xHCI(eXtensible Host Controller Interface)。

OHCI:不仅仅是usb用的主控制器接口标准。主要是遵循csr (configuration space register)标准。是其他厂商在设计usb host controller时遵循的标准,如via, nec, ali, 包括nvidia等等。

UHCI: 由intel制定的usb 1.1主控制器(host controller)的硬件实例

EHCI: USB 2.0的主控制器标准接口,兼容 OHCI 和 UHCI。

xHCI:USB 3.0 的控制器标准,兼容 USB 2.0 及其以下的设备。

从上面看出,USB 的兼容性很好,出了新协议仍不忘兼容旧协议。

三、USB 拓扑结构

USB 像 I2c 一样,是主从结构,所有的通信只能由主机发起。下面是 USB 的拓扑结构(图片来自百度图片)。
在这里插入图片描述

USB控制器下接根集线器(root hub),根集线器下面再接集线器或者设备,集线器下面还可以接集线器,所以很容易看出来USB通过集线器来拓展口的数量,当然不可以无限制的接集线器,USB2.0要求最多为6层。同事USB的设备地址为7位,不能超过127个设备(0地址是给刚接入未初始化设备使用)。

四、USB的 device、 congfig、 interface、 endpoint

USB中包含device(设备)、config(配置)、interface(接口)和endpoint(端点)。一个设备下面可以有多个配置,每个配置代表某种功能,同一时刻只有有一个配置生效。

一个配置下可以有多个接口,接口就是端点的集合。而一个接口下面可以有多个端点,USB通信通信的基本形式,主机通信的目标就是端点。
在这里插入图片描述

五、USB通信的几种方式

USB 像 I2C 一样采用主从的通信方式,所有的通信必须由主机发起。虽然 USB 传输数据的也只有两根线,可通信方式可比I2C复杂的多。想想电脑上用的 USB 设备,像 优盘、摄像头、键盘鼠标等等各种各样的设备,各有不同的特点,像优盘需要进行大量数据传输,并且不能出错;摄像头数据量也不小,并且是实时传输,可能够允许错包(几个错包不至于画面没法看吧);而鼠标键盘数据量很小,但要求及时相应,要不然挪动鼠标的时候一卡一卡的谁受得了?所有 USB 协议要有多种通信方式来满足不同的需求。

USB 有四种传输方式:

批量传输:

批量传输用在那种需要大量传输数据,但对实时性要求不高的情况下。如优盘,拷贝数据的时候需要大量数据传输,但对时间上并没有特别严格的要求,通常多几秒钟也不是什么问题,但是不允许有错误,一个错误包就可能导致整个文件就废了,显然是不行的。如果检测到校验错误的包,会涉及到重传。

中断传输:

中断传输中的中断是一个很容易误解的词汇,尤其是想到鼠标键盘等 USB设备,是不是有数据上报的时候给主机触发一个中断?不是说 USB 所有的传说操作只能由主机发起吗?这里的中断并不是指硬件上那种中断机制,而是 USB 主机按照指定的时间不断的查询 设备 是否有数据传输。具体以多少时间来查询,根据设备要求而定。

同步传输:

看名字也是要保证信息传输的同步性,比如摄像头,需要实时传输数据。但同步传输也有个特点,虽然要求实时性,但不要求百分之百的包正确,毕竟错了几个包并不怎么影响视频质量,即使检测到错包也不需要重传。假想一下,摄像头的数据流实施的在传输,突然发现一个错包,然后去重传,可后面的数据仍然源源不断的传输,这个时候你重传了一个包,原本在它后面的数据都已经传输过去了,你重传它有什么用呢,错了就错了吧。

控制传输:

前面三种都是要 传输数据的,一个 USB 控制器下面挂接那么多的 设备,究竟怎么直接传输数据呢,总得先寻个址,发几个包先建立起来链接再说吧,这个过程就要到控制传输。尤其是一个新设备刚插入USB 集线器中,需要通过控制传输来进行设备枚举。所以控制传输就是传输控制信息的。

六、USB协议包结构及类型

简单来说 USB 包的结构如下:其中传输方式为LSB,也就是先传低位
| 同步域 | 8位标识符PID | … | EOP |
同步域:一是通知设备要开始传输了,而是主机和设备时间的时钟同步

8位标识符PID:标识包的类型,目前USB协议仅使用4位(PID0PID3),另外4位(PID4PID7)是PID0~PID3的取反,用来校验PID

…: 不同PID类型的包,此处不一样,像握手包就没有此部分

EOP:包结束标识

下表是不同PID对应的包类型:
在这里插入图片描述
IN、OUT和SETUP令牌包结构:注意IN和OUT是相对主机来说的,IN就是设备发主机收,OUT反之。

同步域8位标识符PID7位地址4位端点号5位CRC5校验EOP

SOF令牌包结构图:

同步域8位标识符PID11位帧号5位CRC5校验EOP

数据包结构图:

同步域8位标识符PID字节0字节1字节n16位CRC16校验EOP

握手包结构图:

|同步域 |8位标识符PID| EOP|

PRE包:当需要传送低速事务时,主机首先发送一个PRE令牌包(以全速模式发送)。对于全速设备,将会忽略这个令牌包。集线器在接收到这个令牌包之后,打开其连接了低速设备的端口,接着主机就会以低速模式给低速设备发送令牌包和数据包等。

同步域8位标识符PIDEOP

PING包:

同步域8位标识符PID7位地址4位端点号5位CRC5校验EOP

SPLIT包:高速事务分裂令牌包,通知集线器将高速数据包转化为全速或者低速数据包发送给其下面的端口。

开始SPLIT包结构:

同步域
8位标识符PID
7位 Hub addr
1位SC
7位Port
1位S
1位E
2位ET
5位CRC5
EOP
完成SPLIT包结构:

同步域
8位标识符PID
7位 Hub addr
1位SC
7位Port
1位S
1位U
2位ET
5位CRC5
EOP
其中 SC为0代表start-split token

参数port是指设备在 HUB 下的端口号

参数S和E:
在这里插入图片描述
在这里插入图片描述
(4)ERR:在分裂事务中表示错误使用。高速分裂事务的过程比较复杂,而且主要是由集线器完成,所以不详细说明

不同的传输方式也就是上面的包类型的不同组合,协议吗,就是两边按照同一套规则,你一句我一句的完成要传输的任务,

固定的交互时序,没有理解难度。

七、USB设备枚举过程简介

USB 支持热插拔,设备在需要的时候插入,不需要的时候拔出,所以 USB 设备不能事先定义好,然后注册进去,所以这就要求在插入的时候建立 usb_device。下面简单总结下设备枚举过程

1.主机集线器检测到设备插入: 前面说过, USB 设备的D+ (全速设备,高速设备也会先识别成全速设备)或 D-(低速设备)接1.5k上拉电阻,设备插入的时候会根据 D+ 还是D-是高电平识别出是什么类型的设备。

2.主机发送Get_Status请求: 集线器用中断传输方式上报集线器上的事件。当主机收到插入设备事件,就给集线器发送一个Get_Status请求更多的消息。

3.主机发送Set_Feature请求: 当主机获取到插入新设备后,给集线器发送一个Set_Feature请求,请求集线器重启端口。

4.主机和集线器建立数据链路: 主机在此发送Get_Status获取设备的重启状态。当集线器释放重启状态,设备就开始工作,准备好 0 endpoint 准备响应主机通信。

5.获取最大数据包长度: 前面的4步是主机和hub之间的交互,不涉及 usb 驱动框架的操作,从这一步开始USB驱动框架介入。

主机向 0 号端点发送 Get_Device_Descriptor命令获取设备描述符,然后读取设备描述符的bMaxPacketSize0字段,其地址偏移为7,此时只读前8字节(有些设备只支持返回8字节)。此时设备的缺省地址为 0 ,所以一个时刻只能枚举一个设备。

6.主机给设备分配地址: 第5步交互的时候,还是使用默认0地址,此时就要发送Set_Address分配一个唯一的设备地址。设备收到此请求,返回确认信息,并保存新的地址,然后就不再使用0地址,开始使用新的地址。

7.主机再次发送Get_Device_Descriptor命令: 上次发送Get_Device_Descriptor只是为了获取到bMaxPacketSize0字段,这次可是真的要获取设备描述符了。

8.主机发送Get_Device_Configuration命令: 获取到设备描述符后,开始获取配置描述符,USB设备收到此请求要返回全部配置信息。

9.主机发送Get_Device_String命令: 获取字符描述(如果有的话)。

到此,USB枚举也就完成了,接下来就是要在 USB 总线上匹配相应驱动,后面的事都是匹配到驱动的动作了,在后面分析驱动的时候再详解。USB 虽然使用起来方便,可驱动框架却比较复杂,但大多数工作都由 linux 内核完成,后面将分析代码中 USB设备时如何枚举的,以及如何匹配驱动。其实只要设备枚举出来了,后面不就是 在 总线上 match 驱动吗!

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值