我的USB入门第一课之读《圈圈教你玩USB》

1、    USB主机是如何检测到设备插入的呢?这要从USB集线器接收端的接口说起。
    在USB集线器的每个下游端口的D+和D-上,分别接了一个15K欧姆的下拉电阻到地。这样,当
集线器的端口悬空(即没有设备插入)时,输入端就被这两个下拉电阻拉到了低电平,而在USB的设备
端,在D+或者D-上接了一个1.5KΩ的上拉电阻到3.3V电源,1.5K的上拉电阻时接在D+还是D-上,由设备
的速度来觉得,对于全速和高速设备,上拉电阻接在D+上的,而低速设备的上拉电阻接在D-上。
    当设备插入到集线器时,接了上拉电阻的那条数据线的电压由1.5KΩ的上拉电阻和15KΩ的下拉电阻
分压决定,大概在3V左右(电源电压3.3V),这对集线器接收端来说时高电平。集线器检测到这个状态后
。他就报告给USB主控制器(或者通过上一层的集线器报告给USB主控制器),这样就检测到设备的插入了,
集线器根据检测到的被拉高的数据线是D+还是D-来判断插入的是什么速度类型的涉笔。USB高速设备先被
识别为全速设备,然后通过集线器和设备两者的确认,再切换到高速模式,再高速模式下,是电流传输
模式,这时要将D+上的上拉电阻断开。
2、USB的描述符及其之间的关系
    USB只是一个总线,只提供一个数据通路而已,USB总线驱动程序并不知道一个设备具体如何操作,
有哪些行为,具体的一个设备实现什么功能,要由设备自己来决定,那么USB主机是如何知道一个设备
的功能和行为的呢?这要通过描述符来实现了,描述符记录了设备的:
    1、类型。
    2、厂商
    3、商品ID(通常依靠他来加载对应的驱动程序)
    4、端点情况
    5、版本号等众多信息。
3、USB1.1协议定义的标准描述符
    1、设备描述符
        设备描述符主要记录的信息有:设备使用的USB协议版本,设备类型,端点0的最大包大小
厂商ID(VID)和产品ID(PID)、设备版本号,厂商字符串索引、产品字符串索引,设备序列号索引,可能的配置数等。
    2、配置描述符
        配置描述符主要记录的信息有:配置所包含的接口数、配置的编号、供电方式、是否支持远程唤醒、电流需求量等。
    3、接口描述符
        接口描述符主要记录的信息有:接口的编号、接口的端点数、接口所使用的类、子类、协议等。
    4、端点描述符
        端点描述符主要记录的信息有:端点号及方向、端点的传输类型、最大包长度、查询时间间隔等。
    5、字符描述符
        字符串描述符主要时提供一些方便人们阅读的信息,他不是必须的。
4、各个描述符之间的关系
    一个USB设备只有一个设备描述符,设备描述符里决定了该设备有多少种配置,每种配置都有一个配置描述符
,而在每个配置符中又定义了该配置有多少个接口,每个接口都有一个接口描述符,在接口描述符里又定义了该
接口有多少个端点,每个端点都有一个端点描述符,由此可以看出,USB的描述符之间的关系是一层一层的,
最上一层是设备描述符,接下来是配置描述符,再下来是接口描述符,最下面是端点描述符。
    在主机获取描述符时,首先获取设备描述符,接着再获取配置描述符,然后根据配置描述符中的配置集合
的总长度,一次将配置描述符,接口描述符,类特殊描述符(如果有),端点描述符一次读回,对于字符串
描述符时单独获取的,主机通过发送获取字符串描述符的请求以及描述符的:1、索引号2、语言ID来获取
对应的字符串描述符。
5、举个例子深刻理解设备、配置、接口、端点。
    这里所说的设备时一个实实在在的USB设备,例如一个USB鼠标,设备有一个设备地址,USB主机依靠这个
设备地址来访问设备。但是在这个设备内部还分得更细。他会分一些端点出来,例如端点0,端点1。也就是说
USB主机和USB设备通信,光有设备地址还不行,得还需要一个 端点地址,有了设备地址和端点地址,就可以
准确的对端点发送和读取数据了。
    而配置和接口,是为了更方便地管理端点而抽象出来的概念,一个设备可以有多个配置,但是同一时刻
只能有一个配置有效。每个配置下又可以有多个接口,当我们需要不同的功能时选择不同的配置即可。
    需要注意的是同一个端点号不能出现在同一个配置下的两个或者多个几口中,但是同一个端点号可以用在
不同的配置中。
6、多个接口的的设备
    具有多个接口,并由接口来实现功能的设备把他叫做USB复合设备,例如一个USB音频设备,它具有一个
音频控制接口,另外话有可能具有一个到多个音频流或MIDI流接口,在主机端会把USB符合设备的每个接口当作
一个功能设备来看待,像常见的USB,U盘等,通常是单一的设备,即一个设备下只有一个配置描述符、一个
接口描述符。
总结:
    由端点构成一个接口(或者反过来说,接口是端点的集合),又由接口构成一个配置(反过来说配置是接口的)
