本文将对Linux鼠标驱动源码进行深入解析,带你了解从设备检测到数据传输的整个过程
一、Linux USB鼠标驱动概述 Linux USB鼠标驱动主要位于内核源代码树的`drivers/hid/usbhid/`目录下,其核心文件为`usbmouse.c`
USB鼠标属于HID(Human Interface Devices,人机接口设备)设备,这类设备包括鼠标、键盘等,主要用于人与计算机进行交互
HID设备要求用户输入能得到及时响应,因此其传输方式通常采用中断方式
二、USB鼠标驱动的模块加载与注册 在`usbmouse.c`文件中,首先定义了一个`usb_device_id`结构体数组`usb_mouse_id_table`,用于描述支持的USB设备
这个数组包含了USB接口类、子类和协议三个匹配项,确保只有符合这些条件的设备才会被该驱动管理
static const struct usb_device_idusb_mouse_id_table【】= { {USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE)}, {} / Terminating entry / }; 接着,定义了一个`usb_driver`结构体`usb_mouse_driver`,并通过`module_usb_driver`宏进行注册
这个结构体包含了驱动的名称、probe函数、disconnect函数以及设备ID表等关键信息
static structusb_driver usb_mouse_driver= { .name = usbmouse, .probe =usb_mouse_probe, .disconnect =usb_mouse_disconnect, .id_table =usb_mouse_id_table, }; module_usb_driver(usb_mouse_driver); 三、USB设备检测与驱动匹配 当一个USB鼠标设备插入后,主机USB控制器会检测到这一事件,并触发USB设备集线器中的“中断”处理函数`hub_irq`
在这个函数中,会获取USB鼠标设备的设备描述符,并根据设备描述符创建USB接口设备
然后,将这个USB接口设备与开发的USB接口驱动进行匹配
匹配过程主要是将获取到的USB设备描述符信息保存在驱动的`id_table`中,并与期望该驱动适用的USB设备进行比较
如果匹配成功,就会调用该驱动的`probe`函数,通过USB总线驱动程序(USB Core和USB HCD)和USB鼠标设备建立联系,进而操作(读写控制)该设备
四、USB鼠标驱动的probe函数 `usb_mouse_probe`函数是USB鼠标驱动的核心函数之一,它负责初始化USB鼠标设备并为其分配必要的资源
这个函数首先通过接口获取USB设备,并获取当前接口的设置和端点描述符
然后,检查该端点是否是中断输入端点,并建立中断输入端点
static intusb_mouse_probe(struct usb_interfaceintf, const struct usb_device_idid) { structusb_device dev = interface_to_usbdev(intf); structusb_host_interface interface; structusb_endpoint_descriptor endpoint; structusb_mouse mouse; structinput_dev input_dev; int pipe, maxp; int error = -ENOMEM; interface = intf->cur_altsetting; if(interface->desc.bNumEndpoints!= return -ENODEV; endpoint = &interface->endpoint【0】.desc; if(!usb_endpoint_is_int_in(endpoint)) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp =usb_maxpacket(dev, pipe, usb_pipeout(pipe)); mouse = kzalloc(sizeof(structusb_mouse),GFP_KERNEL); input_dev = input_allocate_device(); if(!mouse|| !input_dev) goto fail1; // 后续初始化代码... } 在成功获取端点并分配必要的结构体后,`usb_mouse_probe`函数会继续为鼠标设备分配输入设备空间,并设置输入设备的参数
然后,注册这个输入设备,并将其与USB鼠标设备绑定
最后,分配USB请求块(URB)和数据缓冲区,并初始化USB请求块,提交给USB核心进行数据处理
五、USB鼠标的中断处理 USB鼠标的数据传输采用中断UR