USB主机是如何检测到设备的插入的呢?

USB设备的插入检测机制

      首先,在USB集线器的每个下游端口的D+和D-上,分别接了一个15K欧姆的下拉电阻到地。这样,在集线器的端口悬空时,就被这两个下拉电阻拉到了低电平。而在USB设备端,在D+或者D-上接了1.5K欧姆上拉电阻.对于全速和高速设备,上拉电阻是接在D+上;而低速设备则是上拉电阻接在D-上。这样,当设备插入到集线器时,由1.5K的上拉电阻和15K的下拉电阻分压,结果就将差分数据线中的一条拉高了集线器检测到这个状态后,它就报告给USB主控制器(或者通过它上一层的集线器报告给USB主控制器),这样就检测到设备的插入了。USB高速设备先是被识别为全速设备,然后通过HOST和DEVICE两者之间的确认,再切换到高速模式的。在高速模式下,是电流传输模式,这时将D+上的上拉电阻断开。  

     一个简单的实验:只用一个上拉电阻接在USB的+5V和D+或者D-上,WINDOWS也会提示发现新硬件,但是无法找到驱动程序。这时去设备管理器里面看,有显示未知USB设备,并且其VID和PID为0。根据这个,我们可以简单的判断设备是否枚举成功。如下图所示,分别是枚举不成功和枚举成功的图。

USB设备的枚举过程:

     USB主机在检测到USB设备插入后,就要对设备进行枚举了。为什么要枚举呢?枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序调试USB设备,很重要的一点就是USB的枚举过程,只要枚举成功了,那么就已经成功大半了。

       在说枚举之前,先大概说一下USB的一种传输模式——控制传输。这种传输在USB中是非常重要的,它要保证数据的正确性,在设备的枚举过程中都是使用控制传输。控制传输分为三个过程:①建立过程。②可选的数据过程。③状态过程。建立(Setup)过程都是由USB主机发起,它开始于一个Setup令牌包,后面紧跟一个DATA0包。如果是控制输入传输,那么数据过程就是输入数据如果是控制输出传输,那么数据过程是输出数据。如果在设置过程中,指定了数据长度为0,则没有数据过程。数据过程之后是状态过程。状态过程刚好与数据过程的数据传输方向相反:如果是控制输入传输,则状态过程是一个输出数据包;如果是控制输出传输,则状态过程是一个输入数据包。状态阶段用来确认所有的数据都已经正确传输

 枚举的详细过程。

       首先,USB主机检测到USB设备插入后,就会先对设备复位。设备复位后,USB主机就会对地址为0的设备发送获取设备描述符的标准请求。所有的USB设备在总线复位后其地址都为0,这样主机就可以跟那些刚刚插入的设备通过地址0通信。主机在建立阶段发出获取设备描述符的输入请求,设备收到该请求后,在数据过程将设备描述符返回给主机。主机在成功获取到一个数据包的设备描述符后并且确认没有什么错误后(注意:有些USB设备的端点0大小不足18字节(但至少具有8字节),而标准的设备描述有18字节,在这种情况下,USB设备只能暂时按最大包将部分设备描述符返回,而主机在成功获取到前面一部分描述符后,就不会再请求剩下的设备描述符部分,而是进入设置地址阶段),就会返回一个0长度的状态数据包给设备。

       然后主机再对设备复位一下,接下来就会进入到设置地址阶段。这时USB主机发出一个设置地址的请求(建立过程,设置地址无数据过程),地址包含在建立包中,具体的地址USB主机会负责管理,它会分配一个唯一的地址给新的设备。USB设备在收到地址后,返回0长度的状态包,主机收到0长度的状态包之后,会返回一个ACK给设备。设备在收到这个ACK之后,就可以启用新的地址了。这样设备就分配到了一个唯一的设备地址,以后主机就通过它来进行访问该设备。然后主机再次获取设备描述符,这次跟第一次可能有点不一样,这次需要获取完全部的18个字节的设备描述符。当然,如果你的端点0缓冲大于18字节的话,那就跟第一次的情形一样了。

     接下来,主机就会获取配置描述符。配置描述符总共为9字节。主机在获取到配置描述符后,根据里面的配置集合总长度,再获取配置集合。配置集合包括配置描述符,接口描述符,端点描符等等。如果有字符串描述符的话,还要获取字符串描述符。另外HID设备还有HID描述符等。使用BUSHOUND以及通过串口返回信息,很容易看到具体的过程。总之是主机请求什么,你的程序就响应什么.

        USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了。USB的描述符主要有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,HID描述符,报告描述符等等.

     一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;端点描述符定义了端点的大小,类型等等。由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。每种描述符都有自己独立的编号,如下:

