WinXP ECHCI驱动分析
+ -

USB 带宽管理中的32个时隙(TimeSlot)

2026-05-14 本文链接为:http://www.usbzh.com/article/detail-1664.html ,欢迎转载,转载请附上本文链接。

一、时隙的概念

时隙(Time Slot) 是 USB 总线带宽管理中的最小时间单位,每个时隙对应 1 毫秒(ms) 的时间间隔。

以下为32个时隙(覆盖32ms)

0ms 1ms 2ms 3ms 28ms 29ms 30ms 31ms
时隙0 时隙1 时隙2 时隙3 时隙28 时隙29 时隙30 时隙31

二、为什么是 32 个?

设计原因

因素 说明
USB 规范要求 中断端点的最大轮询间隔为 255ms,但常用范围是 1-32ms
轮询间隔对齐 USB 中断端点的轮询间隔必须是 2 的幂:1, 2, 4, 8, 16, 32ms
周期性覆盖 32ms是所有常用轮询间隔的最小公倍数
数组大小 32 是2的幂,便于位运算和数组索引计算

代码实现

UCHAR tmp;
UCHAR hsInterval;

if (endpoint->Parameters.DeviceSpeed == HighSpeed) {
    // normalize the high speed period to microframes
    // for USB 20 the period specifies a power of 2  
    // ie period = 2^(hsInterval-1)
    hsInterval = PipeHandle->EndpointDescriptor.bInterval;
    if (hsInterval) {
        hsInterval--;
    }
    // hsInterval must be 0..5
    if (hsInterval > 5) {
        hsInterval = 5;
    }
    tmp = 1<<hsInterval;
} 
else
{
    tmp = PipeHandle->EndpointDescriptor.bInterval;
}
// this code finds the first interval 
// <= USBPORT_MAX_INTEP_POLLING_INTERVAL
// valid intervals are:
// 1, 2, 4, 8, 16, 32(USBPORT_MAX_INTEP_POLLING_INTERVAL)

所以高速原始的的hsInterval的范围为[1,6],超过6的当6处理

由于时间期定固定为[1,2,4,8,16,32],所以对于tmp的值需要落到该值中的一个

//都先为32,这样超过32的都是32
endpoint->Parameters.Period = USBPORT_MAX_INTEP_POLLING_INTERVAL;//32
if ((tmp != 0) && (tmp < USBPORT_MAX_INTEP_POLLING_INTERVAL))
{
    // bInterval is in range.  Adjust Period down if necessary.
    if ((endpoint->Parameters.DeviceSpeed == LowSpeed) &&(tmp < 8))
    {
        // bInterval is not valid for LowSpeed, cap Period at 8
        //低速不能有<8的情况,因为低速必须大于1ms
        endpoint->Parameters.Period = 8;//1ms

    } else {
        // Adjust Period down to greatest power of 2 less than or equal to bInterval.
        //通过位运算找到与 tmp 有重叠位的最大 2 的幂,找到最大的n,使得 2^n ≤ tmp
        while ((endpoint->Parameters.Period & tmp) == 0) {
            endpoint->Parameters.Period >>= 1;
        }
    }
}

对于低全速,超过32就没有意义了,当32处理了,低于8当8处理
后面是向下取2的N次方最接近的那一个如7取8,19取16,因为只有[1,2,4,8,16,32]这几个。

轮询间隔与时隙的关系

// 中断端点的轮询间隔必须是 2 的幂
#define USBPORT_MAX_INTEP_POLLING_INTERVAL 32

// 常用轮询间隔
ULONG intervals[] = {1, 2, 4, 8, 16, 32};

三、时隙如何用于带宽管理

3.1 时隙分配原理

对于一个周期为 period 的中断端点,它会在每 period 毫秒内占用一次带宽:

示例:周期 = 8ms 的中断端点
┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
│ 时隙0│ 时隙1│ 时隙2│ 时隙3│ 时隙4│ 时隙5│ 时隙6│ 时隙7│
├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤
│ 占用 │      │      │      │      │      │      │      │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘

┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
│ 时隙8│ 时隙9│ 时隙10│时隙11│时隙12│时隙13│时隙14│时隙15│
├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤
│ 占用 │      │      │      │      │      │      │      │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘

以此类推,每隔 8ms 占用一个时隙

由于高速和低全速对bInterval的解释不一样,所以需要统一计算:

// 高速设备的周期计算
if (IsHighSpeed) {
    period = (ULONG)1 << (bInterval - 1);  // 2^(bInterval-1)
} else {
    period = bInterval;  // 低速/全速直接使用
}

3.2 数组索引计算

假设高速端点描述符中bInterval=3,那么每4ms查询一次
那么slot的值应为,其8个

 slot = 0, 4, 8, 12, 16, 20, 24, 28(覆盖32ms窗口)

3.3 带宽表更新

// 分配带宽时,从对应时隙中减去带宽
BandwidthTable[slot] -= bandwidth;

// 释放带宽时,恢复对应时隙的带宽
BandwidthTable[slot] += bandwidth;

四、时隙与不同轮询间隔的关系

示例:不同轮询间隔的时隙占用

