1. 基本定义
URB 是 USB 请求块(USB Request Block)的缩写,为 Linux USB 子系统中的核心数据结构,用于描述一个完整的 USB 传输请求(如控制传输、批量传输等)。
USB充当主机控制器驱动(如 OHCI/UHCI)与 USB 设备驱动之间的通信媒介。
2. 数据结构(简化版)
struct urb {
    struct usb_device *dev;          // 目标USB设备
    unsigned int pipe;               // 管道信息(设备地址+端点号+传输类型)
    void *transfer_buffer;          // 数据缓冲区
    int transfer_buffer_length;     // 数据长度
    usb_complete_t complete;        // 回调函数
    void *context;                  // 回调上下文
    int status;                     // 传输状态(成功/错误码)
    int actual_length;              // 实际传输的字节数
    // ...其他控制字段(ISO帧描述、间隔时间等)
};3. 生命周期
4. 关键字段解析
| 字段 | 作用 | 
|---|---|
| pipe | 编码目标端点、传输类型和方向(详见 usb_sndctrlpipe()等宏) | 
| transfer_buffer | DMA映射后的物理地址(由主机控制器直接访问) | 
| status | 传输结果(如 -EPIPE表示端点错误,0表示成功) | 
| actual_length | 实际传输的数据长度(可能小于 transfer_buffer_length) | 
5. 传输类型支持
URB 可处理所有 USB 传输类型:
| 类型 | 初始化函数 | 典型应用 | 
|---|---|---|
| 控制传输 | usb_fill_control_urb() | 设备配置/命令 | 
| 批量传输 | usb_fill_bulk_urb() | 大文件传输(U盘等) | 
| 中断传输 | usb_fill_int_urb() | 键盘/鼠标事件 | 
| 等时传输 | usb_fill_iso_urb() | 音频/视频流 | 
6. 驱动开发示例
批量传输URB提交
struct urb *urb;
void *buf = kmalloc(BUF_SIZE, GFP_KERNEL);
// 1. 分配URB
urb = usb_alloc_urb(0, GFP_KERNEL);
// 2. 填充批量URB参数
usb_fill_bulk_urb(urb, dev, usb_sndbulkpipe(dev, ep_num), 
                 buf, BUF_SIZE, complete_cb, dev);
// 3. 提交URB
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
    err("提交失败: %d", ret);
    usb_free_urb(urb);
}完成回调函数
void complete_cb(struct urb *urb) {
    if (urb->status) {
        printk("传输错误: %d\n", urb->status);
    } else {
        printk("成功传输%d字节\n", urb->actual_length);
    }
    usb_free_urb(urb);  // 释放URB
}7. 内核实现机制
URB 的底层处理依赖主机控制器驱动(如 OHCI)的 TD(Transfer Descriptor)链:
- URB 分解:USB Core 将 URB 拆分为多个 TD(根据端点最大包大小)
- 硬件调度:主机控制器按 ED(Endpoint Descriptor)组织 TD 链
- 中断反馈:传输完成后通过 HcInterruptStatus通知内核
8. 错误处理
| 错误码 | 含义 | 处理建议 | 
|---|---|---|
| -ENOMEM | 内存不足 | 减少请求大小或重试 | 
| -ENODEV | 设备已断开 | 停止后续URB提交 | 
| -EPIPE | 端点暂停(Stall) | 调用 usb_clear_halt() | 
9. 性能优化
- URB 池化:预分配多个 URB 避免动态分配开销
- 异步提交:在完成回调中提交下一个 URB 保持管道饱和
- 批量化:对大数据传输使用 scatter-gather DMA
10. 与用户空间的交互
通过 ioctl 或 usbfs 可将 URB 暴露给用户程序,实现自定义设备控制(如 libusb 库的核心机制)。
状态:未修正
 我的书签
 我的书签
                                 添加书签
 添加书签 移除书签
 移除书签