#defineDEVICE_DESCRIPTOR 0x01 //设备描述符
#defineCONFIGURATION_DESCRIPTOR 0x02 //配置描述符
#defineSTRING_DESCRIPTOR 0x03 //字符串描述符
#defineINTERFACE_DESCRIPTOR 0x04 //接口描述符
#defineENDPOINT_DESCRIPTOR 0x05 //端点描述符

 

下面分别详细介绍一下各描述符。
1.设备描述符
//定义标准的设备描述符结构
typedefstruct_DEVICE_DCESCRIPTOR_STRUCT
{
BYTEblength; //设备描述符的字节数大小
BYTEbDescriptorType; //设备描述符类型编号
WORDbcdUSB; //USB版本号
BYTEbDeviceClass; //USB分配的设备类代码
BYTEbDeviceSubClass; //USB分配的子类代码
BYTEbDeviceProtocol; //USB分配的设备协议代码
BYTEbMaxPacketSize0; //端点0的最大包大小
WORDidVendor; //厂商编号
WORDidProduct; //产品编号
WORDbcdDevice; //设备出厂编号
BYTEiManufacturer; //设备厂商字符串的索引
BYTEiProduct; //描述产品字符串的索引
BYTEiSerialNumber; //描述设备序列号字符串的索引
BYTEbNumConfigurations; //可能的配置数量
}
DEVICE_DESCRIPTOR_STRUCT,*pDEVICE_DESCRIPTOR_STRUCT;
//实际的设备描述符示例
codeDEVICE_DESCRIPTOR_STRUCTdevice_descriptor= //设备描述符
{
sizeof(DEVICE_DESCRIPTOR_STRUCT), //设备描述符的字节数大小,这里是18字节
DEVICE_DESCRIPTOR, //设备描述符类型编号,设备描述符是01
0x1001, //USB版本号,这里是USB01.10,即USB1.1。由于51是大端模式,所以高低字节交
0x00, //USB分配的设备类代码,0表示类型在接口描述符中定义
0x00, //USB分配的子类代码,上面一项为0时,本项也要设置为0
0x00, //USB分配的设备协议代码,上面一项为0时,本项也要设置为0
0x10, //端点0的最大包大小,这里为16字节
0x7104, //厂商编号,这个是需要跟USB组织申请的ID号,表示厂商代号。
0xf0ff, //该产品的编号,跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程
0x0100, //设备出厂编号

 

0x01, //设备厂商字符串的索引,在获取字符串描述符时,使用该索引号来识别不同的字符串

0x02, //描述产品字符串的索引,同上
0x03, //描述设备序列号字符串的索引,同上
0x01 //可能的配置数为1,即该设备只有一个配置
};

2.配置描述符
//定义标准的配置描述符结构
typedefstruct_CONFIGURATION_DESCRIPTOR_STRUCT
{
BYTEbLength; //配置描述符的字节数大小
BYTEbDescriptorType; //配置描述符类型编号
WORDwTotalLength; //此配置返回的所有数据大小
BYTEbNumInterfaces; //此配置所支持的接口数量
BYTEbConfigurationValue; //Set_Configuration命令所需要的参数值
BYTEiConfiguration; //描述该配置的字符串的索引值
BYTEbmAttributes; //供电模式的选择
BYTEMaxPower; //设备从总线提取的最大电流
}
CONFIGURATION_DESCRIPTOR_STRUCT,*pCONFIGURATION_DESCRIPTOR_STRUCT;

