用于管道策略修改的 WinUSB 函数

若要使应用程序能够获取和设置终结点管道的默认策略参数,Winusb.dll公开 WinUsb_GetPipePolicy 函数以检索管道的默认策略。 WinUsb_SetPipePolicy函数允许应用程序将策略参数设置为新值。

WinUSB 允许通过向终结点管道应用策略来修改其默认行为。 使用这些策略,可以将 WinUSB 配置为最符合设备的功能。 下表提供了 WinUSB 支持的管道策略列表。

注意

表中所述的策略仅适用于指定的终结点。 在其他终结点上设置策略不会影响 WinUSB 读取或写入请求的行为。

策略编号 策略名称 说明 终结点(方向) 默认值
0x01 SHORT_PACKET_TERMINATE 为写入请求发送长度为零的数据包,其中缓冲区是终结点支持的最大数据包大小的倍数。 批量 (OUT)

中断 (OUT)
FALSE
0x02 AUTO_CLEAR_STALL 自动清除停止的管道,而不停止数据流。 批量 (IN)

中断(IN)
FALSE
0x03 PIPE_TRANSFER_TIMEOUT 在取消请求之前,等待超时间隔(以毫秒为单位)。 批量 (IN)

批量 (OUT)

中断(IN)

中断 (OUT)
5 秒(5000 毫秒)控制:0 供他人使用
0x04 IGNORE_SHORT_PACKETS 在收到短数据包或读取特定字节数时完成读取请求。 如果文件大小未知,则请求以短数据包终止。 批量 (IN)

中断(IN)
FALSE
0x05 ALLOW_PARTIAL_READS 允许从返回的数据多于调用方请求的设备读取请求。 批量 (IN)

中断(IN)
TRUE
0x06 AUTO_FLUSH 保存读取请求中的多余的数据,并将其添加到下一个读取请求或放弃多余的数据。 批量 (IN)

中断(IN)
FALSE
0x07 RAW_IO 绕过队列和错误处理以提高多个读取请求的性能。 批量 (IN)

中断(IN)
FALSE
0x08 MAXIMUM_TRANSFER_SIZE 获取 WinUSB 支持的 USB 传输的最大大小。 这是一个只读策略,可通过调用 WinUsb_GetPipePolicy进行检索。 批量 (IN)

批量 (OUT)

中断(IN)

中断 (OUT)
0x09 RESET_PIPE_ON_RESUME 在接受新请求之前从暂停恢复后重置终结点的管道。 批量 (IN)

批量 (OUT)

中断(IN)

中断 (OUT)
FALSE

下表标识了如何使用每个管道策略的最佳做法,并描述了启用策略时生成的行为。

策略 启用 if... 行为
SHORT_PACKET_TERMINATE(0x01) 设备要求以零长度数据包终止 OUT 传输。 大多数设备都不需要此要求。 如果启用(策略参数值为 TRUE 或非零),则每个写入请求都是终结点支持的最大数据包大小的倍数,后跟零长度数据包。

将数据发送到主机控制器后,WinUSB 发送包含零长度数据包的写入请求,然后完成由WinUsb_WritePipe创建的请求。
AUTO_CLEAR_STALL 你不希望失败的传输使终结点处于停滞状态。 仅当禁用RAW_IO时,才会对终结点发出多个挂起的读取请求时,此策略才有用。
  • 如果启用(策略参数值为 TRUE 或非零),则会自动清除停止条件。 此策略参数不会影响控制管道。

    当读取请求失败并且主机控制器返回STATUS_CANCELLED或STATUS_DEVICE_NOT_CONNECTED以外的状态时,WinUSB 会在完成失败的请求之前重置管道。 重置管道会清除停止条件,而不会中断数据流。 只要新传输一直从设备到达,数据将继续流入终结点。 新的传输可以包括发生停止时队列中的传输。

    启用此策略不会显著影响性能。

  • 如果禁用(策略参数值为 FALSE 或零),则在停止传输后到达终结点的所有传输都会失败,直到调用方通过调用 WinUsb_ResetPipe手动重置终结点的管道。
