浅谈USB的枚举过程

这篇具有很好参考价值的文章主要介绍了浅谈USB的枚举过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述

USB 枚举,在有些资料中,认为是插入USB后,USB 设备被分配到新的设备地址,就可以认为枚举结束,这可能是更准确的定义,但为了更好的说明,也可以把插入后的整个交互过程都称为枚举,也就是设备能被主机正确识别,可以被上位机使用了。

二、USB 设备状态

USB 枚举完成之前,USB 设备要经过一系列的状态变化,才能够最终完成枚举。在 USB 设备接入主机到枚举完成的过程可分为以下的状态变化:连接状态、供电状态、默认状态、地址状态、配置状态、挂起状态,其中,当设备变成配置状态时,即可认为 USB 设备和 USB 主机间的枚举完成。

  • 首先,连接状态指的是 USB 设备需要先和主机建立起物理上的连接,USB 设备检测是否连接到主机以及 USB 主机检测是否有 USB 设备连接是 USB 协议能够进行后续工作的前提。简单说来,检测连接状态的必要条件就是在 USB 设备接入时某些状态发生了变化。USB 硬件和协议上可通过检测 VBUS 、D+、D- 这些信号线的电平信号状态来进行检测连接的方法,当然,USB 主机和设备也必须要具有检测断开的能力。关于检测连接的具体协议部分,大家感兴趣的可以去详读 USB协议规范对应章节,在此不在赘述。

  • 供电状态,USB 设备可以从 USB 的 VBUS 上获取电源,或者通过外部电源获取电源,这一种称为自供电设备。而我们比较常见的是通过 VBUS 供电的设备称为总线供电设备。

  • 默认状态指的是 USB 设备进入供电状态后,在被复位之前,不能响应总线上的任何事务。只有当 USB 设备被复位,处于默认状态后,才会响应主机发送过来的请求。

  • 地址状态,指的是 USB 设备在被复位后,且在 USB 主机给 USB 设备设置一个新的地址之前,所有的 USB 设备都使用默认的 0 地址与主机进行通信。当 USB 设备在收到主机发送的设置地址请求之后,USB 设备就会得到一个唯一的地址。USB 设备会一直保存这个地址并使用它与主机进行通信,直到设备被复位或者断开。即使 USB 设备在获取唯一地址之后进入挂起状态,设备依然会保留这个地址,并在总线恢复后继续使用该地址。在设备挂起期间,主机也不能把该唯一地址分配给其他的 USB 设备。

  • 配置状态,指的是在 USB 设备功能能够使用之前,USB 设备和 USB 主机必须协商确定功能相关的配置项,所有的配置项都以描述符的形式提供,其中配置状态所需的描述符主要有以下 6 种:
    设备描述符、配置描述符、字符串描述符、接口描述符、端点描述符、设备限定描述符,当然,这里还有一种特殊的描述符称为接口关联描述符,用于将一组有关的描述符关联起来共同描述符一个特定的功能。USB 主机通过获取描述符请求来获得 USB 设备相关的描述符,通过设置接口和设置配置来设置设备的相关配置项。一旦相关功能参数被配置后,USB 设备就可以正常工作了。正常的 USB 设备在收到 USB 主机发出的复位信号后会进入默认状态,之前所指定的地址、所配置的接口和配置项都将无效,需要由 USB 主机重新指定设备地址,获取描述符并配置相关配置项,才能够使设备重新工作。

  • 挂起状态,指的是 USB 设备在 USB 总线持续 3ms 没有活动时,设备就会自动进入挂起状态。有挂起则意味着有恢复状态,这两个状态切换时 USB 协议实现低功耗的一种机制。进入挂起状态后,USB 设备要维持所有的内部状态。

三、USB 枚举流程

根据上面的状态变化过程,我们可以对 USB 协议进一步的了解。当 USB 主机检测到 USB 设备插入后,就要对设备进行枚举了。其实枚举的作用就是通过协议读取设备的相关信息,知道设备是什么样的设备,然后进行通信,这样主机端就可以根据这些信息安装合适的驱动程序了。USB 设备状态从初始的连接状态到最终的配置状态的变化过程就是整个枚举流程。

