发布: 09_编写USB鼠标驱动程序

This commit is contained in:
weidongshan
2022-10-11 16:44:29 +08:00
parent ef9e6a14ab
commit b76cd138f4
12 changed files with 335 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
# 编写USB鼠标驱动程序 #
参考资料:
* Linux内核源码`include\linux\usb.h`
* Linux内核源码`drivers\hid\usbhid\usbmouse.c`
* 本视频源码在GIT仓库如下位置
```c
doc_and_source_for_drivers\IMX6ULL\source\12_USB\04_usbmouse_as_key
```
## 1. 目标
使用鼠标模拟按键:左键相当于"L"、右键相当于"S"、"中键"相当于 "回车"。
## 2. 编程
### 2.1 驱动框架
![image-20221011095909341](pic/66_usb_input_frame.png)
对于GPIO按键是直接构造、注册一个input_dev结构体在GPIO中断函数里获得数据。
现在数据来源发生了变化数据来自USB设备需要做的事情是
* 构造、注意usb_driver
* usb_driver发现能支持是设备后它的probe函数被调用
* 构造、注册input_dev结构体
* 获得数据:
* 构造、提交URB
* 在URB的回调函数里向Input系统上报数据
### 2.2 实现usb_driver
仿照usbmouse.c如下代码构造一个usb_driver结构体
![image-20221011091940453](pic/64_usb_driver_example.png)
核心是:
* id_table这个驱动能支持哪些设备
* probe函数发现能支持的设备后probe函数记录设备信息、注册输入设备等等
#### 2.2.1 id_table
id_table是一个usb_device_id数组示例如下
![image-20221011092207138](pic/65_usb_id_table.png)
usb_device_id结构体定义如下
* match_flags表示要比较哪些信息可以比较设备ID、DeviceClass、InterfaceClass等等
* 根据match_flags提供其他信息比如设备ID、DeviceClass、InterfaceClass等等
* driver_info驱动程序可能用到的一些信息
```c
struct usb_device_id {
/* which fields to match against? */
__u16 match_flags;
/* Used for product specific matches; range is inclusive */
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice_lo;
__u16 bcdDevice_hi;
/* Used for device class matches */
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
/* Used for interface class matches */
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
/* Used for vendor-specific interface matches */
__u8 bInterfaceNumber;
/* not matched against */
kernel_ulong_t driver_info
__attribute__((aligned(sizeof(kernel_ulong_t))));
};
```
#### 2.2.2 probe函数
probe函数原型如下
```c
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id);
```
第1个参数是"struct usb_interface *"类型,表示匹配到的"USB逻辑设备"。
第2个参数是"struct usb_device_id *"类型它是usb_driver的id_table中的某项表示第1个参数就是跟这个usb_device_id匹配的。有必要的话probe函数里可以从id->driver_info得到驱动相关的一些信息。
在probe函数一般要记录intf信息以后发起USB传输时会用到intf信息。
### 2.3 实现输入设备
核心是分配、设置、注册一个input_device结构体。
### 2.4 实现数据传输
分配、填充、提交URB在URB的回调函数里上报"input_event"。
## 3. 上机实验

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB