Linux下usb设备驱动框架实现:定义核心结构体数据

一. 简介

在 Linux 嵌入式开发中,USB 设备驱动的实现需要遵循 Linux 内核的 USB 子系统框架。USB 驱动通常分为USB 主机端驱动 (Host Driver)和USB 设备端驱动(Device Driver),这里主要学习实现 usb设备驱动框架。

前面几篇文章简单学习了 Linux下usb设备驱动相关的内容。本文开始用示例代码实现一个简单 usb设备驱动框架。

二. Linux下usb设备驱动实现方法

当usb设备驱动注册到内核后,内核的 USB 核心(USB Core)会负责处理底层的 USB 协议、总线枚举、设备发现等复杂工作。当有匹配的设备插入时,USB Core 会通知你的驱动,然后你的驱动再处理与该设备特定的数据交互。

1. usb设备驱动注册与注销

使用 module_initmodule_exit 进行驱动的加载和卸载,核心是注册 usb_gadget_driver结构体。分别调用usb_register_driver()函数usb_deregister()函数。

2. 描述符定义,端点配置

定义设备的各种描述符,包括设备描述符、配置描述符、接口描述符和端点描述符等,用于向上位机描述设备能力。

根据设备功能需求配置 USB 端点(Endpoint),包括控制端点、批量端点、中断端点等。

3. usb设备匹配与绑定(probe函数实现)

当 USB 设备插入并枚举完成后,内核会根据设备的 ID 信息(如厂商 ID、产品 ID)或设备树 compatible 属性,匹配对应的 usb_driver。

匹配成功后,调用驱动的 probe 函数,完成设备初始化(如申请资源、注册字符设备、初始化端点等)。

4. 数据传输

通过 Gadget API 实现与主机的数据收发,通常使用usb_request结构。

5. 设备卸载(disconnect函数实现)

当设备拔出或驱动卸载时,内核调用 disconnect 函数,释放 probe函数中申请的资源(如内存、中断、字符设备等)。

6. 提供与用户空间交互的接口函数

例如,实现一套字符设备框架代码(提供用户空间可访问设备的接口,open,read,write,ioctrl,close函数等)。

三. Linux下usb设备驱动框架示例

USB 驱动本质是内核模块,通过usb_driver 结构体定义驱动行为。并通过usb_register()注册到内
核。

1. 定义usb设备私有数据结构体

usb设备私有数据结构,存储设备相关信息:

复制代码
//定义usb私有数据结构(存储于设备相关信息)
struct usb_dev {
    struct usb_device *udev; //usb设备指针
    struct usb_interface *intf;//接口指针
    struct urb *read_urb;    //URB传输块
    unsigned char *read_buf; //读缓冲区
    size_t read_buf_size;    //缓冲区大小
    __u8 bulk_in_endpointAddr;//批量输入端点地址
    __u8 bulk_out_endpointAddr;//批量输出端点地址
};

2. 填充 struct usb_driver结构体成员

填充struct usb_driver结构体中的成员,包括设备 id 表,probe函数,disconnect函数:

复制代码
static struct usb_device_id my_id_table[] = {
    {USB_DEVICE(0x1234, 0x0a0b)}, //支持VID=0x1234,PID=0x0a0b的设备
    {}   //终止条目(必须存在)
};
static struct usb_driver my_usb_driver = {
    .name = "usb_dev",  //驱动名称,必须是唯一的
    .probe = my_usb_probe,//当设备插入且匹配时调用
    .disconnect = my_usb_disconnect,//当设备拔出时调用
    .id_table = my_id_table, //该驱动支持那些设备
};

//告诉内核这个驱动支持这些设备
//当新的USB设备插入系统时,内核可以通过该表进行驱动匹配
MODULE_DEVICE_TABLE(usb, my_id_table);

可以看出,struct usb_driver结构体中 id_table成员用于进行 usb驱动与设备进行匹配使用的。

probe函数是当驱动与设备匹配成功后,会运行的接口。

disconnect函数是当设备被拔出时会被调用到的接口。

相关推荐
就叫飞六吧20 分钟前
TOML vs YAML:为什么 Cargo 选择 TOML?
linux·运维·服务器
IMPYLH34 分钟前
Linux 的 test 命令
linux·运维·服务器·chrome·bash
xrui581 小时前
2026实战:深度解析 Gemini 3.1 镜像站函数调用在自动化运维工单中的应用
linux·服务器·网络
HackTwoHub1 小时前
Linux 内核史诗级本地提权 全网深度复现、原理完整分析( CVE-2026-31431)
linux·运维·安全·web安全·网络安全·代码审计·安全架构
她说彩礼65万2 小时前
C语言 文件
linux·服务器·c语言
txg6662 小时前
自动驾驶领域热点简报(2026-04-26 ~ 2026-05-03)
linux·人工智能·自动驾驶
二哈赛车手2 小时前
新人笔记---ES和kibana启动问题以及一些常用的linux的错误排查方法,以及ES,数据库泄密解决方案[超详细]
java·linux·数据库·spring boot·笔记·elasticsearch
嵌入式×边缘AI:打怪升级日志2 小时前
嵌入式Linux开发核心自测题(全系列精华浓缩)
java·linux·运维
嵌入式×边缘AI:打怪升级日志2 小时前
TinaSDK Linux Kernel 基本使用(全志T113开发板)
linux·运维·服务器
嵌入式×边缘AI:打怪升级日志3 小时前
Linux内核基础完全入门指南(理论篇)
linux·运维·服务器