USB 双角色驱动程序堆栈体系结构

从 Windows 10 桌面版(家庭版、专业版、企业版和教育版)和 Windows 10 Mobile 开始,Windows 现在支持 USB 双角色控制器。

介绍

USB 双角色功能可使系统成为 USB 设备或 USB 主机。 有关 USB 双角色的详细规范,请访问 USB-IF 的 USB on the Go 信息页面。

双角色功能允许手机或平板电脑等移动设备将自己指定为设备或主机。

当移动设备处于功能模式时,它会连接到电脑或其他设备,而电脑或其他设备则充当所连接移动设备的主机。

当移动设备处于主机模式时,用户可以连接自己的设备,如鼠标或键盘。 在这种情况下,移动设备会托管连接的设备。

通过在 Windows 10 中提供对 USB 双角色的支持,我们提供了以下优势:

  • 通过 USB 与移动外围设备连接,USB 可提供比蓝牙等无线协议更大的数据带宽。
  • 在与其他 USB 设备连接和通信时,可选择通过 USB 为电池充电(只要存在所需的硬件支持)。
  • 让最有可能拥有移动设备(如智能手机)的客户能够完成所有工作。 此功能可提高有线对接情况下的工作效率,即移动设备对接,从而托管外围设备。

下表列出了 Windows 桌面版和移动版中可用的主机类驱动程序列表。

USB 主机类驱动程序 Windows 10 移动版 Windows 10 桌面版
USB 中心 (USBHUB) 是(自 Windows 2000 起)
HID - 键盘/鼠标(HidClass、KBDCLass、MouClass、KBDHid、MouHid) 是(自 Windows 2000 起)
USB 大容量存储(批量和 UASP) 是(自 Windows 2000 起)
通用 USB 主机驱动程序 (WinUSB) 是(自 Windows Vista 起)
USB 音频传入/传出 (USBAUDIO) 是(自 Windows XP 起)
串行设备 (USBSER) 是(自 Windows 10 起)
蓝牙 (BTHUSB) 是(自 Windows XP 起)
打印 (usbprint) 是(自 Windows XP 起)
扫描 (USBSCAN) 是(自 Windows 2000 起)
网络摄像头 (USBVIDEO) 是(自 Windows Vista 起)
媒体传输协议(MTP 发起程序) 是(自 Windows Vista 起)
远程 NDIS (RNDIS) 是(自 Windows XP 起)
通过 USB 访问 IP (IPoverUSB) 是(Windows 10 新增功能)

表中的类别驱动程序是根据设备类别遥测和 Windows 10 的关键应用场景选择的。 我们计划包含数量有限的收件箱、第三方主机驱动程序,以支持 Windows 10 移动版上的关键设备。 对于 Windows 10 桌面版,这些驱动程序可从 OEM 网站或通过 Windows Update (WU) 获取。

对于 Windows 10 Mobile,收件箱中未包含的第三方驱动程序在 Window Update 中不可用。 USB 主机堆栈 + HID 的磁盘占用空间很小。 这就是为什么 Windows 10 移动版的收件箱中并不包含所有的类驱动程序,也很少包含第三方驱动程序。 希望提供第三方驱动程序的 OEM 可以使用电路板支持包 (BSP) 将其添加到移动设备的 OS 映像中。

下表列出了 Windows 移动版本中可用的功能类驱动程序。

注意

功能驱动程序不适用于 Windows 10 桌面版。

USB 功能类驱动程序 Windows 10 移动版 Windows 10 桌面版 备注
媒体传输协议 (MTP) 响应程序 桌面版没有 MTP 响应程序的应用场景。 通过 WinUSB 上的 Easy-MigCable 实现了桌面系统之间的 P2P 场景。
视频显示输出 (vidstream)
通用 USB 功能驱动程序 (GenericUSBFn) IPoverUSB 和其他桌面刷写方案都需要使用此驱动程序。

我们会监控设备附件数据,以便随着设备类别受欢迎程度列表的更新,了解是否需要提供更多的类别驱动程序支持。

驱动程序实现

Microsoft USB 角色转换 (URS) 驱动程序允许系统实施人员利用其平台的双角色 USB 功能。