PIPE_TRANSFER_TIMEOUT 你希望将传输到终结点在特定时间内完成。
  • 如果设置为零(默认值),则传输不会超时,因为主机控制器不会取消传输。 在这种情况下,传输将无限期等待,直到手动取消或传输正常完成。
  • 如果设置为非零值(超时间隔),则主机控制器在收到传输请求时启动计时器。 当计时器超过设置的超时间隔时,将取消请求。

    由于计时器管理,会出现轻微的性能损失。

    请求在 WinUSB 队列中等待时不会超时。

    在 Windows Vista 中,对于所有传输(启用RAW_IO传输除外),WinUSB 会将请求排入队列,直到目标终结点上以前的所有传输都已完成。 主机控制器不包括超时间隔的计算中的排队时间。

    启用RAW_IO后,WinUSB 不会对请求进行排队。 相反,它会将请求直接传递到 USB 堆栈,而 USB 堆栈是否正忙于处理以前的传输。 如果 USB 堆栈繁忙,则它可以延迟处理新请求。 这可能会导致超时。
IGNORE_SHORT_PACKETS RAW_IO已禁用,并且不希望短数据包完成读取请求。
  • 如果启用(策略参数值为 TRUE 或非零),则主机控制器在收到短数据包后不会立即完成读取操作。 而是仅在以下情况下完成该操作:
    • 发生错误。
    • 请求已取消。
    • 已收到所有请求的字节。
  • 如果禁用(策略参数值为 FALSE 或零),则主机控制器在读取请求的字节数或收到短数据包后完成读取操作。
ALLOW_PARTIAL_READS 如果请求缓冲区的大小是最大终结点数据包大小的倍数,设备可以发送的数据量超过所请求的数据。

如果应用程序想要读取几个字节来确定要读取的总字节数,请使用。
  • 如果禁用(策略参数值为 FALSE 或零),并且设备返回的数据数超过所请求的数据,则 WinUSB 将完成请求并显示错误。
  • 如果启用(策略参数值为 TRUE 或非零),并且设备返回的数据数超过所请求的数据,则 WinUSB 可以(具体取决于AUTO_FLUSH设置)将读取请求中的多余的数据添加到下一个读取请求的开头或丢弃多余的数据。

    如果启用,WinUSB 将立即成功完成零字节的读取请求,并且不会将请求向下发送堆栈。
AUTO_FLUSH 已启用ALLOW_PARTIAL_READS策略。

设备可以发送的数据数超过所请求的数据,并且应用程序不需要任何其他数据。 如果请求缓冲区的大小是最大终结点数据包大小的倍数,则可能会发生这种情况。
AUTO_FLUSH在启用ALLOW_PARTIAL_READS时定义 WinUSB 的行为。 如果禁用ALLOW_PARTIAL_READS,WinUSB 将忽略AUTO_FLUSH值。

WinUSB 可以放弃剩余数据,也可以随调用方下一次读取请求一起发送数据。

  • 如果启用(策略参数值为 TRUE 或非零),则 WinUSB 将放弃额外的字节,而无需任何错误代码。
  • 如果禁用(策略参数值为 FALSE 或零),WinUSB 会保存额外的字节,将其添加到调用方下一次读取请求的开头,然后在下一次读取操作中将数据发送到调用方。
RAW_IO 性能是优先级,应用程序将同时向同一终结点提交读取请求。

RAW_IO对调用方在WinUsb_ReadPipe传递的缓冲区施加某些限制:

  • 缓冲区长度必须是最大终结点数据包大小的倍数。
  • 长度必须小于或等于WinUsb_GetPipePolicy检索MAXIMUM_TRANSFER_SIZE的值。
如果启用,则传输绕过队列和错误处理,以提高多个读取请求的性能。 WinUSB 处理读取请求,如下所示:

  • 不是最大终结点数据包大小的倍数的请求失败。
  • 大于 WinUSB 支持的最大传输大小的请求失败。
  • 所有格式良好的请求会立即发送到 USB 核心堆栈,以在主机控制器中计划。


启用此设置可显著改善多个读取请求的性能,方法是减少一个传输的最后一个数据包与下一个传输的第一个数据包之间的延迟。
RESET_PIPE_ON_RESUME 设备不会在挂起时保留其数据切换状态。 在从挂起恢复时,WinUSB 会在允许调用方向终结点发送新请求之前重置该终结点。