主设备和从设备
usb通讯的两端分别称为:HOST(主设备/USB主机)和device(从设备/USB设备)
常见的usb主机: 计算机
usb主机架构
客户软件负责和usb设备的功能单元进行通信,用于实现其特殊供功能,比如:传输文件,播放声音。一般是专用的,根据设备的不同而不同,需要开发人员自行编写。
客户软件: 分为驱动程序和界面应用程序两个部分
驱动程序对接usb系统软件,告知usb收发的数据内容,启动一次usb数据传输。
界面应用程序是最上层的软件,是和驱动程序直接对接,提供可视化操作,可以看到向usb设备的原始数据以及从USB设备接收的最终数据。
usb系统软件: 负责和usb逻辑设备进行配置通讯,并配置主机资源,设置usb参数,根据带宽安排传输队列等。 主要由操作系统执行
usb总线接口: 一般包括usb主机控制器和根集线器两部分。
主机控制器:用于完成主机和usb设备之间的实际传输
根集线器: 实现了主机控制和其他usb设备的连接
usb主设备一般具有以下功能:
- 检测usb设备的插拔动作
- 管理主从通讯之间的控制流
- 管理主从之间的数据流
- 记录主机状态和设备动作信息
- 控制主控制器和usb设备间的电器接口
usb设备按照功能分类: 集线器和功能设备
集线器:
- 用于扩展usb主机的usb端口
- 结构上有一个上行端口,多个下行端口
- 支持级联,系统中最多5个集线器
- 支持速度转换
usb功能设备:
- 一个独立的外围设备,可以是单一功能也可以是多功能的合成设备
- 内部包含有描述自身功能和资源需求的配置信息。
usb设备架构:
使用设备前,必须由主机指明采用哪个配置,哪个接口。usb设备通过描述符来说明其架构中的各种属性,有设备描述符,配置描述符,接口描述符和端点描述符等等。一个设备只会有一个设备描述符,如果是高速设备,既支持高速传输也支持全速传输,那么还需要支持限定描述符,用于指出另一传输速度下的设备总体信息。
使用usb设备前,必须选择一个合适的配置,虽然有多个配置, 但是当前只有一个配置生效。如果是高速设备,既支持高速,也支持全速传输,则必须还要支持其他的速率配置描述符,用于指出另一传输速度下的设备配置信息。
接口描述符用来说明功能属性的,比如usb声卡设备,有两个接口,一个为麦克风接口,一个为耳机输入接口。而且多个接口可以共存的,有几个接口,就有几个接口描述符。
端点是实际的物理单元, usb数据传输就是在usb主机和设备的各个端点之间进行传输的。有多少个端点就有多少个端点描述符。
在usb系统中,一般USB主机通过集线器(HUB)进行usb设备扩展,以层次性的星型拓扑结构进行物理连接。
一个usb功能设备最多通过五级集线器连到usb主机上。有些usb设备内部包含了一个集线器,这种既包含了一个集线器,又包含了usb的设备的usb设备,称之为复合设备。
usb主机和usb设备通信在软件协议上具有如下特征:
- 主机和usb设备之间通讯物理通道:主设备分配的地址/默认地址0+从设备固有端点号
- 主机和usb设备之间时间长度单位: 帧/微帧
- usb主机和usb设备之间协议处理基本单位: 事务处理
- usb主机和usb设备之间通讯: 在基本单元”事务“中,主机总是发起者,并且和设备交互应答方式进行通讯。
连接和检测
usb主机和usb低速设备的连接示意图
usb主机端口的d+d-线上都有15k的下拉电阻,当主机没有连接设备时,在下拉电阻的作用下,这个d+和d-的电压都是近地(0V), 也就是se0状态,此时usb主机检测到se0状态维持了至少2.5us, 会认为没有设备连接。当低速设备连上以后,在usb设备端口的d-线上有1.5k的上拉电阻,此时设备上的上拉电阻和主机d-线上的下拉电阻构成分压,所以在d-线上会出现3v左右的电压,而d+上仍然是0v. 就是差分0状态。此时主机检测到这个状态维持2ms, 认为有设备连接。并且当前设备是低速设备。
总结如下:
- usb主机端口在D+和D-上都有15千欧电阻接地
- 低速USB从设备在D-上连有1.5千欧的电阻到3.0-3.6v电压
- 没有连接: 主机端口检测到D+和D-电压都近地0V
- 低速设备连接: 主机端口检测到D-电压约3v, D+电压近地0V
usb主机和usb全速设备的连接示意图
当全速设备连上以后,在usb设备端口的d+线上有1.5k的上拉电阻,此时设备上的上拉电阻和主机d+线上的下拉电阻构成分压, 所以在d+线上会出现3v左右的电压,而d-上依旧保持0V,这就是差分1状态。此时主机检测到这个状态维持2ms, 认为有设备连接
总结如下:
- usb主机端口在D+和D-上都有15千欧电阻接地
- 低速USB从设备在D+上连有1.5千欧的电阻到3.0-3.6v电压
- 没有连接: 主机端口检测到D+和D-电压都近地0V
- 低速设备连接: 主机端口检测到D+电压约3v, D-电压近地0V
usb主机和usb高速设备的连接示意图
与高速设备的连接比较特殊,它分为高速主机和高速设备,他们之间是一个双向检测,高速主机端口需要检测连接上来的usb设备是低速,全速还是高速,而高速设备同样也需要检测对应连接的主机是全速还是高速主机。
usb高速主机和usb高速设备识别过程
一开始,USB高速设备以一个全速设备的身份出现,设备连接后,d+和d-的压差为3.3v, 由于d+被拉高,告知主机有一个全速的设备接入,这个适合主机端口会输出总线复位信号,d+d-都会拉低,设备看到复位信号后,会通过内部的电流源向d-持续灌输大概17ma左右的电流,在本身线路等效阻抗为40Ω的终端电阻下,会产生大概800mv的电压,我们称之为chirp K信号,这个信号大概持续时间1ms-7ms, 当高速主机检测到这个chirp K信号后,它会在设备发送这个chirp K信号后的100us内,开始回复一连串的kjkjkj的序列,这个序列就是向设备表明,我是一个usb2.0的高速设备的主机,这里的kj信号是连续的,中间是不能间断的,而且每个K或J的持续时间大概是在40-60us之间,高速主机发送这个chirp K信号的方式和设备一样,都是通过电流源向差分数据线交替灌输17ma的电流实现的,所以看到电压都是800mv,如果当前是一个全速的设备,它就不会发出这个chirp K信号,也就说明这个chirp K信号是设备高速usb主机我是一个高速设备,对应如果是一个全速的主机,是不支持高速操作的,那么它也不会再chirp K信号结束后,给出如下图的KJ序列。 所以这种KJ序列是由USB主机告知设备我是一个高速主机。
高速设备初始是以一个全速设备出现的,所以D+上会有1.5K的上拉电阻,当主机和设备都知道对方是高速后,会断开d+上的上拉电阻,连接d+d-上的高速终端电阻,然后再500us内切到高速模式。当它连上了高速终端电阻以后,也就是在3对KJ信号之后,电阻进行了减半,但电流不变,所以这里的电压减半,变成了400mv。所以device applies termination这个点可以认为是usb高速设备从全速切到高速状态的一个分界点。
总结如下:
- 高速设备先以全速设备结构和主机相连,他们之间做双向检测
- 主机输出总线复位信号期间,usb设备以是否可以产生chirp K信号来表明高速或全速身份
- 在chirp K信号后,主机是否发生KJ信号来表明高速主机身份或者是全速主机身份
- 匹配到高速主机和高速设备后,USB设备断开D+上的1.5KΩ的上拉电阻,连接d+和d-上的高速中断电阻,进入默认的高速状态,否则以全速状态通讯。
usb设备插拔,以及速度检测的结果:
- 设备断开: 主机检测到d+和d-上近地状态(0v), 并持续在2.5us以上
- 设备连接: 主机检测到d+或d-上有高电平(3V), 并持续2ms以上
- 低速设备: 主机检测到d-上有高电平
- 全速设备: 主机检测到d+上有高电平(有可能为告诉设备)‘
- 高速设备:主机检测到d+上有高电平,然后通过一系列协商握手信号确认双方身份(双向检查)
总线的几种状态
常见的几种状态 | 描述 |
---|---|
正常工作 | 总线上存在周期性的sof(每个帧开始的sof包)包, 当主机和usb设备连接后, 如果不操作设备,但是设备仍然挂载在设备的端口下面,需要随时进行传输,那么此时usb总线处于正常工作状态。 在全速中1ms一次,高速中125us一次 |
总线复位 | 总线维持SE0状态 > 10ms, 就是由主机控制器或者集线器的下游端口产生,用于驱动d+和d-都处于0V,就是se0状态,并且大于10ms, 这个动作一般都是主机和设备刚连接后,主机控制器或者集线器的下游端口发出,属于usb通讯协议的复位。在一些传输出错的异常情况下,也会出现这个复位动作,这点有点类似于我们芯片使用的上电复位,以及出错后的手动复位的意思 |
总线挂起 | 总线无活动 > 3ms, 当usb总线上持续J状态超过3ms, 就认为处于总线挂起,这个时候主机控制器或集线器的下游端口会停止所有的传输,包括sof令牌包。 而usb检测到这个状态并且持续一段时间后,就可以选择是否将自己进入挂起,比如切换到低功耗模式 |
常见的几种变化 | 触发点 |
---|---|
无连接---->连接 | D+/D-上出现高电平 > 2ms |
正常—>挂起 | J状态保持 > 3ms |
挂起—>正常(唤醒) | 出现K状态信号并持续一段时间,唤醒包括主机唤醒usb设备和设备远程唤醒usb主机两种方式:之后usb主机和设备处于正常工作状态,主机控制器和下游端口正常发出sof包 |
信号传输状态
J 状态(差分) K状态(差分) SE0状态(单端) SE1状态(单端)
状态 | 差分0: D+≈0v D-≈3v 差分1: D+≈3v D-≈0v |
---|---|
J状态 | Low Speed : 差分0 Full Speed:差分1 |
K状态 | Low Speed : 差分1 Full Speed: 差分0 |
SE0状态 | D+和D-都为0V |
SE1状态 | D+和D-状态都大于0.8V |
枚举过程
usb通讯分为两个阶段: 1. 枚举传输阶段 2. 用户数据通信阶段
枚举:枚举过程是所有usb设备连接主机后都必须要经过的一段数据传输,在这个阶段,主机会了解usb设备的信息结构,类别属性,并启用usb设备的每个配置和功能, usb主设备向usb从设备通过获取各种描述符,从而了解设备属性,知道是什么样的设备,并加载对应的USB类,功能驱动程序,然后进行后续一些列的数据通信。
枚举过程的特点:
- 主设备连接识别从设备必须的过程
- 由多个控制传输构成
- 经过地址0(缺省地址)到其他地址(主设备分配地址)的通讯
- 对于挂载多个usb从设备的系统,主设备是逐一进行枚举操作
枚举过程:
- usb设备上电(一般从usb口取电)并连接到usb总线
- 主机检测到总线上有设备连接
- 主机会等待100ms用户机械,电器特性稳定
- 总线执行总线复位至少10ms, host向device发送了bus reset使设备进入了default状态,从此设备可以响应默认地址0, 高速设备在复位期间和usb设备进行握手,完成速度切换,并得到USB设备通讯速度
- 主机驱动总线空闲至少10ms用户恢复时间
- 主机发出获取设备描述符请求(缺省地址),要求device发送64字节
- 主机在收到设备描述符的前18个字节后,可再次向设备发送bus reset, 主机为从设备分配唯一设备地址,后续通讯用此地址
- 主机以新地址发出获取设备描述符请求
- 主机以新地址发出获取配置描述符请求,获取设备全部配置
- 主机分析获取的描述符信息,并作相应记录和处理
- 主机发送设置配置请求,为从设备选择一个合适的配置
设备描述符
- 设备描述符: 第一个需要获取的描述符,长度固定18字节
- 配置描述符: 描述了设备特定的配置,提供了当前配置下设备的功能接口,供电方式,耗电等信息。是一个配置的集合,集合长度不固定,包含了配置描述符,接口描述符,类定义描述符,端点描述符。
控制传输
- 是所有USB从设备必须支持的传输方式,固定使用端点0通讯
- 控制传输的方向是双向的,既可以主机下传数据给设备,又可以从设备上传数据
- 多用于主设备和从设备进行信息,功能,状态等方面的获取和修改。
控制传输可以分为三种结构,每种结构都是由多个事务构成
- 控制写:分为建立阶段,数据阶段和状态阶段。 建立阶段是由一个setup事务构成,数据阶段是由一个或多个out事务构成,最后一个状态阶段由一个IN事务构成
- 控制读:分为建立阶段,数据阶段和状态阶段。 建立阶段是由一个setup事务构成,数据阶段是由一个或多个IN事务构成,最后一个状态阶段由一个OUT事务构成
- 无数据控制: 只有建立阶段和状态阶段,建立阶段是由一个setup事务构成,状态阶段由一个IN事务构成
- 后面括号中的0/1指的是pid类型,事务由多个包组成,如果包中存在数据,这个数据分类,分为data0/1数据包 ,这个0/1就是表示其中表示的是data0数据包还是data1数据吧
- 其实setup包一定是data0, 末尾的状态包一定是data1, 中间数据传输一定是1打头,然后0/1反转
建立阶段 – Setup事务
- 固定的8字节数据结构
- 重点的数据吧哦的PID - DATA0
- 应答包必须为ACK
数据阶段 – 一个或多个连续的IN/OUT事务
- 不是必要阶段
- 控制都—连续IN事务, 控制写 — 连续OUT事务
- 事务数据包从PID_DATA1开始,然后进行1-0-1-0-…交替翻转
- 应答包支持ACK/NAK/STALL
状态阶段 — 一个IN/OUT事务
- 数据包长度为0
- 数据包的PID – DATA1
- 执行的事务和数据阶段事务相反
- 没有数据阶段,执行IN事务