集合),再由配置构成了一个设备(设备是配置的集合),学习USB,一定要把这些关系理清楚了,才能按照
需要构造出一个合适的USB设备,如何一个设备的各种描述符都返回成功了,那么可以说已经成功了大半,相反,
只要描述符出现一点问题,哪怕是一个bit的错误,都可能照成设备无法识别或者无法正常工作!
7、USB设备的枚举过程
    USB主机在检测到USB设备后,就要对设备进行枚举了,为什么要进行枚举呢?枚举是从设备读取各种描述符的信息
,这样主机就可以根据这些信息来加载合适的驱动程序,从而知道设备是什么样的设备,如何进行通讯等
调试USB设备,很重要的一点就是USB的枚举过程,只要枚举成功了,剩下的工作就不多了。
    说枚举之前,得先介绍一下USB的一种传输模式————控制传输。这种传输是USB中非常重要的,他保证了数据
    的正确性,在设备枚举的过程中都是使用控制传输,控制传输分为三个过程:
        1、建立过程
            建立过程都是由主机发起的,它开始于一个SETUP令牌包,后面紧接着一个DATA0数据包
        2、可选的数据过程
            建立过程后紧接着就是数据过程,如果在建立过程中,指定了数据长度为0,则没有数据过程,
数据过程后面是状态过程。
        3、状态过程
            状态过程刚好与数据过程的数据传输方向相反,如果是控制读传输,则状态过程是一个输出
数据包,如果是控制写传输,则状态过程是一个输入数据包,状态过程是用来确认所有的数据 是否已经正确
传输完成。
8、枚举的详细过程
    1、USB主机检测到USB设备插入后,就会对设备复位,USB设备在总线复位后其地址为0,那么主机就可以
通过地址0和那些刚刚插入的设备通信。USB主机往地址为0的设备的端点0发送获取设备描述符的标准请求
(这是控制传输的建立过程)。设置收到该请求后,会按照主机请求的参数,在数据过程将描述符返回给
主机,主机在成功的获取到一个数据包的设备描述符并且确认没有错误之后,就会返回一个0长度的确认
数据包(状态过程)给设备,从而进入到接下来的设置地址的阶段,这里需要注意的是第一次主机只会读取
一个数据包的设备描述符。标准的设备描述有18个字节,有些USB设备的端点0大小不足18字节(但是至少
有8字节),在这种情况下,USB主机也是只发送一次数据输入请求,多余的数据将不会再次请求,因此
如果当设备端点0不足18字节时,就需要注意这个问题了,也就是说在第一次获取设备描述符时,只需要
返回一次数据即可,不要再等待主机继续获取剩余数据(如果还有),因为主机不会这么干,当主机成功获取
到设备描述符的前8个字节后(USB协议规定端点0最大包至少有8字节),他就知道端点0的最大包长度了
因为端点0最大包长度刚好再设备描述符的第八字节处。
    2、主机对设备又一次复位,这时就进入到设置地址阶段,USB主机往地址为0 的设备的端点0发出一个
设置地址的请求(控制传输的建立过程),新的设备地址包含在建立过程的数据包中,具体的地址由
USB主机负责管理,主机会分配一个唯一的地址给刚介入的设备,USB设备再收到这个建立过程之后,就
直接进入到状态过程,因为这个控制传输没有数据过程,设备等待主机请求状态返回(一个输入令牌包)
,收到输入令牌包和,设备就返回0长度的状态数据包,如果主机确认该状态包已经正确收到,就会发送
应答ACK给设备,设备在收到这个ACK后,就启用新的地址了,这样设备就分配到了一个唯一的设备地址,
以后主机就通过它来访问该设备。
    3、主机再一次获取设备描述符,这次跟第一次有点不一样,首先是主机不再使用0地址来访问设备
而是新的设备地址,另外,这次需要获取全部的18字节的设备描述符,如果你的端点0最大包长小于18字节,
那就会有多次请求数据输入(发送多个IN令牌包)。
    4、主机获取配置描述符。配置描述符总共为9个字节。主机在获取到配置描述符后,根据配置描述符中所
描述的配置结合总长度,获取配置集合,获取配置描述符和获取配置描述符的请求是差不多的,只是指定的长度
不一样。有些主机干脆不单独获取配置描述符,而是直接使用最大长度来获取配置描述符集合,因为设备实际
返回的数据可以少于指定的字节数。配置结合包括配置描述符、接口描述符、类特殊描述符(如果有)、端点描述符
等。接口描述符、类特殊描述符、端点描述符是不能单独获取的,必须跟随配置描述符以一个集合的方式一并返回。
    5、如果有字符串描述符,还要获取字符串描述符,另外,像HID设备还有报告描述符,他们是单独获取的
我们还可以使用BUS Hound(一个非常好的数据包监听软件,后面会介绍)查看数据包或者通过串口返回信息来
查看具体的请求,从而在程序中增加对它们的响应代码,主机请求什么,你的程序就要响应什么。

 

//以上内容源于《圈圈教你玩USB》

 

 

    

    
    
 

你可能感兴趣的:(USB学习)