URS 驱动程序旨在为使用单个 USB 控制器的平台提供双角色功能,该控制器可在单个端口上同时扮演主机和外围设备角色。 外围角色也称为功能角色。 URS 驱动程序管理端口的当前角色。 URS 驱动程序会根据来自平台的硬件事件加载和卸载适当的软件堆栈。

在带有 USB micro-AB 连接器的系统上,驱动程序会利用硬件中断来指示连接器上 ID 引脚的状态。 该引脚用于检测控制器在连接中需要承担主机角色还是功能角色。 有关详细信息,请参阅 USB On-The-Go 规范。 在带有 USB Type-C 连接器的系统上,OEM 实施人员应使用 USB Type-C 连接器驱动程序编程接口来提供连接器客户端驱动程序。 客户端驱动程序与 Microsoft 提供的 USB 连接器管理器类扩展 (UcmCx) 通信,以管理 USB Type-C 连接器的各个方面,如 CC 检测、PD 消息传递等。 对于角色切换,客户端驱动程序会将 USB Type-C 连接器的状态传递给 URS 驱动程序。

下图显示了使用 URS 驱动程序的双角色控制器的 USB 软件驱动程序堆栈。

USB 角色切换驱动程序堆栈体系结构。

URS 驱动程序不会同时加载上图所示的功能堆栈和主机堆栈。 URS 驱动程序会加载功能堆栈或主机堆栈,具体取决于 USB 控制器的角色。

硬件要求

如果要开发一个利用 URS 驱动程序的平台,以提供双角色 USB 功能,则必须满足以下硬件要求:

  • USB 控制器

    这些驱动程序是由 Microsoft 作为内置驱动程序提供的。

    Synopsys DesignWare Core USB 3.0 控制器。 收件箱 INF:UrsSynopsys.inf。

    Chipidea 高速 USB OTG 控制器。 收件箱 INF:UrsChipidea.inf。

  • ID 引脚中断

    • 非 USB Type-C 系统的一个或多个 ID 引脚中断有两种实现方式:

      1. 两个边缘触发的中断:一个在连接器上的 ID 引脚接地时触发,另一个在 ID 引脚浮动时触发。
      2. 当 ID 引脚接地时,处于有效电平的单一双有效中断。
  • USB 控制器枚举

    USB 双角色控制器必须是 ACPI 枚举的。

  • 软件支持

    URS 驱动程序需要一个软件接口,以便通过连接器来控制 VBus。 该接口是 SoC 专用的。 有关详细信息,请联系 SoC 供应商。

Windows 不支持以下 USB OTG 功能:

  • 配件充电器适配器检测 (ACA)。
  • 会话请求协议 (SRP)。
  • 主机协商协议 (HNP)。
  • 连接检测协议 (ADP)。

ACPI 系统配置

要使用 URS 驱动程序,必须为系统创建 ACPI 定义文件。 此外,还必须考虑一些与驱动程序相关的因素。

下面是 USB 双角色控制器的 ACPI 定义示例。

