欢迎光临
我们一直在努力

【Linux驱动开发】Linux USB驱动架构详解

Linux USB驱动架构详解

概述

Linux USB子系统是Linux内核中最复杂的子系统之一,它支持USB主机模式、设备模式和OTG模式。USB驱动架构分为三个主要部分:USB主机驱动、USB设备驱动和USB Gadget驱动。本文将深入分析这三个部分的工作原理和实现机制。

1. USB主机驱动架构

1.1 USB主机控制器类型

USB主机控制器(Host Controller Device, HCD)是USB主机侧的核心组件,负责管理USB总线上的所有通信。Linux内核支持多种类型的USB主机控制器:

1.1.1 不同类型的HCD
  • OHCI (Open Host Controller Interface):USB 1.1标准,支持低速(1.5Mbps)和全速(12Mbps)设备
  • UHCI (Universal Host Controller Interface):Intel提出的USB 1.1标准,同样支持低速和全速设备
  • EHCI (Enhanced Host Controller Interface):USB 2.0标准,支持高速(480Mbps)设备
  • xHCI (eXtensible Host Controller Interface):USB 3.0及以上标准,支持超高速(5Gbps)设备
1.1.2 HCD驱动架构

USB主机驱动采用分层架构:

USB设备驱动层

USB核心层 (USB Core)

主机控制器驱动层 (HCD)

硬件层

1.2 USB核心层(USB Core)

USB Core是USB子系统的核心,提供以下功能:

1.2.1 设备枚举和管理
  • 检测设备连接和断开
  • 读取设备描述符信息
  • 分配设备地址
  • 配置设备参数
1.2.2 URB管理

USB Request Block (URB)是USB通信的基本单元:

struct urb {
struct kref kref; /* 引用计数 */
void *hcpriv; /* HCD私有数据 */
struct list_head urb_list; /* URB链表 */
struct usb_device *dev; /* 目标设备 */
unsigned int pipe; /* 管道信息 */
int status; /* URB状态 */
unsigned int transfer_flags; /* 传输标志 */
void *transfer_buffer; /* 传输缓冲区 */
dma_addr_t transfer_dma; /* DMA地址 */
int transfer_buffer_length; /* 缓冲区长度 */
int actual_length; /* 实际传输长度 */
unsigned char *setup_packet; /* 控制传输设置包 */
int start_frame; /* 等时传输起始帧 */
int number_of_packets; /* 等时传输包数量 */
int interval; /* 中断传输间隔 */
int error_count; /* 错误计数 */
void *context; /* 完成回调上下文 */
usb_complete_t complete; /* 完成回调函数 */
/* … 其他字段 */
};

1.2.3 驱动匹配机制

