usb hid驱动 - usb鼠标

news/2024/11/7 8:36:39/

usb鼠标符合usb hid协议,

一般是单一功能(即一个usb 接口)

该接口下有一个默认的双向控制端点, 以及1个中断 in端点

 

bulk in端点读取数据定义: (具体定义需参考hid report描述符, https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/)

通常大部分usb鼠标数据描述如下:

BYTE1 --

       |--bit7:   1   表示 Y 坐标的变化量超出-256~255的范围,0表示没有溢出

       |--bit6:   1   表示 X 坐标的变化量超出-256~255的范围,0表示没有溢出 

       |--bit5:   Y   坐标变化的符号位,1表示负数,即鼠标向下移动 
       |--bit4:   X   坐标变化的符号位,1表示负数,即鼠标向左移动 
       |--bit3:   恒为1 
       |--bit2:   1表示中键按下 
       |--bit1:   1表示右键按下 

       |--bit0:   1表示左键按下 

BYTE2 -- X坐标变化量,与byte的bit4组成9位符号数,负数表示向左移,正数表右移。用补码表示变化量 
BYTE3 -- Y坐标变化量,与byte的bit5组成9位符号数,负数表示向下移,正数表上移。用补码表示变化量
BYTE4 -- 滚轮变化。


 

usb mouse驱动实现如下:

#include <linux/module.h>
#include <linux/printk.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/input.h>MODULE_LICENSE("GPL");
MODULE_AUTHOR("River");struct usbmouse_dev {struct input_dev *input;struct usb_device *usbdev;struct urb* urb;unsigned char *data;
};static struct usbmouse_dev *usbmouse = NULL;const struct usb_device_id usbmouse_ids[] = {{USB_DEVICE(0x0C45, 0x7c25)},    /* my usbmouse */{},
};static int usbmouse_info_open(struct input_dev *dev) {int status;struct usbmouse_dev *usbmouse = input_get_drvdata(dev);printk(KERN_INFO "usbmouse info open\n");status = usb_submit_urb(usbmouse->urb, GFP_KERNEL);if (status < 0) {printk(KERN_ERR "usb_submit_urb failed\n");goto submit_fail;}return 0;submit_fail:return status;
}static void usbmouse_info_close(struct input_dev *dev) {struct usbmouse_dev *usbmouse = input_get_drvdata(dev);printk(KERN_INFO "usbmouse info close\n");usb_kill_urb(usbmouse->urb);return;
}static void usbmouse_info_irq(struct urb *urb) {struct usbmouse_dev *usbmouse = urb->context;unsigned char *data = usbmouse->data;struct input_dev *dev = usbmouse->input;int status = 0;switch (urb->status) {case 0:			/* success */break;case -ECONNRESET:	/* unlink */case -ENOENT:case -ESHUTDOWN:return;/* -EPIPE:  should clear the halt */default:		/* error */goto resubmit;}/** byte 0, bits[0...2] (btn_left, btn_right, btn_middle)* byte 0, bits[4...7] (Device Specific)* byte 1, bits[0...7] (X dispalcement)* byte 2, bits[0...7] (Y dispalcement)* byte 3...n (Device Specific)*/input_report_key(dev, BTN_LEFT, data[0] & 0x1);input_report_key(dev, BTN_RIGHT, data[0] & 0x2);input_report_key(dev, BTN_MIDDLE, data[0] & 0x4);input_report_rel(dev, REL_X, data[1]);input_report_rel(dev, REL_Y, data[2]);/* report sync event */input_sync(dev);resubmit:status = usb_submit_urb(urb, GFP_KERNEL);if (status < 0) {printk(KERN_ERR "usb_submit_urb failed...\n");}
}static int usbmouse_info_probe(struct usb_interface *intf,const struct usb_device_id *id) {int ret = 0;struct usb_interface_descriptor *cur_desc;struct usb_endpoint_descriptor *ep0_desc;struct input_dev *input;struct urb *urb;struct usb_device *usbdev = interface_to_usbdev(intf);int pipe0, maxp;dev_info(&intf->dev, "usb mouse plug in!\n");printk(KERN_INFO "usb mouse detect! vid(0x%x), pid(0x%x)\n",id->idVendor, id->idProduct);cur_desc = &intf->cur_altsetting->desc;ep0_desc = &intf->cur_altsetting->endpoint->desc;if (!ep0_desc || !cur_desc) {printk(KERN_ERR "descriptor error...\n");ret = -EFAULT;goto desc_err;}#if 0printk(KERN_INFO "intf_desc: length(%d), desc_type(%d)\n""           intf_num(%d), alt_setting(%d)\n""           ep_num(%d), intf_class(%d)\n""           intf_subclass(%d), intf_protocol(%d)\n""           i_intf(%d)\n",cur_desc->bLength, cur_desc->bDescriptorType,cur_desc->bInterfaceNumber, cur_desc->bAlternateSetting,cur_desc->bNumEndpoints, cur_desc->bInterfaceClass,cur_desc->bInterfaceSubClass, cur_desc->bInterfaceProtocol,cur_desc->iInterface);
#endifusbmouse = kzalloc(sizeof(struct usbmouse_dev), GFP_KERNEL);if (!usbmouse) {printk(KERN_ERR "usbmouse_dev malloc failed\n");ret = -ENOMEM;goto malloc_fail1;}/* prepare urb */urb = usb_alloc_urb(0, GFP_KERNEL);if (!urb) {printk(KERN_ERR "usb allocate urb failed\n");ret = -EFAULT;goto urb_fail;}usbmouse->urb = urb;usbmouse->data = kzalloc(8, GFP_KERNEL);if (!usbmouse->data) {printk(KERN_ERR "alloc usb mouse data failed...\n");ret = -ENOMEM;goto malloc_fail2;}pipe0 = usb_rcvintpipe(usbdev, ep0_desc->bEndpointAddress);maxp = usb_maxpacket(usbdev, pipe0, 0);/* fill interrupt urb */usb_fill_int_urb(urb, usbdev, pipe0,usbmouse->data, maxp>8?8:maxp,usbmouse_info_irq, usbmouse, ep0_desc->bInterval);/* allocate an input dev */input = input_allocate_device();/* set bit mask *//* support EV_KEY & EV_REL event */input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);/* the usbmouse has left, right & middle button */input->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);/* relative x & y */input->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);/* the usbmouse has other key? */
#if 0input->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |BIT_MASK(BTN_EXTRA);
#endifif (!input) {printk(KERN_ERR "input dev malloc failed\n");ret = -ENOMEM;goto malloc_fail3;}usbmouse->input = input;input_set_drvdata(input, usbmouse);input->open = usbmouse_info_open;input->close = usbmouse_info_close;/* register in input device subsystem */ret = input_register_device(input);if (ret < 0) {printk(KERN_ERR "input_register_device failed\n");goto reg_input_fail;}return 0;reg_input_fail:input_unregister_device(input);usbmouse->input = NULL;malloc_fail3:
malloc_fail2:kfree(usbmouse->data);urb_fail:kfree(usbmouse);malloc_fail1:
desc_err:return ret;
}static void usbmouse_info_remove(struct usb_interface *intf) {dev_info(&intf->dev, "usb mouse plug out!\n");if (usbmouse && usbmouse->input) {input_unregister_device(usbmouse->input);usbmouse->input = NULL;kfree(usbmouse);usbmouse = NULL;}return;
}static struct usb_driver usbmouse_info_driver = {.name = "usbmouse_info",.probe = usbmouse_info_probe,.disconnect = usbmouse_info_remove,.id_table = usbmouse_ids,
};static int __init usbmouse_info_init(void) {int ret = 0;ret = usb_register(&usbmouse_info_driver);if (ret < 0) {printk(KERN_ERR "usb_register failed\n");return ret;}printk(KERN_INFO "usbmouse_info_init succeed\n");return 0;
}static void __exit usbmouse_info_exit(void) {usb_deregister(&usbmouse_info_driver);printk(KERN_INFO "usbmouse_info_exit succeed\n");return;
}module_init(usbmouse_info_init);
module_exit(usbmouse_info_exit);

 


