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函数是当设备被拔出时会被调用到的接口。

相关推荐
币圈小菜鸟5 小时前
Selenium 自动化测试实战:绕过登录直接获取 Cookie
linux·python·selenium·测试工具·ubuntu·自动化
半梦半醒*6 小时前
ansible的playbook练习题
linux·运维·服务器·ssh·ansible·运维开发
学c语言的枫子6 小时前
Ubuntu22.04网络图标消失问题
linux·学习·ubuntu
丁满与彭彭6 小时前
嵌入式学习笔记--LINUX系统编程--DAY03进程控制
linux·笔记·学习
chenfengxiu7 小时前
Centos7安装gitlab
linux·运维·gitlab
羑悻的小杀马特8 小时前
【Linux篇章】再续传输层协议UDP :从低可靠到极速传输的协议重生之路,揭秘无连接通信的二次进化密码!
linux·运维·服务器·后端·网络协议·udp
Linux运维技术栈9 小时前
Linux系统部署:Certbot 实现 Nginx 自动续期&部署 Let‘s Encrypt 免费 SSL 证书
linux·运维·nginx·ssl·certbot
阿雄不会写代码9 小时前
wecross 报错这个文件找不到 tassl-1.1.1b-linux-x86_64.tar.gz
linux·运维·服务器
007php00715 小时前
Go 错误处理:用 panic 取代 err != nil 的模式
java·linux·服务器·后端·ios·golang·xcode