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

Linux USB 子系统深度解析

Linux USB 子系统深度解析

1. USB 基础概念与架构总览

1.1 USB 基础原理

USB(Universal Serial Bus)是一种广泛应用于计算机与外部设备连接的串行总线标准。Linux USB 子系统采用分层架构设计,完美实现了USB协议的复杂性抽象。

USB通信基础要素:

概念说明生活比喻
端点(Endpoint)USB设备上的数据收发点房子的门牌号
管道(Pipe)主机与端点间的逻辑连接连接房子的道路
接口(Interface)相关端点的功能集合房子的不同功能区
配置(Configuration)接口集合,设备同一时间只能激活一个配置房子的不同装修方案

1.2 Linux USB 子系统架构

内核空间
USB核心层
USB设备驱动
USB主机控制器驱动
用户空间
USB设备文件
USB硬件控制器
物理USB设备

2. 核心数据结构深度剖析

2.1 设备表示结构体

struct usb_device {int devnum;                    // 设备号char devpath[16];              // 设备路径enum usb_device_state state;   // 设备状态enum usb_device_speed speed;   // 设备速度// 设备描述符struct usb_device_descriptor descriptor;struct usb_host_config *config;struct usb_host_config *actconfig;// 总线相关信息struct usb_bus *bus;struct usb_host_endpoint ep0;// 设备树结构struct usb_device *parent;struct usb_bus *bus;struct device dev;// 引用计数struct kref kref;
};

2.2 驱动核心结构

struct usb_driver {const char *name;        // 驱动名称// 核心回调函数int (*probe)(struct usb_interface *intf,const struct usb_device_id *id);void (*disconnect)(struct usb_interface *intf);// USB设备ID表 - 驱动支持的设备const struct usb_device_id *id_table;// 电源管理int (*suspend)(struct usb_interface *intf, pm_message_t message);int (*resume)(struct usb_interface *intf);struct device_driver driver;
};

2.3 接口与端点结构

struct usb_interface {struct usb_host_interface *altsetting;  // 可选设置数组struct usb_host_interface *cur_altsetting; // 当前设置unsigned num_altsetting;                // 设置数量// 与驱动的关联struct usb_driver *driver;void *private_data;
};struct usb_host_endpoint {struct usb_endpoint_descriptor desc;    // 端点描述符struct list_head urb_list;              // URB链表void *hcpriv;                           // 主机控制器私有数据
};

2.4 数据结构关系图

管理
包含
包含
关联
关联
usb_driver
+char* name
+usb_device_id* id_table
+probe()
+disconnect()
usb_device
+int devnum
+usb_device_descriptor descriptor
+usb_host_config* config
+usb_bus* bus
usb_interface
+usb_host_interface* altsetting
+usb_driver* driver
usb_host_endpoint
+usb_endpoint_descriptor desc
+list_head urb_list
urb
+usb_device* dev
+usb_host_endpoint* ep
+void* transfer_buffer
+usb_complete_t complete

3. USB 请求块(URB)机制详解

3.1 URB 核心结构

URB(USB Request Block)是USB通信的基本单位,类似于网络数据包。

struct urb {// 基础设施struct kref kref;           // 引用计数void *hcpriv;               // 主机控制器私有数据atomic_t use_count;         // 并发使用计数atomic_t reject;            // 提交失败计数// 设备与端点信息struct usb_device *dev;     // 关联的USB设备struct usb_host_endpoint *ep; // 关联端点unsigned int pipe;          // 管道信息// 传输状态int status;                 // 完成状态unsigned int transfer_flags; // 传输标志// 数据传输void *transfer_buffer;      // 数据缓冲区u32 transfer_buffer_length; // 缓冲区长度u32 actual_length;          // 实际传输长度// 完成回调usb_complete_t complete;    // 传输完成回调函数void *context;              // 回调上下文// 等时传输特定字段int start_frame;            // 起始帧号int number_of_packets;      // 数据包数量int interval;               // 轮询间隔
};