3.接口描述符
//定义标准的接口描述符结构
typedefstruct_INTERFACE_DESCRIPTOR_STRUCT
{
BYTEbLength; //接口描述符的字节数大小
BYTEbDescriptorType; //接口描述符的类型编号
BYTEbInterfaceNumber; //该接口的编号
BYTEbAlternateSetting; //备用的接口描述符编号
BYTEbNumEndpoints; //该接口使用的端点数,不包括端点0
BYTEbInterfaceClass; //接口类型
BYTEbInterfaceSubClass; //接口子类型
BYTEbInterfaceProtocol; //接口遵循的协议
BYTEiInterface; //描述该接口的字符串索引值
}
INTERFACE_DESCRIPTOR_STRUCT,*pINTERFACE_DESCRIPTOR_STRUCT;

4.端点描述符

//定义标准的端点描述符结构
typedefstruct_ENDPOINT_DESCRIPTOR_STRUCT
{
BYTEbLegth; //端点描述符字节数大小
BYTEbDescriptorType; //端点描述符类型编号
BYTEbEndpointAddress; //端点地址及输入输出属性
BYTEbmAttributes; //端点的传输类型属性
WORDwMaxPacketSize; //端点收、发的最大包大小
BYTEbInterval; //主机查询端点的时间间隔
}
ENDPOINT_DESCRIPTOR_STRUCT,*pENDPOINT_DESCRIPTOR_STRUCT;
下面是一个配置描述符集合的定义
typedefstruct_CON_INT_ENDP_DESCRIPTOR_STRUCT
{
CONFIGURATION_DESCRIPTOR_STRUCTconfiguration_descriptor;
INTERFACE_DESCRIPTOR_STRUCT interface_descritor;
ENDPOINT_DESCRIPTOR_STRUCT endpoint_descriptor[ENDPOINT_NUMBER];
}CON_INT_ENDP_DESCRIPTOR_STRUCT;
配置描述符集合的示例

