USB 设备框架
一个 USB设备 可以划分为三层:
-
底层(Bottom Layer):
是一个总线接口,用于传输和接收数据包。 -
中间层(Middle Layer):
负责在总线接口和设备上不同端点(Endpoints)之间传输数据。- 端点是数据的最终消费者或提供者。
- 它可以被看作是数据的源头(Source)或汇点(Sink)。
-
顶层(Top Layer):
提供USB设备的具体功能,例如鼠标或ISDN接口。
本章描述了USB设备中间层的常见属性和操作。中间层的这些属性和操作被设备功能特定的部分用于通过总线接口进行通信,并最终与主机连接。
USB设备的三层架构定义了其工作方式:
-
底层(总线接口)
- 作用:
底层主要负责通过USB标准协议实现数据包的传输。这包括数据的发送、接收以及低级别的错误检测与恢复机制。 - 与主机的关系:
底层直接与主机USB控制器进行交互,通过USB协议的电气和物理接口传输信号。
- 作用:
-
中间层(数据路由)
- 作用:
负责管理和协调数据在设备内部的传递路径。它是数据从主机进入设备后分配到特定端点的关键部分。 - 端点的特性:
每个端点具有独立的端点号,可以通过特定的传输类型(如控制传输、批量传输、同步传输或中断传输)与主机交互。 - 典型用途:
比如,在一个USB音频设备中,某些端点可能用于音频数据流的输入,另一些端点则用于音频的输出。
- 作用:
-
顶层(功能实现)
- 作用:
这一层包含设备实现的具体功能。对于用户来说,这一层决定了设备的实际用途。例如:- 键盘/鼠标:提供用户输入功能。
- 存储设备:提供文件存储与访问功能。
- 网络设备:提供网络通信功能。
- 与中间层的关系:
顶层依赖中间层的数据传递能力,通过对端点的具体操作实现功能。举例来说,一个音频设备需要通过中间层来发送和接收音频数据流。
- 作用:
9.1 USB设备状态
USB设备有几个可能的状态,这些状态中的某些是USB主机和设备都能看到的,而其他一些状态则仅在USB设备内部可见。本节将介绍这些状态。
9.1.1 可见的USB设备状态
可见的设备状态是指那些USB主机能够看到的设备状态。这些状态可以通过USB协议与主机进行交互。图9-1和表9-1总结了这些可见设备状态。
重要提示:当上游端口(与主机连接的端口)发送复位信号时,USB设备会执行复位操作。复位信号完成后,USB设备将被复位并返回到默认状态。
USB设备在与主机通信时,可能会处于不同的工作状态,这些状态决定了设备如何响应主机的命令与请求。
-
默认状态(Default State)
设备接收到复位信号后,首先进入这个状态。此时,设备未完全初始化,主机仍然无法访问设备的所有功能。设备需要完成初始化过程,才能进入其他工作状态。 -
地址分配状态(Address State)
在设备复位之后,设备会分配一个唯一的设备地址。这个状态的变化是由主机控制的,主机通过分配地址使设备能够被识别和访问。 -
配置状态(Configured State)
一旦设备的地址被分配,并且设备的配置过程完成后,设备进入配置状态。这时,设备已准备好与主机进行数据传输和其他交互。 -
挂起状态(Suspended State)
当设备不活动时,或者当USB总线处于低功耗模式时,设备会进入挂起状态。在挂起状态下,设备可以减少功耗以节省能量。
这张图描述了一个USB设备的状态转换,明确展示了设备从连接到主机后的各个状态,以及设备与总线交互的行为。
-
Attached(连接状态)
- 当设备连接到USB总线时,它进入“连接”状态。
- 此时设备尚未供电,总线检测到设备已连接。
转换条件:
- Hub Reset or Deconfigured(集线器复位或未配置): 设备从“已供电”返回到此状态。
- Hub Configured(集线器配置完成): 设备准备进入下一个状态。
-
Powered(供电状态)
- 一旦设备连接到USB总线,它被供电并进入“供电”状态。
- 设备需要电力支持来完成初始化工作。
转换条件:
- Reset(复位): 通过总线发送复位信号后,设备会从“供电”状态进入“默认”状态。
- Power Interruption(电力中断): 如果电力中断,设备会返回到“连接”状态。
- Hub Reset or Deconfigured(集线器复位或未配置): 集线器未完成配置时,设备返回到“连接”状态。
-
Default(默认状态)
- 复位完成后,设备进入“默认”状态。
- 在这个状态下,设备有一个默认地址(默认地址为0x00),但尚未分配具体的设备地址。
转换条件:
- Address Assigned(地址分配): 主机为设备分配一个唯一的地址后,设备进入“地址分配状态”。
- Reset(复位): 如果复位信号重新发送,设备将返回到“默认”状态。
-
Address(地址状态)
- 在这个状态下,设备已经从主机获得了一个唯一地址。
- 设备通过地址与主机进行初步通信。
转换条件:
- Device Configured(设备配置完成): 主机成功完成设备配置后,设备进入“配置状态”。
- Reset(复位): 如果设备接收到复位信号,它将返回到“默认”状态。
- Device Deconfigured(设备未配置): 如果配置被撤销,设备返回到“地址状态”。
-
Configured(配置状态)
- 在这个状态下,设备已完全配置,能够正常与主机进行数据传输。
- 这是设备运行的主要工作状态。
转换条件:
- Device Deconfigured(设备未配置): 如果设备配置被撤销,返回到“地址状态”。
- Reset(复位): 如果设备接收到复位信号,它将返回到“默认”状态。
-
Suspended(挂起状态)
- 当设备没有活动通信或总线进入低功耗模式时,设备进入“挂起状态”。
- 在这个状态下,设备减少功耗,但可以被唤醒。
转换条件:
- Bus Inactive(总线无活动): 如果总线长期处于无活动状态,设备将进入挂起状态。
- Bus Activity(总线活动): 如果检测到总线恢复活动,设备会从挂起状态恢复到之前的状态。
9.1.1.1 附加(连接)状态
USB设备可以连接(附加)或断开(分离)USB。当USB设备未连接到USB时,其状态未在本规范中定义。本规范仅讨论设备连接后所需的操作和属性。
-
USB设备连接和断开
- 连接(附加,Attached):当设备通过USB接口连接到主机(Host)时,进入“附加”状态。这一状态是设备与主机之间建立通信的第一步。
- 断开(分离,Detached):设备物理上从USB接口中移除后,进入“未连接”状态。在这一状态下,USB设备不会参与主机的通信,且其行为未受USB 2.0规范的约束。
-
规范的关注点
本规范的重点是:- 连接后所需的操作:如电源分配、地址分配、数据传输等。
- 连接后设备的属性:如配置描述符的设置、接口的定义等。
-
附加状态的应用场景
设备在附加状态下,主机可以执行以下操作:- 检测设备的存在。
- 为设备分配电源。
- 开始设备的初始化流程(例如复位和地址分配)。
9.1.1.2 供电状态
USB设备可以通过外部电源或通过连接的集线器(Hub)从USB总线获取电力。外部供电的USB设备被称为自供电设备(self-powered)。尽管自供电设备在连接到USB之前可能已经通电,但它们只有在连接到USB并且VBUS电源被施加到设备后,才被视为处于“供电”状态。
设备可以支持自供电和总线供电(bus-powered)两种配置。有些设备配置支持这两种电源方式,其他的设备配置可能仅在设备为自供电时才可用。设备会通过配置描述符报告其电源源能力。设备的电源源状态作为设备状态的一部分报告。
设备可以随时更改其电源源,例如从自供电切换为总线供电。如果某个配置支持两种电源模式,那么报告的最大功率就是该配置下设备在任一模式下从VBUS拉取的最大电流。无论设备处于何种模式,它都必须遵守该最大值。如果某个配置只支持一种电源模式,并且设备的电源源发生变化,设备将失去当前配置和地址,并返回到供电状态。如果设备是自供电且其当前配置需要超过100mA的电流,那么当设备切换为总线供电时,它必须返回到地址状态。自供电的集线器,如果失去本地电源,允许保持在配置状态。
集线器端口必须有电才能检测到端口状态的变化,包括设备的连接和断开。总线供电的集线器在配置完成之前不会提供任何下游电力,配置完成后,集线器会根据其配置和电源源提供电力。USB设备必须能够在电力初次施加后的指定时间内被分配地址(请参阅第7章)。当连接到端口的设备被检测到后,主机会启用该端口,同时也会重置连接的设备。
- 设备电源方式: USB设备可以通过外部电源(自供电)或通过USB总线(总线供电)获得电力。
- 电源状态: 设备只有在连接到USB并获得VBUS电源后,才被认为处于“供电”状态。
- 电源模式切换: 设备可以在不同的电源模式间切换,但在切换时必须遵守设备配置所定义的最大功率。
- 配置描述符: 设备通过配置描述符报告其支持的电源方式。
- 设备切换配置: 如果电源方式发生变化(如从自供电切换为总线供电),设备会丢失当前的配置和地址,进入供电状态。
- 集线器电源管理: 集线器端口需要供电才能检测端口状态的变化,并且总线供电的集线器在配置前不会提供下游电力。
USB设备的电力管理是USB协议中的一个重要方面。根据设备的设计,它们可以选择从外部电源(自供电)或通过USB接口连接获取电力。如果设备在USB连接之前已经供电,那么它的状态只有在VBUS电压施加之后,才会被认为是“供电”状态。这意味着即使设备在外部电源供电下工作,它必须在连接USB之后才能正式开始与USB主机的通信。
设备的配置描述符对于报告设备的电源源能力至关重要。这个描述符告诉主机设备是否支持自供电、总线供电,或者两者兼容。对于支持多种电源模式的设备,最大功率的报告是关键,它定义了设备在任何电源模式下所能消耗的最大电流。设备在切换电源模式时,必须确保它不会超出该最大功率限制。
此外,如果设备在配置过程中需要超过100mA的电流并切换到总线供电模式,它必须返回到地址状态。这是为了确保总线供电设备不会消耗超过USB总线供电能力的电流。
集线器的电源管理也很重要。USB集线器(特别是总线供电的集线器)在配置完成之前不会向下游设备提供电力。一旦集线器配置完毕,它会根据自身的配置和电源来源提供适当的电力。
9.1.1.3 默认状态
设备通电后,必须在接收到总线的复位信号之前,不响应任何总线事务。设备接收到复位信号后,它将使用默认地址进行通信。复位过程完成后,USB设备将以正确的速度(即低速/全速/高速)进行操作。低速和全速的速度选择由设备的终端电阻决定。一台支持高速操作的设备将在复位过程中决定是否以高速运行(详细内容参见第七章)。
一台支持高速操作的设备必须能够在全速的电气环境中成功复位。在设备成功复位后,设备必须成功响应设备和配置描述符请求,并返回适当的信息。设备在全速模式下操作时,可能无法支持其预期的功能。
- 设备初始化: 当USB设备刚通电时,它不会立刻响应总线上的任何请求。设备必须先接收到来自USB总线的复位信号,才能开始与主机通信,并且在复位之后,设备会使用默认地址进行通信。
- 速度选择: 在复位完成后,设备会根据其硬件和连接环境选择工作速度。低速和全速设备通过设备的终端电阻来决定,而支持高速的设备则在复位过程中决定是否切换到高速模式。
- 复位过程: 高速设备在全速环境中需要能够成功复位。复位成功后,设备会响应描述符请求并返回必要的信息。设备可能在全速模式下无法提供完整的功能。
-
设备启动与复位: 每当一个USB设备通电时,系统会先通过硬件或控制器发送复位信号。这个过程对所有设备都是必须的,复位信号使得设备进入可以响应主机请求的状态。在这个阶段之前,设备不能进行任何数据通信。
-
设备速度选择: USB设备的通信速度可以是低速(1.5 Mbps)、全速(12 Mbps)或高速(480 Mbps)。低速和全速设备依赖设备内部的终端电阻来决定通信速度。而支持高速的设备,则会在复位过程中决定是否切换至高速模式。如果总线支持高速,设备也会尝试切换到高速模式。
-
设备的功能性: 设备在完成复位后会通过标准的USB请求(如设备描述符和配置描述符请求)来向主机提供基本信息。这些信息帮助主机了解设备的能力及其所支持的功能。然而,并非所有设备在全速模式下都能完全发挥其全部功能。特别是高速设备,在全速模式下可能会受到带宽限制,无法提供与高速模式下相同的性能。
9.1.1.4 地址状态
所有USB设备在初次供电时或在设备重置后使用默认地址。每个USB设备在连接或重置后会被主机分配一个唯一地址。设备在挂起时会保持其分配的地址。
无论设备当前是否被分配了唯一地址,或者是否仍在使用默认地址,设备都可以响应默认管道上的请求。
- 默认地址:所有USB设备在首次接入电源或重置时使用的是一个默认的地址。这意味着在连接到USB总线的初期,设备没有特定的身份标识。
- 唯一地址的分配:当设备被主机检测到并初始化时,主机会为设备分配一个唯一的地址。这是为了确保每个设备在USB系统中的标识性。
- 挂起状态下保持地址:即使设备进入挂起状态,它仍会保持已分配的唯一地址,而不会恢复为默认地址。
- 默认管道的作用:无论设备是使用默认地址还是已分配的唯一地址,它都可以通过默认管道进行通信。默认管道是USB协议中用于设备初始化、地址分配和设备管理的基本通信通道。
在USB系统中,设备的地址分配是非常重要的一环。每当一个USB设备接入USB总线时,它首先会以“默认地址”与主机进行通信。默认地址通常是0,表示设备没有被分配一个唯一标识符。当主机通过控制传输请求与设备通信时,它会通过设备的默认管道进行数据交换。
一旦设备与主机建立连接并完成初始化,主机会为设备分配一个唯一的地址,这个地址通常是一个介于1到127之间的数值,确保每个设备在USB系统中的唯一性。这些地址会在设备被挂起(例如进入省电模式或待机模式)时继续保持,并且在设备重置后重新分配。挂起状态下,设备依然能够响应来自主机的特定请求,尽管它可能不在活跃工作状态。
这种机制确保了即使设备进入低功耗模式,USB主机仍然能够识别和管理该设备,维持设备通信的连贯性。
9.1.1.5 配置状态
在USB设备的功能使用之前,必须对设备进行配置。从设备的角度来看,配置包括正确处理一个SetConfiguration()请求,并且该请求中的配置值不能为零。配置设备或更改备用设置会导致所有与受影响接口中的端点相关的状态和配置值恢复为其默认值。这包括将任何使用数据切换(data toggles)的端点的数据切换设置为DATA0。
USB设备在使用其功能之前,必须先经过配置。配置的过程是设备处理来自主机的SetConfiguration()
请求,并且配置值必须为非零值。当设备配置或更改备用设置时,所有相关的端点状态和配置会被重置为默认值,其中包括数据切换状态(如数据传输的切换值会被设置为DATA0)。
在USB设备的生命周期中,设备需要经过配置才能进行正常的通信。这一过程由主机通过发送SetConfiguration()
请求来触发,设备必须响应此请求并根据请求中的配置值进行配置。值得注意的是,配置值不能为零,因为零值表示设备没有有效的配置。
配置的主要作用是让设备进入可以使用的状态,并确保设备的各个功能正常运行。每个设备可能有多个配置选项(例如支持不同的功能模式或接口)。当设备接收到一个新的配置请求时,它会根据该配置重新设置其内部状态,包括端点(endpoint)的配置。端点是用于数据传输的逻辑通道,设备在配置过程中会对其进行初始化。
此外,当设备更改配置或备用设置时,相关的端点状态会被恢复为默认值。这意味着数据切换(Data Toggle)的状态会被重置为DATA0。数据切换是指USB协议中用于数据传输的一个控制机制,确保传输的数据包按照正确的顺序传输。当设备配置或设置更改时,重置数据切换状态有助于确保数据的正确传输。
第九章中的“Suspended(挂起)”状态描述了USB设备在没有总线活动时如何进入省电模式。以下是详细的翻译和总结:
9.1.1.6 挂起状态
为了节省功耗,USB设备在没有总线通信活动超过指定时间后,会自动进入挂起状态(详见第七章)。在挂起状态下,USB设备会保留内部状态,包括设备地址和配置。
所有设备必须在总线活动超过第七章中规定的时间后进入挂起状态。所有连接的设备在通电后都必须准备好随时进入挂起状态,无论它们是否已经分配了非默认地址或配置。总线活动可能会因主机进入挂起模式而停止。此外,当设备所连接的集线器端口被禁用时,USB设备也应进入挂起状态,这称为“选择性挂起(Selective Suspend)”。
当总线活动恢复时,USB设备会退出挂起状态。设备也可以通过电气信号向主机发出远程唤醒(Remote Wakeup)请求,要求退出挂起模式或选择性挂起。设备是否支持远程唤醒信号是可选的。如果设备支持远程唤醒功能,它必须支持主机启用和禁用该功能。设备重置后,远程唤醒功能必须禁用。
- 挂起状态:设备在一段时间内没有总线通信活动时会进入省电的挂起模式。设备在挂起时仍然保持地址和配置等内部状态。
- 选择性挂起:如果设备所在的集线器端口被禁用,设备也会进入挂起状态。
- 退出挂起:当总线活动恢复,设备会自动退出挂起状态。设备可以通过远程唤醒信号请求主机唤醒。
- 远程唤醒:如果设备支持远程唤醒,它可以通过电气信号通知主机退出挂起模式。设备也需要支持主机启用或禁用该功能。设备重置时,远程唤醒功能被禁用。
USB设备在长时间未接收到总线活动时,为了节省电能,会进入挂起模式。这对于移动设备尤其重要,因为它们依赖电池供电,能耗的降低对于延长电池寿命至关重要。
挂起状态的实现方式涉及设备和主机之间的电气信号通信。设备会监测总线活动,当总线空闲时间超过设定值时,设备就会进入挂起状态。此时,设备会降低功耗,但仍会保持一些重要的状态,如设备地址和配置。选择性挂起机制提供了更多的控制,当设备连接的集线器端口被禁用时,设备会进入挂起状态。
此外,设备可以在挂起状态时,通过电气信号发出“远程唤醒”请求,要求主机重新激活设备。这种能力是可选的,如果设备支持远程唤醒功能,主机需要能够启用或禁用该功能。重置设备时,远程唤醒功能会被禁用,以确保设备在复位后不会突然唤醒。
9.1.2 总线枚举
当USB设备连接到或从USB接口移除时,主机使用一种称为总线枚举的过程来识别并管理设备的状态变化。以下是当USB设备连接到一个供电端口时,主机所执行的操作步骤:
-
通知事件:
USB设备被连接到某个端口后,所属的集线器(Hub)会通过其状态变化管道(Status Change Pipe)向主机发送事件通知(更多内容参考文档第11.12.3节)。此时,USB设备处于供电(Powered)状态,连接的端口是禁用的。 -
确认变化:
主机通过查询集线器来确定具体的状态变化。 -
等待稳定:
主机得知设备已连接到哪个端口后,等待至少100毫秒,以确保插入过程完成,同时设备的电力供应达到稳定状态。然后,主机向该端口发送使能(Enable)和复位(Reset)命令(参考文档第7.1.7.5节中的时序)。 -
复位和初始状态:
集线器对该端口执行必要的复位操作(见文档第11.5.1.5节)。当复位信号解除时,端口被启用。此时,USB设备进入默认(Default)状态,只能从VBUS电源中消耗最多100 mA电流。设备的所有寄存器和状态都已复位,且响应默认地址。 -
分配地址:
主机为USB设备分配一个唯一地址,将设备移动到地址(Address)状态。 -
读取描述符:
在设备获得唯一地址之前,其默认控制管道仍可通过默认地址访问。主机会读取设备描述符,以确定设备默认管道的实际最大数据负载大小。 -
读取配置信息:
主机从设备读取配置信息,遍历所有配置(从零到n-1,n为配置数量)。此过程可能需要几毫秒时间。 -
分配配置值:
根据设备的配置信息及使用需求,主机为设备分配一个配置值。设备进入已配置(Configured)状态,此时该配置中的所有端点具备了各自的描述特性。设备可以消耗描述符中指定的配置所允许的VBUS功率。从设备的角度来看,它已准备好工作。
总线移除:
当USB设备被移除时,集线器再次向主机发送通知。移除设备会禁用连接的端口。在收到移除通知后,主机会更新其本地拓扑信息。
总线枚举是USB主机用来检测、初始化并管理设备连接和移除的一种标准化流程。在设备插入后,主机会按以下步骤完成设备的识别与配置:
-
设备通知与查询:
集线器负责检测设备插入并向主机报告。主机通过集线器查询以确定设备状态。 -
等待稳定:
主机确保设备插入完全并电力稳定后,开始对设备复位和初始化。 -
复位与地址分配:
在复位期间,设备被设置为默认状态(Default),可以接受最多100 mA的电流。之后,主机分配唯一地址,设备进入地址状态(Address)。 -
读取与配置:
主机获取设备描述符和配置信息,确保设备按照指定配置正常运行。最终,设备进入已配置状态(Configured),准备好提供正常的功能服务。
这种流程的设计确保了设备的插拔可动态进行,同时保证了系统的稳定性与兼容性。这种机制是USB“即插即用(Plug and Play)”功能的关键所在。
9.2 通用USB设备操作
所有USB设备都支持一组通用操作。本节将描述这些操作。
9.2.1 动态连接和移除
-
USB设备的连接与移除:USB设备可以随时连接或移除,操作非常灵活。每个USB设备的连接点或者端口由集线器(Hub)负责管理,集线器需要报告端口状态的任何变化。
-
连接设备时的操作:当主机检测到设备连接时,会启用设备所连接的集线器端口,并且这同时会导致设备复位。复位后的USB设备会具有以下特征:
- 响应默认的USB地址:设备在复位后会响应默认的USB地址(0地址)。
- 未配置:设备在复位时尚未配置,即尚未完成设备描述符的读取等配置操作。
- 未进入挂起状态:设备复位时不会立即进入挂起状态(Suspend),会保持活跃状态。
-
设备移除时的操作:当设备从集线器端口移除时,集线器会禁用设备所在的端口,并通知主机该设备已被移除。主机会根据这个通知做出相应的操作。
设备的连接和移除由集线器进行管理,集线器的作用不仅是提供物理连接点,还负责端口状态的监控和通知主机设备的连接变化。
-
设备连接时的复位:USB设备连接到主机时会经历复位过程。这意味着在设备刚连接时,它会被赋予默认地址(0地址),并且不会立即进入工作模式,而是处于一个初始状态。这有助于主机能够识别并初始化设备。
-
设备移除时的处理:当设备从端口移除时,集线器会禁用该端口,并通知主机设备已移除。这也表明,USB系统在设备的移除过程中具备快速响应和处理机制,以保证数据传输的安全性和设备管理的流畅性。
9.2.2 地址分配
当USB设备连接到主机时,主机负责为该设备分配一个唯一的地址。这个过程是在主机重置设备后进行的,并且设备连接的集线器端口已被启用。
USB设备连接到主机后的一个关键步骤——地址分配。在USB总线中,设备必须拥有一个唯一的地址才能与主机进行通信。这一过程发生在设备连接后,主机首先会重置设备,然后为其分配一个地址。这是USB设备初始化的一个重要部分。
-
设备连接与重置:当USB设备插入主机时,主机会对设备进行重置。这是为了确保设备以正确的状态启动,并使得设备能够响应主机的请求。设备重置是通过发送一个特殊的信号给设备实现的。
-
集线器端口启用:如果设备通过USB集线器连接到主机,那么在设备连接之前,集线器端口必须被启用。这意味着集线器能够正确识别和响应设备的连接请求。
-
唯一地址分配:在设备重置和端口启用之后,主机会给设备分配一个唯一的地址。这个地址用于后续的设备识别和通信。所有设备在USB总线上都必须有一个唯一的地址,防止发生地址冲突,确保数据能够正确地发送到目标设备。
-
地址分配的顺序:通常,主机会从地址1开始分配设备地址,每个新的设备连接时,地址会逐步递增。这个过程通过枚举过程来完成,主机通过发送特定的控制请求来分配地址。
9.2.3 配置
USB设备必须在使用其功能之前进行配置。主机负责配置USB设备,通常主机会请求设备的配置信息,以确定设备的能力。
在配置过程中,主机会设置设备的配置,并在必要时选择接口的适当备用设置。
在单一配置下,一个设备可以支持多个接口。接口是由一组相关的端点组成,这些端点将设备的某一特性或功能呈现给主机。与这些端点进行通信所使用的协议以及每个端点在接口中的作用,可能会作为设备类或厂商特定定义的一部分加以说明。
此外,配置中的每个接口可能有备用设置,这些备用设置重新定义了与之关联的端点的数量或特性。如果存在这种情况,设备必须支持GetInterface()
请求,以报告指定接口的当前备用设置,并支持SetInterface()
请求,以选择指定接口的备用设置。
在每个配置中,每个接口描述符包含字段,用于标识接口号和备用设置。接口号从零开始,最大值为该配置所支持的并发接口数减一。备用设置的编号范围从零到指定接口的备用设置数量减一。设备在初次配置时的默认设置是备用设置零。
为了支持能够管理一组相关USB设备的自适应设备驱动程序,设备和接口描述符包含Class(类)、SubClass(子类)和Protocol(协议)字段。这些字段用于标识USB设备所提供的功能和与设备功能进行通信的协议。类代码被分配给一组相关设备,该组设备已被归类为USB类规范的一部分。设备类可能进一步细分为子类,并且在一个类或子类内,协议代码定义了主机软件如何与设备进行通信。
注意: 类、子类和协议代码的分配必须进行协调,但这超出了本规范的范围。
- 配置过程:USB设备必须经过配置才能使用其功能,主机负责配置并请求设备的配置信息。
- 接口和备用设置:每个USB设备可能有多个接口,一个接口是设备的功能单元,包含多个端点。接口有默认设置和备用设置,备用设置可以调整接口的端点数量或特性。
- Class/SubClass/Protocol字段:用于标识设备的功能及协议类型,帮助设备驱动程序识别设备并正确处理。
USB设备在连接到主机时,主机并不能直接使用设备的所有功能。设备首先需要通过配置过程进行初始化。配置过程由主机发起,主要是为了让主机了解设备的能力及功能,从而决定如何与设备进行交互。
-
配置过程:
- 配置请求:主机请求设备的配置信息,设备向主机提供相关数据,描述设备支持的配置。
- 接口的概念:接口是设备的一个功能单元,每个接口由多个端点(Endpoint)组成。每个端点可以执行特定的任务,如数据传输、命令响应等。
- 备用设置:一个接口可以有多个备用设置,备用设置通常用来调整接口的工作方式,如改变端点数量或特性。备用设置可以由主机通过
GetInterface()
和SetInterface()
请求来查询或更改。
-
设备类别:
- Class、SubClass、Protocol:这些字段帮助USB设备标识其类型和协议。例如,一个设备可能属于"音频类"(Class),可以进一步细分为"扬声器子类"(SubClass),并且使用特定的协议进行通信。
- 这些分类字段使得设备驱动程序可以更有效地管理和适配设备。通过这些信息,主机可以快速识别设备类型,加载适当的驱动程序,并进行通信。
-
默认配置:
- 每个接口的默认配置是备用设置零。主机首先会根据这个默认配置与设备交互,后续可以根据需求更改为其他备用设置。
9.2.4 数据传输
USB设备的端点与主机之间的数据传输有四种方式。有关这四种传输类型的定义,请参阅第5章。同一个端点编号可以在不同的备用设置中用于不同类型的数据传输。然而,一旦选定某个备用设置(包括接口的默认设置),USB设备的端点将在该备用设置下仅采用一种数据传输方法,直到选择了另一个备用设置。
-
数据传输的四种方式
根据USB 2.0规范,数据传输的四种主要类型是:- 控制传输(Control Transfers):主要用于设备配置和命令交互。它提供了初始化和命令通信的机制。
- 批量传输(Bulk Transfers):设计用于大批量数据传输,适合非实时传输,例如打印机或存储设备。
- 中断传输(Interrupt Transfers):为需要低延迟响应的设备设计,如键盘、鼠标等。
- 同步传输(Isochronous Transfers):专用于对实时数据流有严格时间要求的设备,如音频和视频设备。
这些传输方式的具体定义和限制可参考第5章中的数据流模型。
-
备用设置(Alternate Settings)
- USB接口中的备用设置是为了满足设备在不同工作模式下的需求。
- 端点复用:同一个端点编号在不同的备用设置中可以用于不同的数据传输方式。例如:
- 在一种备用设置下,端点编号可以用于批量传输;
- 在另一种备用设置下,端点编号可能用于同步传输。
- 唯一性限制:当某个备用设置被选中时,该端点只能使用该设置中定义的一种传输方式。只有当切换到其他备用设置时,端点的数据传输方式才会改变。
9.2.5 电源管理
参阅手册
9.2.6 请求处理
除了 SetAddress() 请求(请参阅第9.4.6节)外,设备在返回 ACK 信号后,即可开始处理请求。设备应在允许状态阶段成功完成之前,完成请求的处理。有些请求会启动需要数毫秒才能完成的操作。对于这些请求,设备类需要定义一种方法,除了状态阶段的完成以外,用于指示操作已经完成。例如,集线器端口上的重置操作需要至少 10 毫秒才能完成。当发出 SetPortFeature(PORT_RESET) 请求(请参阅第11章)时,重置操作的“完成”意味着端口上的重置已经启动。当端口的状态变化被设置为指示端口已经启用时,重置操作的完成被信号化。这种技术防止主机不断轮询以检查完成状态,特别是当已知请求将花费较长时间时。
在 USB 设备请求处理中,设备通常在接收到请求后立即开始处理,除非是涉及 SetAddress() 请求。设备需要在状态阶段之前完成大部分的请求处理。不过,有些请求需要较长时间才能完成,可能需要数毫秒或更长的时间。在这种情况下,设备类必须提供一种机制,允许设备在不依赖状态阶段的完成来通知主机请求已完成。
例如,当执行端口重置操作时,设备并不会立即完成状态阶段,而是会首先启动重置操作。设备会通过改变端口状态来指示操作已完成,而主机不需要频繁地检查重置是否完成。这种方法有效避免了大量轮询请求,提高了效率。
-
请求的处理开始时机:
当设备收到控制传输的 Setup 阶段并返回 ACK 后,它就可以开始处理请求了。对于大部分请求,设备在状态阶段开始之前应完成所有请求的处理。 -
长时间操作的处理:
有些请求会涉及到需要较长时间才能完成的操作。例如,集线器端口的重置操作,通常需要至少 10 毫秒。在这些情况下,设备必须在操作开始时向主机发出通知,而不是等待操作完成才能结束请求的处理。这有助于避免设备长时间处于忙碌状态。 -
通过状态变化信号化完成:
当设备需要较长时间完成请求时,设备通常会通过某些状态变化来通知主机。例如,SetPortFeature(PORT_RESET) 请求并不会在重置完成时结束,而是在重置启动时就标记为“完成”。一旦操作完成,设备会通过改变端口状态来表示操作已成功完成。主机可以通过检查端口的状态变化来得知操作是否已完成,而不需要持续轮询。 -
避免频繁轮询:
这种方法避免了主机对操作的不断轮询。轮询在长时间操作的场景中会造成性能浪费,因为主机不断检查是否完成,反而浪费了时间和资源。通过这种状态变化的方法,主机可以在操作完成后得到通知,从而节省了资源。
总结来说,这一节强调了在 USB 请求处理过程中,对于需要较长时间才能完成的操作,设备应采用状态变化信号来通知主机,而不是等待状态阶段的完成。这种方法提高了操作效率,并减少了不必要的轮询负担。
9.2.6.1 请求处理时限
所有设备都应在合理的时间内处理请求。USB规定,任何命令的处理上限为5秒钟。此限制并非在所有情况下都适用,具体的限制将在以下章节中描述。需要注意的是,下面给出的限制旨在涵盖广泛的实现。如果USB系统中的所有设备都使用请求处理的最大时间限制,用户体验将会受到影响。因此,实施过程中应该尽量缩短请求处理的时间。
- 请求处理时限:USB系统要求设备能够在规定的时间内处理请求。正常情况下,任何请求的最大处理时间为5秒。
- 限制范围:虽然有最大时间限制,但并不是所有情况都适用5秒的处理时限。具体适用情况会在后续章节中进一步说明。
- 影响用户体验:如果每个设备都用最大时限处理请求,用户的体验会受到显著影响。因此,设备的设计应该尽量缩短处理请求的时间,以提高系统的响应速度。
USB协议中对设备请求的处理时限进行了规定。为了保证系统的稳定性和响应性,USB设定了一个最大处理时限,通常是5秒钟。这意味着,任何请求都应该在5秒内完成处理,除非有特定的例外情况。为了避免系统中所有设备都耗尽最大时间,从而影响整个系统的响应速度,USB系统鼓励设备实现更短的处理时间。
实际上,USB设备在设计时通常会优先考虑请求处理的高效性,以确保在大多数情况下能够快速响应用户操作,避免出现显著的延迟。
9.2.6.2 重置/恢复恢复时间
在端口被重置或恢复后,USB系统软件应提供一个“恢复”间隔,通常为10毫秒,期间连接到该端口的设备应在此期间内不响应数据传输。
在恢复间隔结束后(从重置结束或恢复信号结束的EOP计时开始),设备必须随时接受数据传输。
- 恢复时间要求:设备在端口被重置或恢复后,需要等待10毫秒的恢复时间。
- 数据传输的响应:在这段恢复时间内,设备应忽略所有数据传输请求。
- 恢复后的行为:恢复间隔结束后,设备应该准备好接受数据传输。
在USB设备连接的端口发生重置或恢复后,设备进入一个“恢复”期,这段时间通常为10毫秒。恢复期间,设备被期望忽略所有数据传输请求,因为它正在从重置或恢复状态中恢复。
此段时间结束后,设备恢复正常工作状态,可以开始接受任何来自主机的数据传输。
USB规范设定这个时间间隔的目的是为了确保设备有足够的时间来完成初始化或准备好从休眠/断开状态中恢复,不会在此期间因为数据传输请求而产生错误或冲突。
9.2.6.3 设置地址处理
在复位/恢复间隔后,如果设备收到 SetAddress() 请求,设备必须能够在 50 毫秒内完成请求的处理,并能够成功完成请求的状态阶段(Status stage)。对于 SetAddress() 请求,当设备发送零长度的状态数据包,或在状态阶段数据包后看到 ACK 响应时,状态阶段被认为成功完成。
在成功完成状态阶段后,设备允许一个 2 毫秒的 SetAddress() 恢复间隔。这个间隔结束时,设备必须能够接收发送到新地址的 Setup 数据包。同时,在恢复间隔结束时,设备必须不再响应发送到旧地址的令牌(除非旧地址和新地址相同)。
-
SetAddress() 请求处理:
- 设备在复位或恢复之后,如果接收到 SetAddress() 请求,必须在 50 毫秒内完成该请求的处理。
- 该请求的处理包括完成状态阶段。状态阶段的成功完成可以通过设备发送零长度的状态数据包,或者设备收到状态阶段数据包后的 ACK 响应来确认。
-
恢复间隔:
- 在状态阶段成功完成之后,设备有 2 毫秒的恢复间隔。此时,设备需要进行准备,以接收新的地址对应的 Setup 包。
- 在恢复间隔结束后,设备不再响应发送到旧地址的令牌,除非新旧地址相同。
SetAddress() 请求是 USB 设备地址分配过程中的关键部分,它使得设备能够从默认地址(通常是 0)转移到一个新的地址。在设备启动或复位后,主机可能会向设备发送 SetAddress() 请求,以将设备从默认地址更改为一个新的唯一地址。
-
状态阶段的成功完成:
- 当 SetAddress() 请求收到并处理完成后,设备需要进入状态阶段并确认这一过程。USB 协议要求设备通过两种方式之一来表示状态阶段成功完成:
- 发送一个零长度的状态数据包。
- 收到主机的 ACK 响应,这表示主机确认已成功接收状态阶段的数据包。
- 当 SetAddress() 请求收到并处理完成后,设备需要进入状态阶段并确认这一过程。USB 协议要求设备通过两种方式之一来表示状态阶段成功完成:
-
恢复间隔:
- 在状态阶段完成后,设备将进入一个短暂的恢复间隔(通常为 2 毫秒)。这个间隔允许设备从旧地址过渡到新地址,并准备好接收新的 Setup 包。
- 设备在恢复间隔内将停止对发送到旧地址的令牌的响应。这确保了地址的唯一性,避免了旧地址和新地址的冲突。
通过这些过程,USB 设备能够正确地处理地址更改,并与主机进行后续的通信。
9.2.6.4 标准设备请求
对于不需要数据阶段的标准设备请求,设备必须能够在接收到请求后50毫秒内完成请求,并成功完成状态阶段。这一限制适用于设备、接口或端点的请求。
对于需要数据阶段传输到主机的标准设备请求,设备必须能够在接收到请求后500毫秒内将第一个数据包返回给主机。对于后续的数据包(如果有),设备必须能够在成功完成前一个数据包的传输后500毫秒内返回它们。设备还必须能够在返回最后一个数据包后50毫秒内成功完成状态阶段。
对于需要将数据阶段传输到设备的标准设备请求,设备有5秒的时间限制。这意味着如果主机以设备能够接受的最大速率提供数据,设备必须能够接受所有数据包并成功完成状态阶段。主机之间的数据包传输延迟会增加设备完成请求的时间限制。
-
没有数据阶段的标准请求:设备需要在接收到请求后50毫秒内完成请求,并成功完成状态阶段。
-
有数据阶段,数据传输到主机的请求:设备必须能够在接收到请求后500毫秒内将第一个数据包返回给主机,并且后续的数据包需要在前一个数据包传输完成后500毫秒内返回。最后,设备需在最后一个数据包返回后50毫秒内完成状态阶段。
-
有数据阶段,数据传输到设备的请求:设备有5秒的时间来接受数据并完成状态阶段。主机传输数据包之间的延迟将加到设备完成请求的时间限制内。
在USB设备通信中,标准设备请求可能包含数据阶段,其中设备需要与主机交换数据。在这些情况下,设备必须严格遵循时间要求,以确保请求的顺利完成。
-
没有数据阶段的请求(如请求设备设置地址或获取设备描述符等)通常没有数据传输,只涉及控制传输的命令和状态阶段。在这种情况下,设备必须在接收到请求后50毫秒内完成请求,并完成状态阶段。
-
有数据阶段,数据传输到主机的请求(如设备返回特定信息或配置的请求)要求设备能够及时返回数据包。设备需要在500毫秒内返回第一个数据包,如果有后续数据包,也应在前一个数据包成功传输后的500毫秒内返回。设备必须能在返回最后一个数据包后50毫秒内完成状态阶段,以确保整个请求周期不超过合理的时间限制。
-
有数据阶段,数据传输到设备的请求(如设备接收配置数据等)则要求设备能够接受从主机传输的数据,并完成状态阶段。尽管设备有较长的5秒时间限制,但如果主机传输速度较快,设备仍需尽量高效地处理这些数据。主机发送数据包的延迟将直接影响设备完成请求所需的时间。
这些时间要求是USB协议中为了确保通信效率和设备响应速度而设定的。设备需要确保在规定的时间内完成任务,否则可能会导致请求超时或数据传输错误。
9.2.6.5 特定于类别的请求
除非类别文件中特别豁免,否则所有特定于类别请求必须满足标准设备请求的时间限制。如果类别文件提供了豁免,则只能在逐个请求的基础上指定豁免。类文档可能要求设备响应比本节中指定的更快。对于标准和特定于类的请求,可能需要更快的响应。
9.2.6.6 速度相关描述符
能够在高速下运行的设备可以在全速或高速下运行。由于必须作为重置处理的一部分正确管理其收发器,设备始终知道其工作速度(有关重置的更多详细信息,请参阅第7章)。在完成复位序列后,设备也以单个速度运行。特别是,在正常操作期间没有速度开关。然而,高速设备可以具有速度相关的配置。也就是说,它可能具有一些仅在高速运行时才可能的配置,或一些仅在全速运行时才可行的配置。支持高速的设备必须支持报告其速度相关配置。高速设备用对当前工作速度有效的描述符信息进行响应。例如,当要求设备提供配置描述符时,它仅返回当前工作速度(例如,全速)的配置描述符。然而,必须有一种方法来确定高速和全速运行的能力。两个描述符允许高速设备报告关于其他工作速度的配置信息。这两个描述符是:(other_speed)设备限定符描述符和other_speed_configuration描述符。主机通过使用具有相应描述符类型值的GetDescriptor请求来检索这两个描述符。注意:除非主机显式发出相应的GetDescriptor请求,否则不会检索这些描述符。如果未发出这两个请求,则该设备将只是一个单速设备。支持高速的设备必须将其描述符的bcdUSB字段中的版本号设置为0200H。这表示此类设备支持USB 2.0定义的other_speed请求。如果描述符版本号小于0200H的设备接收到这些other_speed请求,则该设备应导致请求错误响应(请参阅下一节)。不应向USB 1.x设备(即设备描述符版本低于0200H的设备)发出other_speed请求
9.2.7 请求错误
当设备接收到未为设备定义的请求、不适合设备的当前设置或具有与请求不兼容的值的请求时,则存在请求错误。设备通过响应下一个数据阶段事务或消息的状态阶段返回STALL PID来处理请求错误。最好在下一个数据阶段事务中返回STALLPID,因为这避免了不必要的总线活动。
9.3 USB设备请求
参阅手册
9.4 标准设备请求
参阅手册
9.5 设备描述符
USB 设备通过描述符 (descriptors) 报告其属性。描述符是一种具有定义格式的数据结构。每个描述符以一个字节宽的字段开始,该字段包含描述符的总字节数,接着是一个字节宽的字段,用于标识描述符的类型。
通过使用描述符,可以简洁地存储各个配置的属性,因为每个配置可以重用其他配置中具有相同特性的描述符或描述符的部分内容。这种方式使得描述符类似于关系型数据库中的数据记录。
在适当的情况下,描述符会包含对字符串描述符的引用,提供用于人类阅读的显示信息来描述描述符。这些字符串描述符的包含是可选的。然而,描述符中对字符串描述符的引用字段是强制性的。如果设备不支持字符串描述符,则这些字符串引用字段必须重置为零,以表示没有可用的字符串描述符。
如果描述符返回的长度字段值小于规范定义的长度,则该描述符无效,主机应将其拒绝。如果描述符返回的长度字段值大于规范定义的长度,主机将忽略多余的字节,但下一个描述符的位置由返回的长度值确定,而不是预期的长度值。
设备可以通过以下两种方式返回类或供应商特定的描述符:
- 如果类或供应商特定的描述符使用与标准描述符相同的格式(例如,以一个长度字节开始,后跟一个类型字节),它们必须与标准描述符交错返回,并包含在通过
GetDescriptor(Configuration)
请求返回的配置信息中。在这种情况下,类或供应商特定的描述符必须紧跟它们修改或扩展的相关标准描述符之后。 - 如果类或供应商特定的描述符独立于配置信息,或者使用非标准格式,则可以通过指定类或供应商特定描述符类型和索引的
GetDescriptor()
请求从设备中检索这些描述符。类或供应商规范将定义检索这些描述符的适当方法。
USB设备使用描述符来报告其属性。每个描述符是一个具有定义格式的数据结构。描述符的格式包括以下两个主要部分:
- 描述符长度:一个字节的字段,指明描述符的总字节数。
- 描述符类型:一个字节的字段,标识描述符的类型。
描述符的使用使得设备能够高效地存储和传输其配置信息。每个配置可能会重用一些来自其他配置的描述符或描述符的部分,这样做类似于关系数据库中的数据记录。
-
字符串描述符
描述符可能包含指向字符串描述符的引用,字符串描述符提供了可显示的、用于描述描述符的可读信息。需要注意的是:- 字符串描述符是可选的,但描述符中的引用字段是强制性的。
- 如果设备不支持字符串描述符,那么引用这些字符串描述符的字段应设置为0,以指示没有可用的字符串描述符。
-
描述符的长度
描述符中有一个“长度”字段,它指定了描述符的字节数。如果该字段的值小于规格中定义的长度,则说明描述符无效,主机应当拒绝它。如果字段的值大于规格中定义的长度,则额外的字节会被主机忽略,但后续描述符会根据长度字段返回的值进行定位,而不是根据预期的长度。 -
类别和厂商特定描述符
USB设备还可以返回类特定或厂商特定的描述符。这些描述符可以通过两种方式返回:- 与标准描述符交织返回:如果类特定或厂商特定描述符使用与标准描述符相同的格式(即以长度字节开头,并跟随一个类型字节),它们应当在通过
GetDescriptor(Configuration)
请求返回的配置信息中与标准描述符交织出现。在这种情况下,类或厂商特定的描述符必须位于它们修改或扩展的标准描述符之后。 - 独立返回:如果类或厂商特定的描述符与配置无关,或者使用非标准格式,它们可以通过
GetDescriptor()
请求获取,这个请求会指定类或厂商特定描述符的类型和索引。类或厂商的规范将定义如何检索这些描述符。
- 与标准描述符交织返回:如果类特定或厂商特定描述符使用与标准描述符相同的格式(即以长度字节开头,并跟随一个类型字节),它们应当在通过
- 描述符通过标准格式有效地传递设备的配置信息。
- 描述符中可能包含字符串描述符的引用,但这是可选的,若设备不支持,则引用字段应为0。
- 描述符的长度字段用于确定描述符的有效性和处理方式,长度字段不符合规范时会导致错误处理。
- 类或厂商特定描述符的处理方式与标准描述符不同,具体的获取方式由设备的类或厂商规范决定。
9.6 标准USB描述符定义
参阅手册
9.7 设备类别定义
参阅手册