USB原理简单叙述
USB简介:
USB的几种版本:
1. USB 1.0:速度 1.5Mb/s
2. USB 1.1:速度 12Mb/s
3. USB 2.0:速度 60MbB/s
4. USB 3.0:速度 640MB/s
USB的主要优点:
1. 可以热插拔:不需要重复“关机将并口或串口电缆接上再开机”的动作。
2. 携带方便。
3. 标准统一,USB鼠标,USB硬盘,USB打印机都是用同样的标准与个人电脑连接。
4. 可以连接多个设备:可以使用USB HUB不断级联(最高可以连接127个设备)。
USB类型(仔细一看还真不少):
一个正常的USB接口的引脚说明如下:
USB系统结构:
一个USB的系统拓扑结构包含:主机,根集线器,集线器,设备。
主机:对于每个USB系统来说,都有一个成为HOST控制器(就是上图的主机)的设备,该HOST控制器和一个根HUB最为一个整体。这个根HUB下面又可以级联多级的BUB。USB主控制器负责处理主机与设备之间的电器盒协议层互联。常见的USB主控制器规格有:
OHCI:主要是非PC系统上的USB芯片。如ARM。
UHCI:大多是intel和via主板上的USB控制器。他们是USB1.1规格。
EHCI:USB2.0规格,兼容OHCI和UHCI。
根集线器:每个USB Host控制器都会自带一个USB Hub,被称为根集线器。这个根HUB可以接子HUB,每个HUB上挂在USB设备。通过外接USB Hub,可以插更多的USB设备。当USB设备插入到USB Hub或从上面拔出时,都会发出电信号通知系统。
USB设备:USB设备就是插在USB总线上工作的设备,广义上讲USB Hub也算是USB设备。
一个USB设备的逻辑结构如下:
每个USB设备都可以包含一个或者多个配置,不同的配置使设备表现出不同的功能组合(在探测/连接器件需从中选择一个),配置有多个接口组成。在USB协议中,接口由多个端点组成,代表一个基本的功能。看下面的一个例子:
貌似其他的都比较好理解,主要是端点的概念,端点是USB设备中唯一可寻址部分,它是位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据。主机与设备的通信最终作用于设备的各个端点,它是主机与设备间通信交流的一个逻辑终端。
设备枚举:基于pnp机制,设备被枚举时,他必须向主机报告各个端点的特性,包括端点号,通信方向,端点支持的最大包大小,带宽要求。
端点0:每个设备必须有端点0,他用于设备枚举和对设备进行一些基本的控制功能。除了端点0,其余的端点在设备配置前不能与主机通信。
每个USB设备有一个唯一的地址,这个地址实在设备连接上主机时,由主机分配的。而设备中的每个端点在设备内部有唯一的端点号。
USB设备描述符:
当我们把USB设备查到我们的主机上的时候,主机能够自动识别出我们的USB设备类型。就是依靠的USB设备描述符。
就好比每一个PCI设备中,都有这么一组固定格式的配置寄存器,通过这组寄存器,主技能获取PCI设备的信息。在每一个USB设备内部,同样也包含了类似于PCI寄存器这样的固定格式的数据,通过这些数据,USB主机就可以获取USB设备的类型,生产厂商等数据。这组固定格式的数据,我们就称之为USB描述符。标准的USB设备有5种描述符:
1. 设备描述符
2. 配置描述符
3. 接口描述符
4. 端点描述符
5. 字符串描述符
一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个使用了几个端点,就有几个端点描述符。
USB数据传输:
USB传输:针对设备对系统资源要求的不同,在USB规范中规定了4种不同的数据传输方式:
1. 等待传输
2. 中断传输
3. 控制传输
4. 批量传输
控制传输:控制传输主要用来传输设备控制命令,设备状态查询及确认命令。当USB设备接收到这些数据和命令后,将依据先进先出的原则按队列方式处理到达命令。
中断传输:该方式传输的数据量很小,但是这些数据需要及时处理,以达到实时的效果,此方式主要用在键盘,鼠标以及游戏手柄上。注意,这个中断并不是硬件上的中断,因为USB的通信只能有主设备发起,所以这个中断实际上是主设备不断地查询。
等时传输:该方式用来连接对数据的正确性要求不高而对时间极为敏感的外部设备。如麦克风等。等时传输以固定的传输速率,连续不断的在主机与USB设备之间传输数据,在传输数据发生错误的时候,USB并不会处理这些错误。
批量传输:该方式用来传输要求正确无误的数据。通常打印机,扫描仪和数码相机以这种方式与主机连接。
下面粗略的说一下USB抓包工具抓的包的格式,为以后做准备:
USB的数据传递首先是基于Transfer(传输)的:中断传输,批量传输,同步传输,控制传输。
一个transfer由一个或者多个事务(transaction)构成,事务可以分为in事务,out事务,setup事务。
一个事务由一个或者多个packet(包)构成,包可以分为令牌包(setup),数据包(data),握手包(ACK)和特殊包。
一个包可以由多个域构成,域可以分为同步域(SYNC),标示域(PID),地址域(ADDR),端点域(ENDP),帧号域(FRAM),数据域(DATA),校验域(CRC)。
USB设备枚举:
USB设备在正常工作之前,第一件要做的事情就是枚举。枚举是让HOST认得这个USB设备,并且为该设备准备资源,建立好主机和设备之间的数据传递机制。
一个设备枚举的过程分为如下8步:
1. 获取设备描述符
2. 复位
3. 设置地址
4. 再次获取设备描述符
5. 获取配置描述符
6. 获取接口,端点描述符
7. 获取字符串描述符
8. 选择设备配置
下图是接入一个USB鼠标之后完整的枚举过程:
下面,我们来逐步分析:
获取设备描述符:
传输0的第一个事务如下:
可以看出,这是一个setup事务,设备要执行的命令就是GET_DESCRIPTOR,也就是获取描述符。
其中分为三个包,第一个令牌包和第二个数据包为主机传输给设备。第三个握手包为设备传输给主机。
主机发送完令牌包,下一个数据包包含的就是命令了,主要分析一下第二个包数据包中的DATA字段。Data中总共有16位,每位的含义如下(USB协议报文是小端模式!!!):
因为USB是小端模式,所以从最低到最高分析:
0x80:表示期望的数据传输方向为设备传输给主机,这条命令的接收者为设备。
0x06:代表了一个命令,根据table9-3,可以得知,代表的命令为获取描述符。
0x00 0x01:值为1,这两个字节中的高字节代表type,根据下表可查出type为device,所以结合上一字节得出结论:该命令想要得到的描述符为设备描述符。
传输0的第二个事务如下:
这是一个in事务,是设备把自己的描述符传递给主机,可以看出,还是由主机先发起连接,然后设备发送设备描述符,最后主机给出ACK握手包。
传输0的第三个和第四个事务是在继续传输设备描述符
传输0的第五个事务为按照协议发送的,没有实质意义。
复位:
这个包是发送复位命令。
设置地址:
设置地址由传输5和传输6构成。传输6为协议要求,没有实质意义。主要分析传输5的data.
第二个字节为0x05,根据查表可知代表的意义为set_address,当命令为set_address的时候,根据手册可以得出data的格式是这样的:
再次获取设备描述符:
这个过程和第一次获取设备描述符一样,对于usb鼠标这种设备描述符比较简短的设备这个步骤不是必须的,但是对于某些设备描述符比较长的设备第一次只获取部分描述符,这一次才会获取完整描述符。顺便补充一句,软件自动解析的设备描述符是这样滴:
获取配置描述符:
事务12中第二个包,根据其第二个字节可知这是一个获取描述符的命令,根据其第四字节可知获取的描述符类型为。
事务13和事务14为设备向主机发送配置描述符。
获取接口,端点描述符:
看到这有个小疑问,事务16中不是获取配置描述符的格式吗????视频里说接口端点描述符在配置描述符中一起获取出来了,现在对协议还是很模糊….
获取字符串描述符:
传输5用来获取字符串描述符:
事务23中第一个包是令牌包,感觉令牌包的作用就是主机用来发起连接。第二个包是数据包,根据第四个字节0x03,可以知道他获取的是字符串描述符。第三个包为设备发送给主机的握手包。
事务24中有设备将字符串描述符发送给主机。
事务25为协议要求,没有实际意义。
传输6和传输7也是用来获取字符串描述符,但是看一看到,不同获取的描述符序号不一样。
选择设备配置:
可以看出,其data选项中第2个字节是0x09,代表set_configuration。根据set_configuration的指令格式:
可以得知,主机选取的是1号配置。
这条有点晕,明明是set传输,但是0x0a是get_interface啊,不过我认为这一步应该是设置接口。
至此,USB鼠标枚举过程结束!
USB原理简单叙述的更多相关文章
- USB OTG简单介绍
1 引言 随着USB2.0版本号的公布,USB越来越流行,已经成为一种标准接口.如今,USB支持三种传输速率:低速(1.5Mb/s).全速(12Mb/s)和快速(480Mb/s),四种传输类型:块传输 ...
- wp7之换肤原理简单分析
wp7之换肤原理简单分析 纠结很久...感觉勉强过得去啦.还望各位大牛指点江山 百度找到这篇参考文章http://www.cnblogs.com/sonyye/archive/2012/03/12/2 ...
- jQuery插件实现的方法和原理简单说明
下文来自 http://www.itzhai.com/jquery-plug-ins-to-achieve-the-methods-and-principles-of-simple-instructi ...
- LDAP服务器的概念和原理简单介绍
LDAP服务器的概念和原理简单介绍 1. 目录服务 目录是一个为查询.浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样.目录数据库和关系数据库不 ...
- Docker系列之原理简单介绍
目录 1.1.Docker架构简介 1.2.Docker 两个主要部件 1.3.虚拟机和Docker对比: 1.4.Docker内部结构 Docker系列之原理简单介绍 @ Docker是一个开源的应 ...
- 锐速与BBR的原理简单解析
锐速与BBR的原理简单解析 4 前言 昨天,有一位朋友在我的文章下留言说,锐速和BBR不都是一样,是拥塞算法嘛.因为这方面需要讲的东西比较多,所以我还是专门水一篇文章吧. 锐速 参考资料: http ...
- AbstractRoutingDataSource 实现动态数据源切换原理简单分析
AbstractRoutingDataSource 实现动态数据源切换原理简单分析 写在前面,项目中用到了动态数据源切换,记录一下其运行机制. 代码展示 下面列出一些关键代码,后续分析会用到 数据配置 ...
- ThreadLocal原理简单刨析
ThreadLocal原理简单刨析 ThreadLocal实现了各个线程的数据隔离,要知道数据是如何隔离的,就要从源代码分析. ThreadLocal原理 需要提前说明的是:ThreadLocal只是 ...
- View的滚动原理简单解析
一直对View的滚动了解的不深,说明确了吧也能说出个所以然来,所以我就花了点时间做了一个小小的总结,言归正传,view的滑动分为下面三种: 1)View本身不滚动,指滚动View的内容,这也是View ...
随机推荐
- SFTP服务配置以及命令/代码操作
POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or ...
- Egret的第三方库制作,以及在大型项目中的应用
目录: 一 创建第三方库 二 TypeScript库 三 JavaScript库 四 第三方库制作在大型RPG中的实际应用 参考: 第三方库的使用方法 目标: 本文目的是将现有游戏的框架制作成第三方库 ...
- spring @Transactional的自调用失效问题与事务的典型错误用法剖析
@Transactional的自调用失效问题 有时候配置了注解@Transactional,但是它会失效,这里要注意一些细节问题,以避免落入陷阱. 注解@Transaction的底层实现是Spring ...
- LeetCode_371. Sum of Two Integers
371. Sum of Two Integers Easy Calculate the sum of two integers a and b, but you are not allowed to ...
- NETTY 心跳机制
最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github上的开源代码Jupiter,写的RPC框架让我感叹人外有人,废话不多说,下面的代码全部截取自Jupiter,写了一 ...
- 使用jsPlumb插件实现动态连线功能
这周去看了两天的羽毛球亚锦赛,工作有提前晚上加班做一些,但是技术文章却拉下了. 这段时间一直在寻找可以实现前端元素动态连线的功能,找了好几个库,考虑过用d3或者原生svg和canvas来实现,最后和同 ...
- 由于我最近搞了个wordpress搭建博客,这里我为大家分享一哈,使用wordpress过程中遇到的坑
Windows server下搭建mysql+php+apache环境参考教程: https://blog.csdn.net/qq_38125058/article/details/81157865 ...
- R画柱形图和箱线图
数据格式如下 gene_id Sham-1 Sham-2 Sham-3 Sham-4 Sham-5 Rep-1h-1 Rep-1h-2 Rep-1h-3 Rep-1h-4 Rep-1h-5 Rep-3 ...
- JWT知识整理
JSON Web Token:(https://jwt.io/) JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑(Compact)且自包含(Self-co ...
- 1181: 零起点学算法88——偶数求和(C语言)
一.题目: 题目来源WUSTOJ 二.源代码: #include<stdio.h> int main() { int n, m, num, sum, i, j, k; while (sca ...