codeCON_INT_ENDP_DESCRIPTOR_STRUCTcon_int_endp_descriptor= //配置描述符集合
{
//configuration_descriptor //配置描述符
{
sizeof(CONFIGURATION_DESCRIPTOR_STRUCT), //配置描述符的字节数大小,这里为9
CONFIGURATION_DESCRIPTOR, //配置描述符类型编号,配置描述符为2
(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+
sizeof(INTERFACE_DESCRIPTOR_STRUCT)+
sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)*256+
(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+
sizeof(INTERFACE_DESCRIPTOR_STRUCT)+
sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)/256, //配置描述符集合的总大小
0x01, //只包含一个接口
0x01, //该配置的编号
0x00, //iConfiguration字段
0x80, //采用总线供电,不支持远程唤醒
0xC8 //从总线获取最大电流400mA
},
//interface_descritor //接口描述符
{

sizeof(INTERFACE_DESCRIPTOR_STRUCT), //接口描述符的字节数大小,这里为9
INTERFACE_DESCRIPTOR, //接口描述符类型编号,接口描述符为3
0x00, //接口编号为4
0x00, //该接口描述符的编号为0
ENDPOINT_NUMBER, //非0端点数量为2,只使用端点主端点输入和输出
0x08, //定义为USB大容量存储设备
0x06, //使用的子类,为简化块命令
0x50, //使用的协议,这里使用单批量传输协议
0x00 //接口描述符字符串索引,为0,表示没有字符串
},
//endpoint_descriptor[]
{
{ //主端点输入描述
sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7
ENDPOINT_DESCRIPTOR, //端点描述符类型编号,端点描述符为5
MAIN_POINT_IN, //端点号,主输入端点
ENDPOINT_TYPE_BULK, //使用的传输类型,批量传输
0x4000, //该端点支持的最大包尺寸,64字节
0x00 //中断扫描时间,对批量传输无效
},
{ //主端点输出描述
sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7
ENDPOINT_DESCRIPTOR, //端点描述符类型编号,端点描述符为5
MAIN_POINT_OUT, //端点号,主输出端点
ENDPOINT_TYPE_BULK, //使用的传输类型,批量传输
0x4000, //该端点支持的最大包尺寸,64字节
0x00 //中断扫描时间,对批量传输无效
}

其中关于端点的类型定义如下
//定义的端点类型
#defineENDPOINT_TYPE_CONTROL 0x00 //控制传输
#defineENDPOINT_TYPE_ISOCHRONOUS 0x01 //同步传输
#defineENDPOINT_TYPE_BULK 0x02 //批量传输
#defineENDPOINT_TYPE_INTERRUPT 0x03 //中断传输
端点号的定义如下
#defineMAIN_POINT_OUT 0x02 //2号输出端点
#defineMAIN_POINT_IN 0x82 //2号输入端点

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python堆排序算法_python 排序 堆排序

算法思想 :堆排序利用堆数据结构设计的一种排序算法,堆是一种近似完全二叉树的结构,同时满足堆积的性质,即对于任意的i均有ki>k(2i1),ki>k(2i2)步骤:将数组转化为最大堆将当前堆的根结点和最后一个结点交换&…

final在类和方法中的使用

package final0; //final修饰的类不能继承//final修饰的方法不能继承public class TestFinal3 { public static void main(String[] args) { }} // 修饰的类不能继承final class Dad {}class Dad { // final修饰的方法不能继承:public final void method(){} public final void…

单招计算机专业考多少分可以录取,单招考多少分能过?单招分数线

单独招生是高等职业院校的一种招生形式,和普通高考相比,虽然单招人数连年增加,但报考人数相比高考总人数还是略少的,竞争压力没有那么大,录取率相对高很多,基本不存在落榜,上大学更安全&#xf…

全国计算机等级考试题库二级C操作题100套(第97套)

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程刷题面经求职讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进…

【job】2013年5-5阿里巴巴暑期实习招聘笔试题目及部分答案

网上各种标为2013年,实际上都是2012年或者更早的,下面的才是真正的2013年5月5日考试的卷子。 答题说明: 1.答题时间90分钟,请注意把握时间; 2.试题分为四个部分:单项选择题(10题,20分…

powershell新建python文件_powershell如何打开Python

展开全部(1)打开powershell。在开始菜单的搜索框输入powershell,回车即可打开。(2)运行62616964757a686964616fe59b9ee7ad9431333337616631python。在打开的powershell里直接输入python,回车即可打开。如果python不能被识别,需要先在powershe…

操作系统以什么方式组织用户使用计算机,操作系统习题

1.1 什么是计算机的操作系统?操作系统是有效地控制和管理计算机系统资源,合理地组织计算机的工作流程, 以及方便用户的程序的集合1.2 操作系统管理计算机系统的哪些资源?操作系统管理和控制计算机系统中的所有软、硬件资源1.3 为什么要引进分时系统?分…

微信小程序的页面渲染(if/for)

下面&#xff0c;粗略的介绍一下微信小程序的条件渲染、列表渲染、数据绑定等&#xff0c;详细的内容大家可以去看微信小程序的API,在此只做简单描述&#xff0c;希望能帮助到大家 条件渲染 <!--wxml--> <view wx:if"{{view WEBVIEW}}"> WEBVIEW </v…

Linux进程间通信(管道、消息队列、共享内存、信号、信号量)

目录Linux进程间通信概述1.管道无名管道(pipe)有名管道(fifo)2.消息队列(msg)消息队列的通信原理消息队列相关api消息队列收发数据键值生成消息队列移除3.共享内存(shm)4.信号(sig)信号概述信号编程&#xff08;入门&#xff09;信号携带消息&#xff08;高级&#xff09;5.信号…

Eclipse上GIT插件EGIT使用手册之五_查看历史记录

Team -> Show in history可以查看版本历史提交记录 可以选择对比模式

emacs python debug_我常用的 Python 调试工具 - 博客 - 伯乐在线

以下是我做调试或分析时用过的工具的一个概览。如果你知道有更好的工具&#xff0c;请在评论中留言&#xff0c;可以不用很完整的介绍。日志没错&#xff0c;就是日志。再多强调在你的应用里保留足量的日志的重要性也不为过。你应当对重要的内容打日志。如果你的日志打的足够好…

solr7.4 centos7安装

环境&#xff1a;centos7、JDK1.8、solr 自带Jetty启动 一、安装JDK1.8环境 1、下载JDK jdk-8u172-linux-x64.rpm 下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2、安装JDK rpm -ivh jdk-8u131-linux-x64.rpm 3、…

一个常见的台式计算机有哪些硬件部分组成,台式电脑有哪些组成部分

篇一&#xff1a;电脑硬件的基本组成部分电脑硬件的基本组成部分 很多刚接触电脑的朋友不是很清楚电脑组成部分&#xff0c;不清楚电脑硬件由什么组成&#xff0c;电脑学习网就为朋友们详细介绍电脑硬件的组成&#xff0c;并简单介绍电脑组成部分的这些电脑硬件的基本功能。(1)…

How to Fix an App that Crashes in Release but n...

2019独角兽企业重金招聘Python工程师标准>>> 今天在测试app时&#xff0c;发现app store上版本有奔溃现象&#xff0c;但是直接用xcode跑本地程序没问题。猜测release&debug版本造成的&#xff0c;后发现targets的 optimization level设置问题&#xff0c;将rel…

全国计算机等级考试题库二级C操作题100套(第94套)

第94套&#xff1a; 函数fun的功能是&#xff1a;计算 的前n项之和。若x2.5&#xff0c;n15时&#xff0c;函数值为&#xff1a;1.917914。 请在程序的下划线处填入正确的内容并把下划线删除&#xff0c;使程序得出正确的结果。 注意&#xff1a;源程序存放在考生文件夹下的BL…

斐波那契数列c++代码_轮到你了,斐波那契数列!

前阵子&#xff0c;日剧“轮到你了”终于大结局了&#xff0c;虽然结局有点一言难尽&#xff0c;但黑岛和二阶堂两个学霸之间的爱情&#xff0c;还是很甜呢呐&#xff01;两个学霸之间的默契的斐波那契数列也被许多网友认为是凶手行凶的依据。到底这数列有啥神奇之处&#xff0…

悖论对计算机科学影响,引力波的发现对计算机科学有什么意义?

满意答案saihdfa2016.02.28采纳率&#xff1a;43% 等级&#xff1a;10已帮助&#xff1a;420人引力波的发现对计算机科学的意义&#xff1a;允许引力波携带有更多的之前从未被观测过的信息。引力波有两个非常重要而且比较独特的性质。第一&#xff1a;不需要任何的物质存在于…

抽屉之Tornado实战(5)--点赞与评论树

点赞 点赞的过程&#xff1a;数字增加&#xff0c;并在后台点赞表记录数据 需要发过去的数据&#xff1a;用户id&#xff0c;新闻id 用户id从session里获得&#xff0c;那新闻id怎么获取呢&#xff1f;这想到分页是循环新闻列表来展示内容&#xff0c;循环的新闻id可以做为参…

全国计算机等级考试题库二级C操作题100套(第98套)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

用于计算的计算机主机,一种用于区块链计算的计算机主机的制作方法

技术特征&#xff1a;1.一种用于区块链计算的计算机主机&#xff0c;包括计算机主机主体(1)&#xff0c;其特征在于&#xff1a;所述计算机主机主体(1)上开凿有散热孔(2)&#xff0c;且计算机主机主体(1)的内腔通过散热孔(2)与外界相连通&#xff0c;所述散热孔(2)内固定连接有…