USB学习笔记, 同时希望能帮助快速上手做USB应用开发. 整理自以下资料: 什么是USB从接口讲起对于终端用户来说,对USB最直观的认识就是USB的接口插头,看图: 现时间点大家最熟悉的几种USB插头莫过于USB2.0的TypeA、Mini-B、Micro-B;最近开始频繁露脸的USB3.0的TypeA、TypeC。 定义USB是Universal Serial Bus的缩写,中文译为通用串行总线,USB出现之前,计算机领域中的接口太多太繁杂,USB出现之后减少了接口的种类,总的来说就是设计出了一个万能的接口,各种外设都能用同一种接口,所以才冠以“通用(是Universal)”为名。 USB线缆特性
传输速度维基百科图: 版本历史维基百科图: 角色USB Host(USB主机)主机就是USB总线中作主设备角色的设备, 负责管理USB总线中的数据传输及端口管理. USB DeviceUSB Device就是在USB总线中作从设备角色的设备 USB Hub它的实现也就是USB扩展坞啦
USB系统架构USB Bus Interface Layer该层为硬件设备连接. USB相关的基础知识 - USB相关的硬件中有更详细的介绍.
USB Device Layer该层可以理解为USB总线的驱动层, 有关USB通讯的部分由这一层实现, 为上层提供服务. Function LayerFunction也就是除了Hub以外的Device, 它为整个系统提供了某些具体能力, 比如U盘为系统提供储存设备. 通讯机制搞USB开发, 我们关心的是Function Layer层通讯: 设备上Function通过Interface, 经由Endpoint与Client SW通讯. Interface看上面的架构图, 可知一个Function里可以有多个Interface, 比如一个键盘可以和摄像头做在一起, 用两个Interface实现. Pipe(管道)/Endpoint(端点)端点是Device中的概念, 有点像Socket通讯中的Port(端口), 用于区分USB总线中当的数据是哪个Interface的, 一个Interface可能使用了多个Endpoint. 端点是有方向的, 可以是IN(Device->Host)或者OUT(Host->Device). 端点可以理解成Deivce上的一个由USB Device管理的缓冲区, 数据到达后通知上层Interface来处理. 管道表示主机与端点间的通讯, 是Host和Endpoint间抽象的传输通道, 可以理解为USB地址(枚举时确定的地址)+EP编号构成, 由Host侧的System Drvier维护EP信息以便上层与Device通讯. 我们可以把端点和管道当做同一个东西. USB通讯实际上就是端点通讯,在Host看来每一个Device就是一堆端点, Host通过端点与设备进行通信,以使用设备的功能。每一个端点都有它的属性,比如传输方式(Transfers, 后面会讲)、总线访问频率、带宽、端点号和数据包的最大容量等。一个USB端点只能在一个方向承载数据,或者从主机到设备(称为输出端点),或者从设备到主机(称为输入端点),因此端点可看作一个单向的管道。 Packet (包) 和 事务(Transaction)包是在Pipe上传输的数据(包是由”域”组成的, 它是USB数据的最小单位, 这里不讨论). Transaction翻译成”事务”, 我理解为”一次通讯过程”, 分别有IN事务、OUT事务和SETUP事务三大事务, 每种事务通常由Token(令牌包)、Data(数据包)、Handshake(握手包)三个阶段构成,这里用阶段的意思是因为这些包的发送是有一定的先后顺序的:
上图就是典型的事务: 主机发Token–数据包–握手包–结束 USB是主从式总线, 所以所有事务都是由主机发送的Token开始, 任一时刻USB系统中仅有一个包在传输. 传输 (Transfers)传输由事务构成, Endpoint的传输方式可以是以下四种中的其中一种. Control Transfers (控制传输)
USB总线保证这种方式下数据不会丢失. 用于Device插入后配置/获取设备信息, 设备也可以自定用途, 比如用于查询设备状态. SETUP事务图示: 控制传输的Read/Write序列, 读写操作由一串有序的事务组成: Bulk Transfers (块传输)
用于可靠传输大量数据, 单次允许传输更多的数据(所以在Device中它们端点的缓存区会更大), 保证数据的正确性但不保证实时性(取决于总线的繁忙程度). Interrupt Transfers (中断传输)
用于少量数据的低延迟传输, Host以不低于Device指定的频率向设备发令牌请求数据, 也可以由Host向Device发送数据. Isochronous Transfers (同步传输)
用于传输大量数据, 不要求可靠性但要求实时性. 类似中断传输, 同步传输也是由Host周期访问设备, 只是同步传输不能保证数据成功传输. Class为了能让最常用的设备普及和提高兼容性, USB组织定义了很多标准Class, 比如HID(人体输入设备), Mass Storage(大容量储存设备), 这些设备接入Host上一般不需要额外的驱动, 因为已经预置了通用的驱动, 做USB应用很多时候都是在某个Class上做开发. USB接口设备Class文档可以找到各Class的文档 枚举既然USB是种通用串行口, 插入USB设备到主机之后, 主机又怎么知道插入的是什么设备(USB版本? PID/VID? 端点数量和传输能力如何?), 实现了什么功能呢(有哪些Function/Interface?), 把这些信息弄清楚的过程叫做枚举. 该部分内容对应协议手册的第9章. 设备状态设备状态图如下, 枚举就是从Attached状态转换到Configured状态的过程: 1、接入态(Attached):设备接入主机后,主机通过检测信号线上的电平变化来发现设备的接入; 2、供电态(Powered):就是给设备供电,分为设备接入时的默认供电值,配置阶段后的供电值(按数据中要求的最大值,可通过编程设置) 3、缺省态(Default):USB在被配置之前,通过缺省地址0与主机进行通信; 4、地址态(Address):经过了配置,USB设备被复位后,就可以按主机分配给它的唯一地址来与主机通信,这种状态就是地址态; 5、配置态(Configured):通过各种标准的USB请求命令来获取设备的各种信息,并对设备的某此信息进行改变或设置。 6、挂起态(Suspended):总线供电设备在3ms内没有总线操作,即USB总线处于空闲状态的话,该设备就要自动进入挂起状态,在进入挂起状态后,总的电流功耗不超过280UA。 端点0
所有USB设备需要实现一个默认的控制方式, 它就是既能输入也能输出的端点0, Host通过这端点0获取设备的描述、配置、状态,对设备进行设置。 端点0在Device上电后就默认存在, 这是STM32HAL库中重置USBD的代码, 可见对EP0_IN和EP0_OUT进行了配置: 可见, 端点0实际上是IN/OUT两个端点, 以控制传输(Control Transfers)的方式通讯. Generic USB Device Operations(通用USB设备操作) / USB Device Requests(USB设备请求) / Standard Device Requests(标准设备请求)通过端点0, Host可以使用一些”默认的控制方式”完成一些基本的操作, 每个Device都要实现这些操作, 这就是”通用USB设备操作”. 阅读bmRequestType定义可知, “USB设备请求”允许Host通过端点0使用控制传输方式向USB设备发出请求, 这些请求可以是”标准设备请求”/“Class求”/“设备制造商自定义请求”. “标准设备请求”是”通用USB设备操作”的具体实现, 它规定了一些命令比如”Set Descriptor”(获取描述符)/“Set Configuration”(设置配置索引), 使用这些命令可以完成枚举过程(但不仅用于枚举). Descriptors (描述符)描述符储存在设备中, 有几种描述符储存着设备的各种信息, 枚举过程中主机通过标准设备请求从设备获取这些描述符.
各类描述符的具体定义请参考USB2.0协议手册9.6章及其他资料. 配置描述符集合主机获取配置描述符时, 接口描述符/端点描述符/等等相关的描述符附着在它后面一同提交. 梳理一下Endpoint/Interface/Configuration间的关系:
假设一个配置集合包含2个Interface, 均为XXX Class, 每个Interface两个Endpoint, 那么它大概是这个样子:
枚举过程这部分在USB基础知识概论的4.4章中讲得很清楚了, 这里为了防死链复制一份pdf. 其他资料和工具协议文档对于工程师来说, 文档永远是你最值得信任的伙伴(除了文档还太新没几个勘误表的时候..). <圈圈教你玩USB>这本书很大白话, 实现了HID鼠标/HID键盘/CDC串口/MIDI设备/U盘/自定义设备和驱动开发, 推荐. USBTreeView免费/开源软件, 显示USB设备树形结构, 显示设备连接信息/描述符, 枚举时调试比较方便. BusHound强力的调试工具, 能抓USB包, 免费版只能捕获最多32条数据, 每条数据最多8字节, 完整版价格400刀每用户. USBlyzer官网 USB论坛提供的工具 |
|
来自: xingwangjy > 《嵌入式》