轮询间隔 32ms 窗口内占用的时隙 计算公式
1ms 0, 1, 2, …, 31 slot = i (i=0..31)
2ms 0, 2, 4, …, 30 slot = 2*i
4ms 0, 4, 8, …, 28 slot = 4*i
8ms 0, 8, 16, 24 slot = 8*i
16ms 0, 16 slot = 16*i
32ms 0 slot = 0

可视化示例

32ms 时间窗口内的时隙占用情况:

轮询间隔=1ms:  ██████████████████████████████
轮询间隔=2ms:  █░█░█░█░█░█░█░█░█░█░█░█░█░█░█░
轮询间隔=4ms:  █░░░█░░░█░░░█░░░█░░░█░░░█░░░█░
轮询间隔=8ms:  █░░░░░░░█░░░░░░░█░░░░░░░█░░░░░
轮询间隔=16ms: █░░░░░░░░░░░░░░█░░░░░░░░░░░░░░
轮询间隔=32ms: █░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

█ = 占用时隙
░ = 空闲时隙

scheduleOffset

scheduleOffset 用于错开不同端点的查询时间,避免多个端点同时占用总线
当scheduleOffset=0时

for (i = 0; i < n; i++) {
    slot = scheduleOffset + i * period;
    // scheduleOffset=0: slot = 0,4,8,12,16,20,24,28 正确
}

当scheduleOffset=1时

for (i = 0; i < n; i++) {
    slot = scheduleOffset + i * period;
    // scheduleOffset=0: slot = 1,5,9,13,17,21,25,29 正确
}

scheduleOffset选择剩余带宽最大的位置 ,以平衡总线上的负载分布

┌─────────────────────────────────────────────────────────────────┐
│ 假设:period=4, bandwidth=1000 bps                               │
│                                                                 │
│ BandwidthTable[0..31] = [5000, 3000, 4000, 6000, ...]           │
│                                                                 │
│ scheduleOffset=0:                                               │
│   检查 slot: 0, 4, 8, 12, 16, 20, 24, 28                        │
│   最小可用带宽 = min(5000, ...) = 4000 bps                       │
│                                                                 │
│ scheduleOffset=1:                                               │
│   检查 slot: 1, 5, 9, 13, 17, 21, 25, 29                        │
│   最小可用带宽 = min(3000, ...) = 2000 bps                       │
│                                                                 │
│ scheduleOffset=2:                                               │
│   检查 slot: 2, 6, 10, 14, 18, 22, 26, 30                       │
│   最小可用带宽 = min(4000, ...) = 3500 bps                       │
│                                                                 │
│ scheduleOffset=3:                                               │
│   检查 slot: 3, 7, 11, 15, 19, 23, 27, 31                       │
│   最小可用带宽 = min(6000, ...) = 5500 bps  ← 最佳选择!          │
│                                                                 │
│ 最终选择 scheduleOffset=3,因为它的最小可用带宽最大                │
└─────────────────────────────────────────────────────────────────┘

五、设计优势

为什么使用 32 时隙方案?

优势 说明
精确调度 每个时隙独立管理,支持细粒度的带宽分配
周期对齐 32 是所有常用轮询间隔的最小公倍数,保证周期端点能完整覆盖
高效计算 32 是 2 的幂,数组索引计算可以用位运算优化
资源预留 保留 10% 带宽给控制/批量传输
公平性保证 通过最佳拟合算法(best-fit)平衡各时隙的负载

六、总结

问题 答案
32个时隙是什么 USB 总线带宽管理中的最小时间单位,每个时隙对应 1ms,共覆盖 32ms 时间窗口
为什么是32 32是常用轮询间隔(1/2/4/8/16/32ms)的最小公倍数,能完整覆盖所有中断端点的周期
如何使用 通过 BandwidthTable[32] 数组跟踪每个时隙的可用带宽,分配时从对应时隙减去带宽
设计目的 实现精确的带宽调度,保证实时传输的QoS,同时为异步传输预留资源

这种设计使得 USB 驱动能够高效地管理总线带宽,确保不同类型的传输(中断、等时、控制、批量)都能获得合理的资源分配。

本文链接为:http://www.usbzh.com/article/detail-1664.html ,欢迎转载,转载请附上本文链接。

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936     USB技术交流3:1031974172

0 篇笔记 写笔记

USB 带宽管理中的32个时隙(TimeSlot)
一、时隙的概念时隙(Time Slot) 是 USB 总线带宽管理中的最小时间单位,每个时隙对应 1 毫秒(ms) 的时间间隔。以下为32个时隙(覆盖32ms)0ms1ms2ms3ms…28ms29ms30ms31ms时隙0时隙1时隙2时隙3…时隙28......
USB带宽管理完整流程
USB设备的带宽管理由USB控制器如ECHI统一管理。USB控制器驱动启动时 (USBPORT_StartDevice)├─► TotalBusBandwidth = 微端口报告的带宽└─► BandwidthTable[i] = TotalBusBandwidth * 0.9 (保留10%给控......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • CDC
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • USB资源
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    您的支持,是我们前进的动力!