3.2 URB 生命周期

应用程序USB核心主机控制器驱动硬件控制器usb_alloc_urb()usb_fill_bulk_urb()usb_submit_urb()提交URB到调度队列配置硬件传输传输完成中断完成回调调度调用complete回调函数usb_free_urb()应用程序USB核心主机控制器驱动硬件控制器

3.3 URB 传输类型对比

传输类型特点适用场景可靠性速度
控制传输可靠的请求/响应式设备配置、命令
批量传输可靠的大数据传输文件传输、打印
中断传输周期性的小数据传输键盘、鼠标
等时传输实时流数据,可能丢失音频、视频

4. USB 驱动开发实战

4.1 最简单的USB驱动示例

下面实现一个基础的USB骨架驱动:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>// 定义设备支持的USB设备ID表
static struct usb_device_id skel_table[] = {{ USB_DEVICE(0x1234, 0x5678) },  // 厂商ID:0x1234, 产品ID:0x5678{ }                              // 终止条目
};MODULE_DEVICE_TABLE(usb, skel_table);// 设备探测函数 - 当设备插入时调用
static int skel_probe(struct usb_interface *interface,const struct usb_device_id *id)
{struct usb_device *dev = interface_to_usbdev(interface);printk(KERN_INFO "USB Skeleton device connected\n");printk(KERN_INFO "Vendor:ID = %04x:%04x\n", le16_to_cpu(dev->descriptor.idVendor),le16_to_cpu(dev->descriptor.idProduct));// 分配设备私有数据结构// 初始化设备// 创建设备节点等return 0; // 成功返回0
}// 设备断开函数 - 当设备移除时调用
static void skel_disconnect(struct usb_interface *interface)
{printk(KERN_INFO "USB Skeleton device disconnected\n");// 清理资源// 释放分配的内存// 删除设备节点等
}// USB驱动结构定义
static struct usb_driver skel_driver = {.name = "usb-skeleton",.id_table = skel_table,.probe = skel_probe,.disconnect = skel_disconnect,
};// 模块初始化
static int __init usb_skel_init(void)
{int result;printk(KERN_INFO "USB Skeleton driver initializing\n");// 注册USB驱动result = usb_register(&skel_driver);if (result) {printk(KERN_ERR "usb_register failed. Error number %d\n", result);return result;}printk(KERN_INFO "USB Skeleton driver registered successfully\n");return 0;
}// 模块清理
static void __exit usb_skel_exit(void)
{printk(KERN_INFO "USB Skeleton driver unregistering\n");usb_deregister(&skel_driver);printk(KERN_INFO "USB Skeleton driver unregistered\n");
}module_init(usb_skel_init);
module_exit(usb_skel_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("USB Skeleton Driver");

4.2 数据传输示例

添加URB数据传输功能:

// 定义设备私有数据结构
struct usb_skel {struct usb_device *udev;struct usb_interface *interface;struct urb *bulk_in_urb;unsigned char *bulk_in_buffer;size_t bulk_in_size;__u8 bulk_in_endpointAddr;
};// 改进的探测函数
static int skel_probe(struct usb_interface *interface,const struct usb_device_id *id)
{struct usb_device *dev = interface_to_usbdev(interface);struct usb_skel *dev;struct usb_host_interface *iface_desc;struct usb_endpoint_descriptor *endpoint;int i;int retval = -ENOMEM;// 分配设备结构dev = kzalloc(sizeof(*dev), GFP_KERNEL);if (!dev)return -ENOMEM;dev->udev = usb_get_dev(dev);dev->interface = interface;// 查找批量输入端点iface_desc = interface->cur_altsetting;for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {endpoint = &iface_desc->endpoint[i].desc;if (!dev->bulk_in_endpointAddr &&usb_endpoint_is_bulk_in(endpoint)) {// 找到批量输入端点dev->bulk_in_size = le16_to_cpu(endpoint->wMaxPacketSize);dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;dev->bulk_in_buffer = kmalloc(dev->bulk_in_size, GFP_KERNEL);if (!dev->bulk_in_buffer) {retval = -ENOMEM;goto error;}// 分配URBdev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);if (!dev->bulk_in_urb) {retval = -ENOMEM;goto error;}}}// 保存设备数据到接口usb_set_intfdata(interface, dev);printk(KERN_INFO "USB Skeleton device now attached\n");return 0;error:skel_delete(dev);return retval;
}// URB完成回调函数
static void skel_read_bulk_callback(struct urb *urb)
{struct usb_skel *dev = urb->context;// 同步保护spin_lock(&dev->err_lock);// 检查URB状态switch (urb->status) {case 0:             // 成功// 处理接收到的数据printk(KERN_INFO "Received %d bytes of data\n", urb->actual_length);break;case -ECONNRESET:   // 异步取消case -ENOENT:case -ESHUTDOWN:// 设备断开,不需要处理break;default:            // 错误printk(KERN_ERR "URB error %d\n", urb->status);break;}spin_unlock(&dev->err_lock);
}// 启动读取操作
static int skel_start_read(struct usb_skel *dev)
{int result;if (!dev->bulk_in_urb || !dev->bulk_in_buffer)return -ENODEV;// 填充URBusb_fill_bulk_urb(dev->bulk_in_urb,dev->udev,usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),dev->bulk_in_buffer,dev->bulk_in_size,skel_read_bulk_callback,dev);// 提交URBresult = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);if (result) {printk(KERN_ERR "Failed to submit read URB: %d\n", result);}return result;
}

5. USB 子系统核心框架深度解析

5.1 完整的USB子系统架构

硬件层
内核空间
USB核心层
USB设备驱动层
主机控制器驱动层
用户空间
USB主机控制器
USB设备
VFS层
USB设备文件系统
UHCI驱动
OHCI驱动
EHCI驱动
xHCI驱动
HID驱动
存储驱动
网络驱动
自定义驱动
USB设备管理
USB总线管理
URB调度
配置描述符解析
应用程序
libusb库

5.2 设备枚举过程详解

主机控制器HCD驱动USB核心Hub驱动设备驱动检测到设备连接报告新设备获取设备描述符返回设备信息分配设备号创建设备文件设置设备地址获取配置描述符返回配置信息解析接口和端点loop[配置过程]调用probe函数初始化设备返回成功主机控制器HCD驱动USB核心Hub驱动设备驱动

6. 工具与调试手段

6.1 常用工具命令

工具命令功能描述示例用法
lsusb列出USB设备信息lsusb -v
usbmonUSB流量监控cat /sys/kernel/debug/usb/usbmon/0u
udevadm设备管理信息udevadm info -a -n /dev/bus/usb/001/001
dmesg查看内核日志dmesg | grep usb
usb-devices显示USB设备树usb-devices

6.2 调试技巧与实践

启用USB调试:

# 启用动态调试
echo 'module usbcore +p' > /sys/kernel/debug/dynamic_debug/control
echo 'module uhci_hcd +p' > /sys/kernel/debug/dynamic_debug/control# 查看USB设备树
ls /sys/bus/usb/devices/# 监控特定设备的URB
usbmon -i 1 -s 1024

内核配置选项:

# 确保以下配置开启
CONFIG_USB_DEBUG=y
CONFIG_USB_MON=y
CONFIG_DYNAMIC_DEBUG=y

7. 高级主题与性能优化

7.1 电源管理

// 电源管理操作
static int skel_suspend(struct usb_interface *intf, pm_message_t message)
{struct usb_skel *dev = usb_get_intfdata(intf);if (!dev)return 0;// 停止挂起的URBusb_kill_urb(dev->bulk_in_urb);return 0;
}static int skel_resume(struct usb_interface *intf)
{struct usb_skel *dev = usb_get_intfdata(intf);int retval = 0;if (!dev)return 0;// 重新提交URBretval = skel_start_read(dev);return retval;
}

7.2 scatter-gather DMA

// 使用scatterlist进行高效DMA传输
static int skel_perform_dma_transfer(struct usb_skel *dev,struct scatterlist *sg,int num_sgs,int direction)
{struct urb *urb;int retval;urb = usb_alloc_urb(0, GFP_KERNEL);if (!urb)return -ENOMEM;// 设置scatter-gather URBusb_fill_bulk_urb(urb, dev->udev,direction == USB_DIR_IN ?usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr) :usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),NULL, 0, skel_bulk_callback, dev);urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;urb->sg = sg;urb->num_sgs = num_sgs;urb->transfer_buffer_length = usb_sglist_size(sg, num_sgs);retval = usb_submit_urb(urb, GFP_KERNEL);if (retval) {usb_free_urb(urb);return retval;}return 0;
}

8. 总结

8.1 核心要点总结

架构层次清晰:

  1. 硬件抽象层:主机控制器驱动隔离硬件差异
  2. 核心调度层:统一管理设备、配置、URB调度
  3. 设备驱动层:提供具体设备的功能实现
  4. 用户接口层:通过设备文件和libusb提供用户空间访问

关键数据结构关系:

usb_driver
usb_interface
usb_device
usb_host_endpoint
urb
transfer_buffer
usb_device_id
usb_device_descriptor

8.2 性能优化建议

优化方面具体措施效果
URB管理批量提交URB,重用URB对象减少内存分配开销
数据传输使用scatter-gather DMA减少数据拷贝
中断处理底半部处理复杂逻辑减少中断延迟
电源管理及时暂停空闲设备降低功耗

8.3 开发最佳实践

  1. 错误处理:始终检查USB函数返回值,正确处理各种错误情况
  2. 资源管理:确保probe/disconnect函数中资源分配释放对称
  3. 并发安全:使用适当的锁机制保护共享数据
  4. 电源感知:正确实现suspend/resume回调
  5. 性能监控:使用USB监控工具持续优化性能
http://www.dtcms.com/a/557237.html

相关文章:

  • Linux time function in C/C++【2】
  • 人工智能学习中深度学习之python基础之迭代器、生成器、文件处理和模块等
  • wordpress显示评论数福建企业seo推广
  • 12.C++:模版进阶
  • 大模型训练评估中的交叉验证详解
  • 变更股东怎样在工商网站做公示做网站的收费标准
  • (142页PPT)立白MES解决方案1Wonderware运营管理平台(附下载方式)
  • 机器学习日报10
  • Linux 2.6.10 调度器负载均衡机制深度解析:从理论到实现
  • 访链家网网站开发嘉定房地产网站建设
  • 多商户商城APP源码开发的未来方向:云原生、电商中台与智能客服
  • Liunx线程安全
  • 基于数据增强与对抗学习的门诊电子病历(EMR)文本分类python编程
  • 企业网站seo推广技巧建设视频网站设计意义
  • VSCode的插件配置同步到gitee
  • 短剧广告联盟 APP 用户画像:基于观看行为的广告精准投放模型
  • 找快照网站查询网站建设博采
  • [论文阅读] AI+ | AI如何重塑审计行业?从“手工筛查”到“智能决策”:AI审计的核心逻辑与未来路径
  • 论文精读:A review on multi-view learning(多视图学习综述)
  • 长宁制作网站网站建设属于会计哪个科目
  • 波动率建模(三)Heston模型及其Python实现
  • 左侧 导航 网站泰安信誉好的网络推广公司
  • python 初学2
  • 51单片机基础-LCD12864液晶显示
  • 在openSUSE-Leap-15.6-DVD-x86_64-Media自制应用软件离线包——备份91个视频解码器的rpm包
  • 《云原生基础设施》
  • dedecms手机网站开发怎么在网站底部添加备案号
  • 2019个人建网站利用关键词进网站后台
  • 物联网技术与应用传感器学习笔记
  • 云架构设计与实践:从基础到未来趋势