枚举流程可分为以下几个步骤:

  • 获取设备描述符
  • 设置设备的地址
  • 获取完整设备描述符
  • 获取配置描述符
  • 获取字符串描述符
  • 获取限定描述符
  • 配置设备的配置描述符
  • 获取设备描述符,这是开始枚举的第一步,主机通过获取描述符请求来获取设备的描述符,对于高速设备和低速设备,用于控制传输的端点 0 支持的最大包长度是确定的,分别是 64 和 8 字节,但对于全速设备,端点 0 支持的最大包长度可以是 8、16、32、64 字节,在 USB 主机获取到设备的设备描述符之前,USB 主机无法确定 USB 设备端点 0 的最大包长度,这样 USB 主机获取设备描述符的请求有可能不能正常完成。

  • 在双方通信前,USB 主机必须要指定端点 0 上的最大包长度,以便于正确检测控制传输种数据阶段的结束,假设 USB 主机端指定的 USB 端点 0 的最大包长度为 64 字节,而实际的 USB 设备端点 0 的最大包长度为 8 字节,由于 USB 设备描述符长度为固定的18 字节,当主机发送第一个获取设备描述符请求时将会要求设备端发送 18 字节的数据,USB 设备在收到请求后,准备发送 18 字节的数据,但实际最大包长度为 8 字节,所以 18 字节需要分三个事务去发送完成,但主机端指定的最大包长度为 64 字节,当主机接收到第一个 8 字节的事务时,就认为数据阶段已经完成,而 USB 设备此时正在准备发送第二个 8 字节的事务,导致这个控制传输由于双方的通信状态不同步而无法正常完成。这也是复位后主机为什么需要再次获取设备描述符,也就是上面说到的针对一些 USB 设备,设备描述符可能需要分多次获取,这样有可能获取的描述符是不完整的,而复位后是要获取设备描述符的全部 18 字节。

针对这个问题,不同 USB 主机的做法也有些不同。

  • 比如 Windows 7 系统在第一次获取设备描述符后,直接进行复位,将设备状态重置为初始状态。而由于设备端所支持的最小的最大包长度为 8 ,此时主机一定能获取到设备描述符的前 8 个字节,而设备描述符的第 8 个字节就是设备端点0所支持的最大包长度,所以主机可以在后续的控制传输中使用这个设备端的最大包长度来保证双方正常通信。
    而 Ubuntu 的 USB 主机做法则有些不同,主机端第一次获取设备描述符只获取其前 8 字节,不管 USB 设备端点的最大包长度是多少,USB 设备只能发送 8字节的数据,同时通信双方同步结束数据阶段。之后 USB 主机读取 USB 设备描述符的第 8 个字节,得到设备端点0的最大包长度,用于后续的控制传输。
  • 设置设备的地址,主机发送设置地址请求来设置设备的地址,请求中的 Setup 数据内包含主机为设备分配的新地址,设备收到地址后,进入地址状态,在该设备未复位或断开之前,设备会一直使用该地址与主机通信,在本次传输中,USB 主机和设备都仍然使用地址 0 进行通信。在设备收到设置地址请求后,必须要在 50ms 内处理该请求并完成该请求的状态阶段,在完成状态阶段后,可以有 2ms 的恢复时间,在这个时间内 ,USB 主机不能使用其刚刚指定的地址与设备通信,在这个时间之后,设备必须要使用该新地址与主机进行通信,同时,设备不能对发送到旧地址的任何请求产生回复,除非新旧地址一致。

  • 获取完整设备描述符,前面我们讲到了设备描述符部分,并且在上面的新地址设置完成后,主机与设备将会用新的地址通信,USB 主机会用新地址与设备进行通信,来获取完整的 18 字节的 USB 设备描述符。USB 设备描述符的第 18 字节表示该设备配置描述符的数目。

  • 获取配置描述符,由于每个设备配置描述符的长度都不一样,USB 主机无法提前得知设备的配置描述符长度,因此配置描述符的数据中必须要有表示长度的部分,由于第 9 字节代表该配置下 USB 设备的最大消耗电流值,因此主机将会先获取配置描述符的前 9 个字节,若该配置下的最大消耗电流值超过了 USB 主机可提供的额度,该配置将不可用,如果设备中的所有配置都不可用,该设备也会不可用,这将会中止整个枚举流程。

  • 获取字符串描述符,该部分主要包括了设备的一些字符串格式的信息,如设备制造商、产品信息和序列号、语言种类等。

  • 获取限定描述符,USB 主机可能会尝试去获取设备的限定描述符,以获取 USB 设备在其他速度模式下的信息。USB 设备也不一定会支持限定描述符,在这种情况下,USB 设备将会回复 STALL 表示设备不支持该描述符,这种控制传输的失败并不影响设备的正常枚举和使用。

  • 配置设备的配置描述符,主机在获取设备的某个配置描述符之后,会解析该描述符中所有的接口信息,和端点信息,之后主机就可以发出设置配置请求来通知 USB 设备使用哪一个配置。该请求命令中包含一个配置值,这个值是主机从设备的配置描述符中解析得来的,设备收到请求后,会判断配置值是否合法,若合法,设备就进入配置状态,设备会根据配置值选择对应的配置描述符,进行初始化操作,完成初始化后,设备就具备了与主机进行数据传输的能力,此时枚举阶段结束。以上则是整个枚举的过程,后续的 USB 通信将主要发生在配置描述符的接口或端点描述符所描述符的端点上。

