Linux驱动学习(2) 从usb驱动到input子系统2

USB驱动的学习

参考博客:https://blog.csdn.net/qq_21792169/article/details/48790745
参考书籍:《Linux设备驱动程序》

(一)USB驱动概述
1.要写鼠标驱动,首先必须理解USB设备层次,《Linux设备驱动程序》中给出的层次图如下。USB层次主要有三层架构,USB主控制器驱动(USB Host Controllers)直接和USB硬件设备进行通信,USB核心子系统(USB Core)为USB驱动程序提供访问和控制硬件的接口,USB驱动用于向应用程序传递通信消息。
在这里插入图片描述
2.USB设备的构成
(1)直接参考书上的结构图:
在这里插入图片描述

USB设备包括配置、接口和端点。一个USB设备可能包含多个配置,一个配置可能包含多个接口,一个接口可能包含多个端点。所以必须理解它们的具体含义:
① 配置:这里的配置在内核里面被定义为结构体struct usb_host_config,通常把接口和配置结合一起使用,例如接口2-1,表示配置号为2,接口号为1。我们在驱动代码里面如果要获取设备信息并不使用这个结构体,而是使用struct usb_device。
② 接口:通常一个接口表示一个功能,例如一个USB音响有两个接口,一个USB键盘接口一个USB音频流接口。在驱动代码里面我们接收到这个参数,并从中获取端口信息。驱动中用struct usb_interface结构体表示USB接口。
③ 端点:USB 端点在内核中使用结构 struct usb_host_endpoint 来描述,通常可以把端点看做单向的数据通道,我们可以从USB接口结构体中获取通信管道pipe,然后利用管道进行通信。端点类型有以下几种,我们使用不同的通信方式来适配不同类型的端点。
1)中断端点:这是我们获取鼠标键盘等事件使用的端点类型,通常用来传送小量数据。
2)控制端点:通常用于配置设备,例如每个USB设备都有默认的控制端口“端口0”
3)块端点(批量端口):传输大量信息,例如打印机或者存储器。
4)同步端点:通常用于实时数据收集,例如音频流或者视频流。

3.USB设备在sysfs文件系统中的表示
(1)书中已经做了最简单的解释:
root_hub-hub_port:config.interface
即根集线器号-根集线器端口号:配置号.接口号。然后就可以查看设备信息和接口信息,sysfs并不显示端口信息。
用虚拟机举个例子:
先从input系统中获取USB设备信息
(注意,虚拟机要获取usb信息需要点击设备-USB-对应设备进行设备切换,例如我的virtualbox:
在这里插入图片描述

cat /proc/bus/input/device
在这里插入图片描述
可以看到具体设备的sysfs地址,然后可以到sysfs查看设备信息和接口信息
cat /sys/devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/bInterfaceClass
在这里插入图片描述
(可以看到对于特殊字符shell进行了转义)
其中“usb1”表示此usb设备所在usb集线器(也是主控制器)序号为1;”1-2”表示集线器序号1,usb设备在集线器上的端口号为2;“1-2:1.0”的前两位和前面相同含义,冒号后两位表示usb设备配置号为1,接口号为0;前面的“pci0000:00/0000:00:06.0”表示此usb集线器和pci总线向连,所以usb集线器又叫做usb总线和pci总线相连的桥。
这里知道usb集线器可以包含多个usb设备,而usb驱动想要和usb设备通信必须经过usb控制器驱动,所以采用树形结构将usb设备进行分类。。

4.端点传输信息载体URB
我们在驱动中用的比较多的数据结构就是URB,因为我们所做的驱动仅仅是一层中间层,上有输入子系统,下有控制器驱动,USB驱动主要作用常常是利用URB告诉主控制器你想传递或者接收的信息,然后利用input系统发出相关事件。(当然某些特殊的USB驱动可以直接和应用软件沟通而不经过input系统)
书上对URB创建到结束的生命周期描述得非常到位:
• 被一个 USB 设备驱动创建.
• 安排给一个特定 USB 设备的特定端点.
• 提交给 USB 核心, 被 USB 设备驱动.
• 提交给特定设备的被 USB 核心指定的 USB 主机控制器驱动, .
• 被 USB 主机控制器处理, 它做一个 USB 传送到设备.
• 当 urb 完成, USB 主机控制器驱动通知 USB 设备驱动.
理解了这一层后就明白,URB是有消亡时间的,所以如果我们通过URB注册了中断,在收到中断消息后URB就已经完成了流程,如果需要多次接收中断需要再次注册URB。
驱动使用struct urb表示URB,这个URB有几个重要的成员。
struct usb_device *dev
指向这个 urb 要发送到的 struct usb_device 的指针.。
unsigned int pipe
发送给指定设备的管道.。
void *transfer_buffer
缓存地址,对用发送或者接收的数据就放在这块缓存上。
int transfer_buffer_length
缓冲的长度。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值