3、USB设备端控制器:设备控制器功能、端点(Endpoint)概念、管道(Pipe)与传输类型
在USB枚举过程中,Host端与Device端的交互最终都落在设备控制器的硬件与固件配合上。理解设备控制器的内部功能、端点(Endpoint)的寻址模型、管道(Pipe)的逻辑映射以及四种传输类型的适用场景,是移植USB设备驱动的核心基础。本节从硬件架构出发,逐步拆解这些概念在枚举流程中的具体体现。
3.1 设备控制器功能
USB设备控制器(USB Device Controller, UDC)是嵌入在设备端(如MCU、SoC)中的硬件模块,负责处理USB总线上的协议层事务。其主要功能包括:
- 协议引擎:自动解析USB包格式(SOP、PID、数据、CRC),处理位填充与反填充。
- 事务管理:处理SETUP/IN/OUT事务,生成握手包(ACK/NAK/STALL)。
- 端点管理:提供多个物理或虚拟端点,每个端点对应一个FIFO或缓冲区。
- 中断生成:在完成一个USB事务或检测到总线事件(复位、挂起、恢复)时向CPU产生中断。
- DMA支持:部分控制器支持直接内存访问,减少CPU搬运数据的开销。
移植要点:在适配新平台时,需要重点关注UDC的中断处理机制、端点FIFO深度以及DMA通道配置。不同厂商(如Synopsys、NXP、ST)的UDC寄存器布局差异较大,但功能抽象层可统一。
3.2 端点(Endpoint)概念
端点是USB设备中唯一可寻址的数据缓冲区,每个端点都有一个唯一的端点号和方向(IN/OUT)。Host通过端点号与设备进行数据交换。端点0是所有USB设备必须实现的默认控制端点,用于枚举过程中的控制传输。
| 端点属性 | 说明 | 枚举阶段典型值 |
|---|---|---|
| 端点号 | 0~15(高速/全速),0~127(超高速) | 端点0固定用于控制传输 |
| 方向 | IN(设备→Host)或 OUT(Host→设备) | 端点0双向(SETUP+IN/OUT) |
| 传输类型 | 控制、批量、中断、同步 | 端点0必须为控制传输 |
| 最大包大小 | 取决于速度和传输类型 | 全速64字节,高速64字节 |
| 轮询间隔 | 中断/同步端点的帧间隔 | 枚举阶段不涉及 |
关键理解:端点0是枚举的“生命线”。在设备收到Set Address之前,所有通信都通过端点0进行。设备固件必须确保端点0的FIFO在复位后立即可用,且能正确处理SETUP、IN、OUT三种事务。
3.3 管道(Pipe)与传输类型
管道是Host软件与设备端点之间的逻辑连接。每个管道对应一个端点的地址、方向、传输类型和最大包大小。USB规范定义了四种传输类型,每种类型对应不同的应用场景和可靠性要求。
3.3.1 四种传输类型对比
| 传输类型 | 典型用途 | 带宽保证 | 错误重试 | 最大包大小(全速) | 枚举阶段使用 |
|---|---|---|---|---|---|
| 控制传输 | 枚举、配置、命令 | 10% 预留 | 是(自动重试) | 8/16/32/64 字节 | ✅ 必须 |
| 批量传输 | U盘、打印机数据 | 无(空闲时发送) | 是(硬件重试) | 8/16/32/64 字节 | ❌ 非必须 |
| 中断传输 | 鼠标、键盘、HID | 有(轮询间隔) | 是(硬件重试) | 1~64 字节 | ❌ 非必须 |
| 同步传输 | 音频、视频流 | 有(固定带宽) | 否(无重试) | 1~1023 字节 | ❌ 非必须 |
移植陷阱:在枚举阶段,Host只会使用控制传输(端点0)。如果设备固件错误地将端点0配置为批量或中断类型,Host将无法完成Get Descriptor请求,导致枚举失败。务必确认端点0的描述符中bmAttributes字段为0x00(控制传输)。
3.3.2 控制传输的四个阶段
控制传输是枚举的核心,由以下四个阶段组成:
- SETUP阶段:Host发送8字节的Setup包到端点0,包含请求类型、请求码、值、索引和长度。
- DATA阶段(可选):根据Setup包的方向,Host或设备发送数据。例如Get Descriptor请求中,设备返回描述符数据。
- STATUS阶段:接收方发送一个零长度包或握手包,表示传输完成。
- 错误处理:如果设备无法处理请求,返回STALL握手,Host将中止当前控制传输。
3.4 管道与端点映射的代码示例
在设备固件中,通常使用端点描述符数组来定义每个管道的属性。以下是一个典型的端点描述符定义示例(适用于全速设备):
/* 端点描述符结构体(USB 2.0规范) */
typedef struct {
uint8_t bLength; // 描述符长度(7字节)
uint8_t bDescriptorType; // 端点描述符类型(0x05)
uint8_t bEndpointAddress; // 端点地址(bit7:方向,bit3-0:端点号)
uint8_t bmAttributes; // 传输类型(0:控制,1:同步,2:批量,3:中断)
uint16_t wMaxPacketSize; // 最大包大小
uint8_t bInterval; // 轮询间隔(ms)
} __attribute__((packed)) usb_endpoint_descriptor_t;
/* 实际配置:端点1 IN 中断传输,64字节,轮询间隔10ms */
const usb_endpoint_descriptor_t ep1_in = {
.bLength = 7,
.bDescriptorType = 0x05,
.bEndpointAddress = 0x81, // 0x80 | 0x01 → EP1 IN
.bmAttributes = 0x03, // 中断传输
.wMaxPacketSize = 64,
.bInterval = 10
};
移植检查清单:在适配新UDC时,请确认以下端点相关寄存器配置正确:
• 端点使能寄存器(EP Enable)
• 端点类型寄存器(EP Type)
• 端点最大包大小寄存器(EP MaxPacket)
• 端点FIFO地址与大小(FIFO Base Address)
• 端点中断使能(EP Interrupt Enable)
• 端点使能寄存器(EP Enable)
• 端点类型寄存器(EP Type)
• 端点最大包大小寄存器(EP MaxPacket)
• 端点FIFO地址与大小(FIFO Base Address)
• 端点中断使能(EP Interrupt Enable)
3.5 传输类型选择策略
在设备枚举完成后,设备需要根据应用需求选择合适的传输类型。以下决策流程可帮助开发者快速确定:
- 是否需要可靠传输? → 是:控制/批量/中断;否:同步。
- 是否需要固定带宽? → 是:中断/同步;否:控制/批量。
- 数据量是否较大? → 是:批量;否:控制/中断。
- 是否对延迟敏感? → 是:中断;否:批量。
在枚举阶段,所有通信都使用控制传输。设备描述符中的bNumConfigurations字段决定了后续配置的数量,而每个配置中的接口描述符会进一步定义端点及其传输类型。
3.6 本章小结
设备控制器、端点和管道构成了USB设备端通信的三大基石。在枚举移植过程中,开发者需要重点关注:
- UDC的初始化时序(时钟、中断、FIFO)必须在Host复位后立即完成。
- 端点0必须配置为控制传输,且最大包大小与设备描述符一致。
- 管道映射关系由Host在Set Configuration时建立,设备固件只需正确报告端点描述符。
- 四种传输类型的选择直接影响设备性能和兼容性,枚举阶段仅使用控制传输。