四、总结

其实枚举过程可以简化为主机向设备发送标准请求,设备向主机发送描述符。主机需要知道设备的各种信息,设备需要把自己的信息发送到主机上。文章来源地址https://www.toymoban.com/news/detail-791576.html

到了这里,关于浅谈USB的枚举过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 香橙派/树莓派 电脑linux 电赛备赛指南-opencv全过程最简安装,ssh,vnc,USB摄像头驱动和配置环境避坑,手把手教学。opencv视觉入门(一)

    老早就想写博客了把之前的项目都记录下来,但是一直碍于每次做完项目都挺累的,于是就偷懒没写,不过每次做完都有总结,现在已经大三了,觉得应该把自己之前学习过程中遇到的经验或者坑写出来,后面会陆陆续续的发出来,今天先来讲一下有关这份博客的前提背景吧

    2024年04月08日
    浏览(51)
  • [桌面运维]PC常用的视频接口,显示器VGA、DVI、HDMI、DP、USB-C接口的认识和应用

    ⬜⬜⬜ 🐰🟧🟨🟩🟦🟪(*^▽^*)欢迎光临 🟧🟨🟩🟦🟪🐰⬜⬜⬜ ✏️write in front✏️ 📝个人主页:陈丹宇jmu 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 🙉联系作者🙈by QQ:813942269🐧 🌈致亲爱的读者:很高兴你能看到我的文章,希望我的文章可以帮助到你,祝万事

    2024年02月07日
    浏览(49)
  • 【usb】linux内核USB键盘驱动解析--普通键值上报及转化

    建议阅读前置文章【usb】linux内核USB键盘驱动解析–特殊键值上报及转化 以Linux5.10内核中USB键盘驱动为例进行解析:https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.10.tar.gz 文件路径:linux-5.10/drivers/hid/usbhid/usbkbd.c 本次我们主要分析第120~139行的这个for循环。 for循环变量i范围是

    2023年04月08日
    浏览(38)
  • RK3588平台开发系列讲解(USB篇)Linux Android USB软件架构

    平台 内核版本 安卓版本 RK3588 Linux 5.10 Android 12

    2024年02月09日
    浏览(55)
  • Linux USB 驱动实验

    USB 是很常用的接口,目前大多数的设备都是USB 接口的,比如鼠标、键盘、USB 摄像头等,我们在实际开发中也常常遇到USB 接口的设备,本章我们就来学习一下如何使能Linux内核自带的USB 驱动。注意!本章并不讲解具体的USB 开发,因为USB 接口很复杂,不同的设备其协议也不同

    2024年02月07日
    浏览(41)
  • Linux USB 设备检测

    最常用的命令就是 lsusb ,但是 lsusb 仅能查看当前的简单 USB 设备信息,要查看详细的 USB 设备信息,最好还是借助 Linux 下的 debugfs 机制。 debugfs 挂载: 通过 debugfs 查看 USB 设备信息 通过 /sys/kernel/debug/usb/devices 设备节点可以看到当前 USB 设备的详细信息,具体如下: 针对上面

    2024年02月15日
    浏览(42)
  • linux 下查看 USB 设备

    在 sysfs 文件系统下,查看 USB 设备,看到一些乱七八糟的设备显示,它们都是什么呢?今天来介绍一下。 usb1 usb1 表示该 SOC 上接了 1 条 USB 总线,即 1 个 USB Controller。 PS:如果有多个 USB Controller,将会是 usb1、usb2、usb3。。。 1-0:1.0 而 1-0:1.0 表示什么呢? 1:表示 1 号总线,或

    2024年02月04日
    浏览(39)
  • linux上USB检测异常,报错usb 7-1: device descriptor read/8, error -71

    芯片:RK356x 问题:部分USB设备检测异常;部分设备检测成功,但在使用过程中不稳定,经常断开disconnect然后重新连接connect USB设备插入检测打印信息,如下

    2024年02月15日
    浏览(49)
  • Rockchip linux USB 驱动开发

    Linux USB 协议栈是一个分层的架构,如下图 5-1 所示,左边是 USB Device 驱动,右边是 USB Host 驱动,最底层是 Rockchip 系列芯片不同 USB 控制器和 PHY 的驱动。                                               Linux USB 驱动架构 Rockchip 系列芯片,主要使用两种 USB 2.0 PHY IP:Innosi

    2024年01月25日
    浏览(48)
  • Linux: USB Gadget 驱动简介

    限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 本文所有分析基于 Linux 4.14 内核代码。 USB 设备驱动,按照设备端关联的 USB 控制器 是工作在 主模式 还是 从模式 ,分为 USB 设备主机侧驱动 (主模式) ,或者 USB 设备从机侧驱动 (从模式

    2024年02月07日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包