当前位置: 首页 > news >正文

【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通过以下方式匹配设备和驱动:

  1. 设备ID匹配:基于vendor ID和product ID
  2. 接口类匹配:基于接口类别、子类别和协议
  3. 设备类匹配:基于设备类别

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 枚举步骤
  1. 设备连接检测:Hub检测到设备连接
  2. 设备复位:Hub对设备进行复位操作
  3. 地址分配:USB Core为新设备分配唯一地址
  4. 描述符读取:读取设备描述符获取基本信息
  5. 配置选择:选择合适的配置
  6. 接口驱动匹配:为每个接口寻找匹配的驱动
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_deviceDevice表示整个USB设备
usb_interfaceInterface表示设备的一个功能接口
usb_host_endpointEndpoint表示数据传输的端点
urbTransfer表示一次USB传输
usb_gadgetDeviceGadget模式下的设备表示
usb_functionFunctionGadget模式下的功能模块

4.3 驱动模型对比

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

5. 开发实践建议

5.1 USB设备驱动开发

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

5.2 Gadget驱动开发

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

5.3 调试技巧

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

6. 总结

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

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

http://www.dtcms.com/a/618127.html

相关文章:

  • Linux服务器配置ssh免密登陆多台服务器、服务器别名配置
  • 百度推广青岛公司网站在线优化
  • java学习3-redis集成
  • 【Linux】深入理解进程(四)(进程地址空间)
  • 数据结构1.0 面试题
  • 网站定制哪家快高档网站设计公司
  • 信创产品认证机构有哪些?信创检测报告和信创产品评估证书如何办理?
  • 官方网站建设计划书文山做网站yunling88
  • 数据分析笔记12:函数
  • 如何驯服AI编程
  • 电动自行车起火酿事故,智慧社区如何分阶段阻绝灾害发生?
  • 淄博做网站的公司排名优化系统
  • 基于Rust构建一个实用的图片转Base64工具
  • asp.net mvc做网站难吗胶州网站优化
  • [C#] NO.4 我的第一个项目
  • 运放之电压跟随器
  • CSS3 框大小
  • 商城网站系统资源
  • 网站源码怎么有苏州首页关键词优化
  • 深度学习实战(基于pytroch)系列(二十二)多通道输入输出
  • 本周热搜(11月9日~11月16日)
  • React useMemo(当依赖项未变化,重复渲染时直接返回上一次缓存计算结果,而非重新执行计算)
  • 【IOS开发】Objective-C 与 Swift 的对比
  • 在STM32 HAL库中使用 WFI 实现低功耗准确延时
  • 编程语言落地手册:erlang实现与汇编剖析
  • 搜索下单(es、mysql、MQ同步;关于事务失效)
  • aleph-node Node upgrade instructions 节点升级说明
  • 找谁做网站网站建设与运营培训班
  • 智能制造与工业4.0:5G与物联网的深度融合
  • GSV1201S(2201S)#ACP@支持 DisplayPort 1.2 到 HDMI 1.4 转换且集成嵌入式 MCU