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

编写Linux下usb设备驱动方法:probe函数中要进行的工作

一. 简介

前一篇文章简单学习了 Linux下usb设备驱动实现流程,文章如下:

编写Linux下usb设备驱动方法:usb设备驱动实现流程-CSDN博客

本文来学习一下 usb设备驱动的 probe函数要完成的任务。

当usb主控制器检测到设备与 驱动相匹配时,就会执行usb的 probe函数。

二. 编写Linux下usb设备驱动的方法:probe函数中要进行的工作

当 USB主控制器驱动发现一个设备与你的 id_table 匹配时,probe函数就会执行。probe函数的主要任务:

(1) 验证设备基本信息(合法性检查)

在进行资源分配前,需先确认设备的硬件特性是否符合驱动预期,避免对不兼容设备进行错误初始化:

  • 检查设备描述符:验证设备的接口数量、端点类型、传输能力等是否与驱动支持的范围匹配(例如驱动只支持中断端点,需检查设备是否存在中断端点)。
  • 确认端点参数:通过 usb_interface 的 cur_altsetting 成员获取当前接口的端点描述符,检查端点地址、最大包长(wMaxPacketSize)、中断间隔(bInterval)等是否符合驱动设计(例如确保缓冲区大小不超过端点最大包长)。
  • 检查设备版本 / 功能:对于复杂设备(如带多个配置的 USB 设备),可能需要验证设备固件版本、支持的功能集等。

(2) 分配与初始化驱动私有数据结构: 使用 kzalloc 或 devm_kzalloc
  • 分配私有数据内存:使用 kzalloc分配内存(确保初始化为 0,避免野指针)。
  • 关联核心对象:将 usb_deviceusb_interface等核心结构体指针存入私有数据(需通过    usb_get_dev 增加设备引用计数,确保设备不被意外释放)。
  • 初始化关键成员:如数据传输缓冲区大小、URB 指针初始化为 NULL 等。

(3) 初始化数据传输机制(URB 准备)

USB 设备的核心功能是数据传输,probe函数需为传输准备好 URB(USB Request Block,USB 请求块)—— 内核中 USB 传输的 “载体”:

  • 分配 URB:通过 usb_alloc_urb 分配与端点类型匹配的 URB(如中断端点用 usb_alloc_urb(0, ...),等时端点需指定 iso 包数量)。
  • 填充 URB:根据端点类型调用对应的填充函数(如中断端点用 usb_fill_int_urb,批量端点用 usb_fill_bulk_urb ),设置传输方向、缓冲区、完成回调函数等。
  • 关联 URB 与私有数据:将私有数据设为 URB 的 context,便于回调函数中访问设备资源。

usb四种传输类型中,控制传输和批量传输,可以不用进行URB传输块的分配,填充,关联等刚工作。可以使用 usb内核提供的函数接口进行传输:

控制传输可以使用 usb_control_msg()函数进行传输,批量传输可以使用 usb_bulk_msg() 函数进行传输(在使用 usb_control_msg()函数或 usb_bulk_msg()函数进行 USB 控制传输时,USB 内核已经封装了 URB(USB Request Block)的分配、填充、提交和释放等底层工作,开发者无需手动操作 URB 结构)。

(4) 注册用户空间接口(可选)

若驱动需要与用户空间程序交互(如通过 ioctl 发送命令、读写数据),probe 函数需注册字符设备、sysfs 节点或其他接口:

字符设备注册:通过 cdev_init、cdev_add 注册字符设备,关联文件操作结构体(file_operations),让用户空间可通过 /dev/xxx 访问。

sysfs 节点创建:通过 sysfs_create_group 等函数创建属性文件,暴露设备状态或配置参数(如 echo 1 > /sys/class/myusb/enable 开启设备)。

(5) 启动数据传输(可选)

对于需要 “设备插入后立即开始工作” 的场景(如传感器设备周期性上报数据),probe函数可在初始化完成后直接提交 URB,启动首次数据传输:

http://www.xdnf.cn/news/18721.html

相关文章:

  • HTML+CSS+JavaScript实现的AES加密工具网页应用,包含完整的UI界面和加密/解密功能
  • 集成电路学习:什么是ONNX开放神经网络交换
  • 网络编程——TCP、UDP
  • ADC-工业信号采集卡-K004规格书
  • JWT用户认证后微服务间如何认证?(双向TLS(mTLS)、API网关、Refresh Token刷新Token)微服务间不传递用户认证Token
  • zookeeper基础概念及部署
  • Redis缓存雪崩缓存击穿缓存穿透的处理方式
  • java18学习笔记
  • Nuxt.js@4 中管理 HTML <head> 标签
  • AI 伦理的 “灰色地带”:数据隐私与技术创新如何平衡?
  • 零知开源——基于STM32F103RBT6和ADXL335实现SG90舵机姿态控制系统
  • Coze用户账号设置修改用户头像-前端源码
  • 深度学习之第三课PyTorch( MNIST 手写数字识别神经网络模型)
  • AI创业公司:Freya 金融语音AI Agent
  • 电池分选机:破解电池性能一致性难题的自动化方案|深圳比斯特
  • 【VS2022】背景设置详细教程(背景透明)
  • 智数园区-前台
  • Linux的奇妙冒险———进程信号
  • 算法每日一题 | 入门-分支结构-肥胖问题
  • java 并发编程八股-多线程篇
  • 【iOS】内存管理及部分Runtime复习
  • Kubernetes高可用架构设计:多Master节点部署与etcd集群运维深度指南
  • centos7 安装coze
  • ZYNQ [Petalinux的运行]
  • Pytorch框架的训练测试以及优化
  • 数据结构青铜到王者第三话---ArrayList与顺序表(2)
  • 区块链技术原理(18)-以太坊共识机制
  • 哈夫曼树详解
  • 神经网络|(十五)概率论基础知识-协方差标准化和皮尔逊相关系数
  • 人机协作,温暖升级:有鹿机器人与保洁张阿姨的故事