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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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

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

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

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

solr7.4 centos7安装

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

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

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

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

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

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

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

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

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

光动能表怎么维护_西铁城手表推荐,西铁城光动能表推荐选购指南

有的朋友们在京东上面看到款式多样的西铁城手表和西铁城光动能手表的时候,不知道怎么选择哪一款适合自己佩戴的?那么今天我就通过这篇文章,跟大家详细的分享一下关于西铁城手表的知识。让大家在选购的时候更加清晰明了的知道哪一款适合自己。…

python-2:工欲善其事,必先利其器 修改jupyter保存文件目录(亲测)

在桌面上创建 Jupyter Notebook快捷方式图标.将打开的Jupyter Notebook程序关闭,然后找到桌面快捷方式,右键>属性,然后把目标后面输入框最后的“%USERPROFILE%”这个参数去掉后,确定。否则之后做的其它修改无法生效。打开 cmd …

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

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

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

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

安卓APP_ 其他(1) —— 程序的签名打包并在手机上运行

摘自:安卓APP_ 其他(1) —— 程序的签名打包并在手机上运行 作者:丶PURSUING 发布时间: 2021-03-29 20:58:26 网址:https://blog.csdn.net/weixin_44742824/article/details/115310388 刚学到第四个控件&am…

计算机数据恢复专业,专业电脑数据恢复软件哪个好

原标题:专业电脑数据恢复软件哪个好在我们日常清理电脑时,有时会意外删除一些有用的文件,比如重要文件、照片等。这时就需要使用数据恢复软件尝试恢复数据。EasyRecovery是一款强大有效实现数据恢复的软件,软件占用空间小&#xf…

C#开发移动应用系列(2.使用WebView搭建WebApp应用)

C#开发移动应用系列(2.使用WebView搭建WebApp应用) 原文:C#开发移动应用系列(2.使用WebView搭建WebApp应用)前言上篇文章地址:C#开发移动应用系列(1.环境搭建) 嗯..一周了 本来打算2天一更的 - - ,结果 出差了..请各位原谅.. 今天我们来讲一下使用WebView搭建WebApp应用. 说明一…

new 一个模板、类_Java必备基础-类(Class)

你好,我是goldsunC让我们一起进步吧!类上一篇文章介绍了Java的基础数据类型和引用数据类型中的数组,引用数据类型除了数组之外,还包括类和接口。那什么是引用数据类型呢?看个例子:public class Test {publi…

华北电力大学计算机科学与技术考研,华北电力大学吴克河教授谈计算机科学与技术专业...

导语:读万卷书不如行万里路,行万里路不如名师点悟。选导师也是个大学问——择师而师,不可草草。为此我们特邀请众多精英导师,我们期待他们的亲身经历和观点建议,能够给考研路上的你以参考……华北电力大学计算机科学与…