USB Core通过以下方式匹配设备和驱动:

  • 设备ID匹配:基于vendor ID和product ID
  • 接口类匹配:基于接口类别、子类别和协议
  • 设备类匹配:基于设备类别
  • 1.3 HCD驱动实现

    以xHCI驱动为例,HCD驱动需要实现以下关键函数:

    static const struct hc_driver xhci_hc_driver = {
    .description = "xhci-hcd",
    .product_desc = "xHCI Host Controller",
    .hcd_priv_size = sizeof(struct xhci_hcd),

    /* 基本生命周期操作 */
    .reset = xhci_reset,
    .start = xhci_run,
    .stop = xhci_stop,
    .shutdown = xhci_shutdown,

    /* URB管理 */
    .urb_enqueue = xhci_urb_enqueue,
    .urb_dequeue = xhci_urb_dequeue,

    /* 端点管理 */
    .endpoint_disable = xhci_endpoint_disable,
    .endpoint_reset = xhci_endpoint_reset,

    /* 根Hub管理 */
    .hub_status_data = xhci_hub_status_data,
    .hub_control = xhci_hub_control,

    /* 设备管理 */
    .alloc_dev = xhci_alloc_dev,
    .free_dev = xhci_free_dev,

    /* 其他必要函数 */
    .get_frame_number = xhci_get_frame_number,
    .irq = xhci_irq,
    };

    2. USB设备驱动模型

    2.1 USB设备层次结构

    USB设备采用树形层次结构:

    USB设备 (Device)
    ├── 配置 (Configuration)
    │ ├── 接口 (Interface)
    │ │ ├── 端点 (Endpoint)
    │ │ ├── 端点 (Endpoint)
    │ │ └── …
    │ ├── 接口 (Interface)
    │ └── …
    ├── 配置 (Configuration)
    └── …

    2.1.1 设备描述符

    struct usb_device_descriptor {
    __u8 bLength; /* 描述符长度 */
    __u8 bDescriptorType; /* 描述符类型 */
    __le16 bcdUSB; /* USB版本号 */
    __u8 bDeviceClass; /* 设备类别 */
    __u8 bDeviceSubClass; /* 设备子类别 */
    __u8 bDeviceProtocol; /* 设备协议 */
    __u8 bMaxPacketSize0; /* 端点0最大包大小 */
    __le16 idVendor; /* 厂商ID */
    __le16 idProduct; /* 产品ID */
    __le16 bcdDevice; /* 设备版本号 */
    __u8 iManufacturer; /* 厂商字符串索引 */
    __u8 iProduct; /* 产品字符串索引 */
    __u8 iSerialNumber; /* 序列号字符串索引 */
    __u8 bNumConfigurations; /* 配置数量 */
    } __attribute__ ((packed));

    2.1.2 接口描述符

    struct usb_interface_descriptor {
    __u8 bLength; /* 描述符长度 */
    __u8 bDescriptorType; /* 描述符类型 */
    __u8 bInterfaceNumber; /* 接口编号 */
    __u8 bAlternateSetting; /* 备用设置 */
    __u8 bNumEndpoints; /* 端点数量 */
    __u8 bInterfaceClass; /* 接口类别 */
    __u8 bInterfaceSubClass; /* 接口子类别 */
    __u8 bInterfaceProtocol; /* 接口协议 */
    __u8 iInterface; /* 接口字符串索引 */
    } __attribute__ ((packed));

    2.1.3 端点描述符

    struct usb_endpoint_descriptor {
    __u8 bLength; /* 描述符长度 */
    __u8 bDescriptorType; /* 描述符类型 */
    __u8 bEndpointAddress; /* 端点地址 */
    __u8 bmAttributes; /* 端点属性 */
    __le16 wMaxPacketSize; /* 最大包大小 */
    __u8 bInterval; /* 轮询间隔 */

    /* USB 3.0扩展字段 */
    __u8 bRefresh;
    __u8 bSynchAddress;
    } __attribute__ ((packed));

    2.2 USB驱动注册和匹配

    2.2.1 USB驱动结构

    struct usb_driver {
    const char *name; /* 驱动名称 */

    /* 当设备匹配成功时调用 */
    int (*probe)(struct usb_interface *intf,
    const struct usb_device_id *id);

    /* 设备断开时调用 */
    void (*disconnect)(struct usb_interface *intf);

    /* 设备挂起时调用 */
    int (*suspend)(struct usb_interface *intf, pm_message_t message);

    /* 设备恢复时调用 */
    int (*resume)(struct usb_interface *intf);

    /* 设备重置前调用 */
    int (*pre_reset)(struct usb_interface *intf);

    /* 设备重置后调用 */
    int (*post_reset)(struct usb_interface *intf);

    /* 设备ID表 */
    const struct usb_device_id *id_table;

    /* 其他字段 */
    struct usbdrv_wrap drvwrap;
    unsigned int no_dynamic_id:1;
    unsigned int supports_autosuspend:1;
    unsigned int disable_hub_initiated_lpm:1;

    /* 设备组 */
    const struct attribute_group **dev_groups;
    };

    2.2.2 设备ID表

    struct usb_device_id {
    __u16 match_flags; /* 匹配标志 */
    __u16 idVendor; /* 厂商ID */
    __u16 idProduct; /* 产品ID */
    __u16 bcdDevice_lo; /* 设备版本号下限 */
    __u16 bcdDevice_hi; /* 设备版本号上限 */
    __u8 bDeviceClass; /* 设备类别 */
    __u8 bDeviceSubClass; /* 设备子类别 */
    __u8 bDeviceProtocol; /* 设备协议 */
    __u8 bInterfaceClass; /* 接口类别 */
    __u8 bInterfaceSubClass; /* 接口子类别 */
    __u8 bInterfaceProtocol; /* 接口协议 */
    __u8 bInterfaceNumber; /* 接口编号 */
    kernel_ulong_t driver_info; /* 驱动私有信息 */
    };

    2.3 USB设备枚举过程

    USB设备枚举是USB Core自动完成的复杂过程:

    2.3.1 枚举步骤
  • 设备连接检测:Hub检测到设备连接
  • 设备复位:Hub对设备进行复位操作
  • 地址分配:USB Core为新设备分配唯一地址
  • 描述符读取:读取设备描述符获取基本信息
  • 配置选择:选择合适的配置
  • 接口驱动匹配:为每个接口寻找匹配的驱动
  • 2.3.2 枚举过程中的关键函数

    /* 设备添加 */
    int usb_new_device(struct usb_device *udev);

    /* 设备配置 */
    int usb_configure_device(struct usb_device *udev);

    /* 接口驱动匹配 */
    int usb_probe_interface(struct usb_interface *intf);

    3. USB Gadget驱动框架

    3.1 Gadget驱动架构

    USB Gadget驱动使Linux系统能够作为USB设备工作,其架构分为多层:

    Gadget Function驱动层

    Composite层 (可选)

    Gadget Function API层

    UDC (USB Device Controller)驱动层

    硬件层

    3.2 UDC驱动

    USB Device Controller (UDC)驱动直接控制USB设备控制器硬件:

    3.2.1 UDC驱动结构

    struct usb_gadget {
    const struct usb_gadget_ops *ops; /* 操作函数 */
    struct usb_ep *ep0; /* 端点0 */
    struct list_head ep_list; /* 端点链表 */
    enum usb_device_speed speed; /* 当前速度 */
    enum usb_device_speed max_speed; /* 最大速度 */
    unsigned int is_dualspeed:1; /* 是否支持双速 */
    unsigned int is_otg:1; /* 是否支持OTG */
    unsigned int is_a_peripheral:1; /* 是否为A设备外设 */
    unsigned int b_hnp_enable:1; /* B设备HNP使能 */
    unsigned int a_hnp_support:1; /* A设备HNP支持 */
    unsigned int a_alt_hnp_support:1; /* A设备备用HNP支持 */
    const char *name; /* 控制器名称 */
    struct device *dev; /* 设备结构 */
    };

    3.2.2 Gadget操作函数

    struct usb_gadget_ops {
    int (*get_frame)(struct usb_gadget *gadget);
    int (*wakeup)(struct usb_gadget *gadget);
    int (*set_selfpowered)(struct usb_gadget *gadget, int is_selfpowered);
    int (*vbus_session)(struct usb_gadget *gadget, int is_active);
    int (*vbus_draw)(struct usb_gadget *gadget, unsigned mA);
    int (*pullup)(struct usb_gadget *gadget, int is_on);
    int (*ioctl)(struct usb_gadget *gadget,
    unsigned code, unsigned long param);
    };

    3.3 Gadget Function驱动

    Gadget Function驱动实现具体的USB设备功能:

    3.3.1 Function驱动结构

    struct usb_function {
    const char *name; /* 功能名称 */
    struct usb_gadget_strings **strings; /* 字符串描述符 */
    struct usb_descriptor_header **descriptors; /* 描述符 */
    struct usb_descriptor_header **hs_descriptors; /* 高速描述符 */
    struct usb_descriptor_header **ss_descriptors; /* 超高速描述符 */

    /* 配置管理 */
    int (*bind)(struct usb_configuration *, struct usb_function *);
    void (*unbind)(struct usb_configuration *, struct usb_function *);

    /* 接口管理 */
    int (*set_alt)(struct usb_function *, unsigned interface, unsigned alt);
    int (*get_alt)(struct usb_function *, unsigned interface);
    void (*disable)(struct usb_function *);

    /* USB请求处理 */
    int (*setup)(struct usb_function *, const struct usb_ctrlrequest *);
    void (*suspend)(struct usb_function *);
    void (*resume)(struct usb_function *);

    /* 其他字段 */
    struct usb_configuration *config;
    struct list_head list;
    struct usb_ep *ep0;
    struct list_head ep_list;
    };

    3.3.2 常用Function驱动
    • mass_storage:U盘功能
    • acm:USB串口功能
    • rndis:USB网络功能
    • uac:USB音频功能
    • uvc:USB视频功能

    3.4 Composite框架

    Composite框架支持将多个Function组合成一个复合设备:

    3.4.1 Composite驱动结构

    struct usb_composite_driver {
    const char *name; /* 驱动名称 */
    const struct usb_device_descriptor *dev; /* 设备描述符 */
    struct usb_gadget_strings **strings; /* 字符串描述符 */

    /* 生命周期管理 */
    int (*bind)(struct usb_composite_dev *cdev);
    int (*unbind)(struct usb_composite_dev *cdev);

    /* 挂起和恢复 */
    void (*suspend)(struct usb_composite_dev *cdev);
    void (*resume)(struct usb_composite_dev *cdev);

    /* USB请求处理 */
    int (*setup)(struct usb_composite_dev *cdev,
    const struct usb_ctrlrequest *ctrl);

    /* 其他字段 */
    struct usb_gadget_driver gadget_driver;
    unsigned needs_serial:1;
    unsigned max_speed:4;
    };

    3.5 ConfigFS配置接口

    ConfigFS提供了用户空间配置Gadget的接口:

    3.5.1 ConfigFS使用示例

    # 创建Gadget配置
    mkdir /sys/kernel/config/usb_gadget/g1
    cd /sys/kernel/config/usb_gadget/g1

    # 设置设备描述符
    echo 0x18d1 > idVendor # Google
    echo 0x4e11 > idProduct # Nexus 4

    # 创建配置
    mkdir configs/c.1
    echo 120 > configs/c.1/MaxPower

    # 创建功能
    mkdir functions/mass_storage.usb0
    mkdir functions/acm.usb1

    # 绑定功能到配置
    ln -s functions/mass_storage.usb0 configs/c.1/
    ln -s functions/acm.usb1 configs/c.1/

    # 绑定到UDC
    echo "musb-hdrc.0.auto" > UDC

    4. 核心数据结构总结

    4.1 USB核心数据结构关系

    usb_device
    ├── usb_device_descriptor
    ├── usb_config
    │ ├── usb_configuration
    │ └── usb_interface
    │ ├── usb_interface_descriptor
    │ └── usb_host_endpoint
    │ └── usb_endpoint_descriptor
    └── usb_host_endpoint (ep0)

    4.2 关键数据结构映射

    内核结构USB规范作用
    usb_device Device 表示整个USB设备
    usb_interface Interface 表示设备的一个功能接口
    usb_host_endpoint Endpoint 表示数据传输的端点
    urb Transfer 表示一次USB传输
    usb_gadget Device Gadget模式下的设备表示
    usb_function Function Gadget模式下的功能模块

    4.3 驱动模型对比

    特性主机模式设备模式(Gadget)
    控制器驱动 HCD驱动 UDC驱动
    设备驱动 USB设备驱动 Function驱动
    枚举过程 自动枚举 手动配置
    复合设备 自动识别 Composite框架
    配置接口 内核内部 ConfigFS

    5. 开发实践建议

    5.1 USB设备驱动开发

  • 分析设备描述符:使用lsusb -v命令获取设备详细信息
  • 确定驱动类型:根据接口类别或设备ID选择合适的匹配方式
  • 实现基本功能:probe、disconnect、urb处理函数
  • 处理错误情况:URB错误处理和设备状态管理
  • 电源管理:实现suspend和resume函数
  • 5.2 Gadget驱动开发

  • 选择开发方式:Legacy方式或ConfigFS方式
  • 确定功能需求:选择合适的Function驱动或开发自定义Function
  • 配置描述符:准备USB描述符信息
  • 实现回调函数:setup、set_alt、disable等关键函数
  • 测试验证:使用USB协议分析仪进行验证
  • 5.3 调试技巧

  • 启用调试信息:配置内核USB调试选项
  • 使用调试工具:usbmon、usbview等工具
  • 查看系统日志:dmesg和syslog中的USB相关信息
  • 分析URB传输:使用usbmon捕获URB传输数据
  • 检查描述符:验证USB描述符的正确性
  • 6. 总结

    Linux USB驱动架构是一个高度模块化和分层的系统,通过清晰的接口定义实现了主机和设备模式的统一管理。理解USB协议规范、掌握核心数据结构、熟悉驱动框架是开发高质量USB驱动的关键。随着USB技术的不断发展,新的USB标准和功能不断涌现,开发者需要持续学习和跟进最新的技术趋势。

    USB驱动开发涉及硬件协议、内核编程、设备管理等多个方面,需要开发者具备扎实的理论基础和丰富的实践经验。通过深入理解本文介绍的架构原理和实现机制,开发者可以更好地开发和调试USB驱动程序。

    赞(0)
    未经允许不得转载:171主机测评 » 【Linux驱动开发】Linux USB驱动架构详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址