//
// You may name the device whatever you want; we don't depend on it being called 'URS0'.
//
Device(URS0)
{
    //
    // Replace with your own hardware ID. Microsoft will add it to the inbox INF,
    // or you may choose to author a custom INF that uses Needs & Includes directives
    // to include sections from the inbox INF.
    //
    Name(_HID, "ABCD1234")

    Name(_CRS, ResourceTemplate() {
        //
        // The register space for the controller must be defined here.
        //
        Memory32Fixed(ReadWrite, 0xf1000000, 0xfffff)


        //
        // The ID pin interrupts, if you are using two edge-triggered interrupts.
        //
        GpioInt(Edge, ActiveHigh, Exclusive, PullUp, 0, "\\_SB.GPI0", 0, ResourceConsumer, , ){0x1001}
        GpioInt(Edge, ActiveHigh, Exclusive, PullUp, 0, "\\_SB.GPI0", 0, ResourceConsumer, , ){0x1002}

        //
        // Following is an example of a single active-both interrupt.
        //
        // GpioInt(Edge, ActiveBoth, Exclusive, PullUp, 0, "\\_SB.GPI0", 0, ResourceConsumer, , ){0x12}
        //

        //
        // For a Type-C platform, you do not need to specify any interrupts here.
        //
    })

    //
    // This child device represents the USB host controller. This device node is in effect
    // when the controller is in host mode.
    // You may name the device whatever you want; we don't depend on it being called 'USB0'.
    //
    Device(USB0)
    {
        //
        // The host controller device node needs to have an address of '0'
        //
        Name(_ADR, 0)
        Name(_CRS, ResourceTemplate() {

            //
            // The controller interrupt.
            //
            Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive, , , ){0x10}
        })
    }

    //
    // This child device represents the USB function controller. This device node is in effect
    // when the controller is in device/function/peripheral mode.
    // You may name the device whatever you want; we don't depend on it being called 'UFN0'.
    //
    Device(UFN0)
    {
        //
        // The function controller device node needs to have an address of '1'
        //
        Name(_ADR, 1)
        Name(_CRS, ResourceTemplate() {

            //
            // The controller interrupt (this could be the same as the one defined in
            // the host controller).
            //
            Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive, , , ){0x11}
        })
    }
}

下面是对 ACPI 文件主要部分的一些解释:

  • URS0 是 USB 双角色控制器的 ACPI 定义。 URS 驱动程序会加载到此 ACPI 设备上。

  • USB0 和 UFN0 是 URS0 范围内的子设备。 USB0 和 UFN0 分别代表 URS 驱动程序枚举的两个子堆栈,以及主机堆栈和功能堆栈。 _ADR 是 ACPI 将这些设备定义与 URS 驱动程序创建的设备对象相匹配的方法。

  • 如果控制器在两个角色中使用相同的中断,则可以在两个子设备中描述相同的控制器中断。 即使在这种情况下,中断仍然可以被描述为“独占”。

  • 可以根据需要对该 ACPI 定义文件进行添加。 例如,可以在 ACPI 定义文件中的任何设备上设置任何其他必要的方法或属性。 这些添加不会干扰 URS 驱动程序的运行。 任何堆栈中需要的其他资源也可在相应设备的 _CRS 中描述。

URS 驱动程序会为主机和功能堆栈分配硬件 ID。 这些硬件 ID 源自 URS 设备的硬件 ID。 例如,如果有一个硬件 ID 为 ACPI\ABCD1234 的 URS 设备,那么 URS 驱动程序为主机和功能堆栈创建的硬件 ID 如下:

  • 主机堆栈:URS\ABCD1234&HOST

  • 功能堆栈:URS\ABCD1234&FUNCTION

INF 驱动程序安装包

如有必要,第三方驱动程序包可依赖于此方案。

如果你是一家 IHV 或 OEM,正在考虑提供自己的驱动程序包,那么以下是一些需要考虑的事项:

  • URS 驱动程序包

    每个平台上双角色控制器的硬件 ID 会被添加到 URS 的收件箱 INF 中。 但是,如果由于某种原因无法添加 ID,IHV/OEM 可以提供一个驱动程序包,该软件包的 INF 需要/包含收件箱 INF,并与其硬件 ID 相匹配。

    当 IHV/OEM 要求在驱动程序堆栈中提供筛选器驱动程序时,就需要使用此驱动包。

  • 主机驱动程序包

    需要使用 IHV/OEM 提供的驱动程序包,该驱动程序包需要/包含收件箱 usbxhci.inf 并与主机设备硬件 ID 匹配。 硬件 ID 的匹配将基于上一节所述的方案。

    当 IHV/OEM 要求在驱动程序堆栈中提供筛选器驱动程序时,就需要使用此驱动包。

    使 URS 驱动程序为主机设备分配 XHCI 兼容 ID 的工作正在进行中。

  • 功能驱动程序包

    需要使用 IHV/OEM 提供的驱动程序包,该驱动程序包需要/包含收件箱 Ufxsynopsys.inf 并与外围设备硬件 ID 匹配。 硬件 ID 的匹配将基于上一节所述的方案。

    IHV/OEM 还可以在驱动器包中包含一个筛选器驱动程序。

另请参阅