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

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

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

注意

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

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

中断 (OUT)
FALSE
0x02 AUTO_CLEAR_STALL 在不停止数据流的情况下自动清除已停止的管道。 ) 中的批量 (

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

批量 (输出)

中断 (IN)

中断 (OUT)
控制) 5 秒 (5000 毫秒;其他 0
0x04 IGNORE_SHORT_PACKETS 在收到短数据包或读取一定数量的字节时完成读取请求。 如果文件大小未知,则请求会在短数据包处终止。 ) 中的批量 (

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

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

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

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

批量 (输出)

中断 (IN)

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

批量 (输出)

中断 (IN)

中断 (OUT)
FALSE

下表确定了有关如何使用每个管道策略的最佳做法,并描述了启用该策略时产生的行为。

策略 如果... 行为
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 会先重置终结点,然后再允许调用方向终结点发送新请求。