http://www.ppmy.cn/news/211216.html

相关文章

USB-HID鼠标键盘驱动

先说结果: 本章驱动,实现了一个USB slave接口模拟出鼠标、键盘设备。在windows10上验证通过。 可以通过本章配套的测试程序,可以完成任意位置的鼠标移动,左击、右击等操作。 键盘的测试程序没有写完,只写了部分案件。就没有贴上来。 下面的代码是在tiny4412开发板上面验…

雷柏MT750S鼠标使用总结(驱动|连接|模式|续航)

【什么值得买 摘要频道】下列精选内容摘自于《无线办公好帮手 雷柏MT750S无线蓝牙鼠标体验》的片段&#xff1a; 驱动 雷柏MT750S的驱动软件界面比较简单&#xff0c;因为没有灯光的原因&#xff0c;软件主要是鼠标按键功能的设置&#xff0c;在左侧显示了各种功能&#xff0c…

USB总线驱动及鼠标驱动实例

转自&#xff1a;https://blog.csdn.net/liangzc1124/article/details/119333357、https://www.cnblogs.com/lifexy/p/7631900.html 1、Windows USB设备驱动 为什么一插上就会有提示信息&#xff1f; 以windows为例&#xff0c;插上一个没有USB驱动的USB设备&#xff0c;会提示…

虚拟鼠标驱动的实现

虚拟鼠标驱动的实现 好久以前的东西了&#xff0c;发出来给感兴趣的朋友参考一下。 虚拟鼠标驱动就是通过驱动虚拟一个mouse&#xff0c;然后通过上层应用程序控制其发码&#xff0c;可以模拟硬件级的发码。 下面来看一下代码&#xff0c;主要的函数如下&#xff1a; NTSTATUS …

USB设备驱动之鼠标

USB设备驱动之鼠标 1. 概述 USB鼠标驱动程序大致分为两大部分&#xff1a;USB设备驱动部分和输入设备驱动部分&#xff0c;USB设备驱动只起了挂接总线和传输数据的作用&#xff0c;而具体的设备类型的驱动仍然是工作的主体。 USB设备驱动部分&#xff1a;负责注册USB设备驱动…

usb键鼠驱动分析

一、鼠标 linux下的usb鼠标驱动在/drivers/hid/usbhid/usbmouse.c中实现 1.加载初始化过程 1.1模块入口 module_init(usb_mouse_init); 1.2初始化函数 static int __init usb_mouse_init(void) //初始化{int retval usb_register(&usb_mouse_driver); //注册usb鼠标…

USB鼠标设备驱动程序简单实现(一)

一、Linux下的USB驱动程序 分离和分层是Linux下驱动程序开发采用的最基本的形式&#xff0c;USB驱动开发在主机端主要涉及两个部分&#xff1a;主机控制器驱动和设备驱动。 主机控制器驱动主要是和具体的Soc相关的&#xff0c;它来识别USB设备&#xff0c;安装对应的设备驱动…

USB鼠标驱动

仿照drivers/hid/usbhid/usbmouse.c系统自带的USB鼠标驱动实现的USB鼠标驱动。 一、usb/usbmouse_as_key.c #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <linux/usb/input.h…