USB鼠标驱动

news/2024/11/6 11:37:46/

仿照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>
#include <linux/hid.h>static int len;
static char *usb_buf;
static dma_addr_t usb_buf_phys;
struct urb *uk_urb;
struct input_dev *uk_dev;static void usbmouse_as_key_irq(struct urb *urb)
{
#if 0int i;static int cnt = 0;printk("date cnt %d: ", ++cnt);for(i = 0; i < len; i++){printk("%02x ", usb_buf[i]);}printk("\n");//加载驱动之后可通过 hexdump dev/input/event0 查看鼠标数据
#endifstatic char per_val;/*鼠标数据格式:data[0]:    bit0 - 左键,1 - 按下,0 - 松开bit1 - 右键,1 - 按下,0 - 松开bit2 = 中键,1 - 按下,0 - 松开data[6]:    = 0x01 滚轮前进= 0xff 滚轮后进*/if((per_val & (1 << 0) ) != (usb_buf[0] & (1 << 0)) ){//左键处理input_event(uk_dev, EV_KEY, KEY_L, (usb_buf[0] & (1 << 0)) ? 1 : 0);input_sync(uk_dev);}if((per_val & (1 << 1) ) != (usb_buf[0] & (1 << 1)) ){//右键处理input_event(uk_dev, EV_KEY, KEY_S, (usb_buf[0] & (1 << 1)) ? 1 : 0);input_sync(uk_dev);}if((per_val & (1 << 2) ) != (usb_buf[0] & (1 << 2)) ){//中键处理input_event(uk_dev, EV_KEY, KEY_ENTER, (usb_buf[0] & (1 << 2)) ? 1 : 0);input_sync(uk_dev);}per_val = usb_buf[0];/* 重新提交urb */usb_submit_urb(uk_urb, GFP_KERNEL);
}static int usbmouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
{struct usb_device *dev = interface_to_usbdev(intf);struct usb_endpoint_descriptor *endpoint;struct usb_host_interface *interface;int pipe;printk("bcdUSB = %x\nVID = 0x%x\nPID = 0x%x\n", dev->descriptor.bcdUSB, dev->descriptor.idVendor, dev->descriptor.idProduct);printk("run %s, %d\n", __FUNCTION__, __LINE__);interface = intf->cur_altsetting;endpoint = &interface->endpoint[0].desc;/* a. 分配一个input_dev */uk_dev = input_allocate_device();uk_dev->name = "usbmouse";/* b. 设置 *//* b.1 能产生哪类事件 */set_bit(EV_KEY, uk_dev->evbit);set_bit(EV_REP, uk_dev->evbit);  /* b.2 能产生哪些事件 */set_bit(KEY_L, uk_dev->keybit);set_bit(KEY_S, uk_dev->keybit);set_bit(KEY_ENTER, uk_dev->keybit);/* c. 注册 */input_register_device(uk_dev);/* d. 硬件相关操作 *//* 数据传输3要素: 源,目的,长度 *//* 源: USB设备的某个端点 */pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);    /* 长度: */len = endpoint->wMaxPacketSize;/* 目的: */usb_buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);/* 使用"3要素" *//* 分配usb request block */uk_urb = usb_alloc_urb(0, GFP_KERNEL);/* 使用"3要素设置urb" */usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval);uk_urb->transfer_dma = usb_buf_phys;uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;/* 使用URB */usb_submit_urb(uk_urb, GFP_KERNEL);return 0;
}static void usbmouse_as_key_disconnect(struct usb_interface *intf)
{struct usb_device *dev = interface_to_usbdev(intf);printk("run %s, %d\n", __FUNCTION__, __LINE__);  usb_kill_urb(uk_urb);usb_free_urb(uk_urb);usb_free_coherent(dev, len, usb_buf, usb_buf_phys);input_unregister_device(uk_dev);input_free_device(uk_dev);
}static struct usb_device_id usbmouse_as_key_id_table [] = {{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },{ }	/* Terminating entry */
};static struct usb_driver usbmouse_as_key_driver = {.name		= "usbmouse",.probe		= usbmouse_as_key_probe,.disconnect	= usbmouse_as_key_disconnect,.id_table	= usbmouse_as_key_id_table,
};static int usbmouse_as_key_init(void)
{usb_register(&usbmouse_as_key_driver);return 0;
}static void usbmouse_as_key_exit(void)
{usb_deregister(&usbmouse_as_key_driver);
}module_init(usbmouse_as_key_init);
module_exit(usbmouse_as_key_exit);
MODULE_LICENSE("GPL");

二、测试

1、说明

KEY_L = 38 = 0x0026
KEY_S = 31 = 0x001f
KEY_ENTER = 28 = 0x001c
因为鼠标中间坏了,就不验证了。

2、内核处理

内核需要把系统自带的USB鼠标驱动移除
在这里插入图片描述

insmod usbmouse_as_key.ko
bcdUSB = 200
VID = 0x46d
PID = 0xc52f
run usbmouse_as_key_probe, 71
input: usbmouse as /devices/virtual/input/input4
usbcore: registered new interface driver usbmouse
/ #
/ # hexdump dev/input/event0
0000000 0878 0000 c7fa 000b 0001 0026 0001 0000
0000010 0878 0000 c7fa 000b 0000 0000 0000 0000
0000020 0878 0000 8d09 000d 0001 0026 0000 0000
0000030 0878 0000 8d09 000d 0000 0000 0000 0000
0000040 0879 0000 3d1c 000c 0001 001f 0001 0000
0000050 0879 0000 3d1c 000c 0000 0000 0000 0000

三、问题排查

1、接上鼠标打印device descriptor read/64, error -62

经分析是USB D+、D-接反导致。

/ # usb 4-1: new full-speed USB device number 2 using ohci-platform
usb 4-1: device descriptor read/64, error -62
usb 4-1: device descriptor read/64, error -62
usb 4-1: new full-speed USB device number 3 using ohci-platform
usb 4-1: device descriptor read/64, error -62
usb 4-1: device descriptor read/64, error -62
usb 4-1: new full-speed USB device number 4 using ohci-platform
usb 4-1: device not accepting address 4, error -62
usb 4-1: new full-speed USB device number 5 using ohci-platform
usb 4-1: device not accepting address 5, error -62
usb usb4-port1: unable to enumerate USB device

2、打印USB disconnect, device number 2

采用有线鼠标测试的时候,出现过加载驱动后打印显示成功加载,但过了一会儿就显示断开了 USB disconnect,采用无线鼠标则没有此类情况。可能是单板USB口采用飞线引出,信号有影响导致。

/ # insmod usbmouse_as_key.ko
bcdUSB = 200
VID = 0x17ef
PID = 0x608d
run usbmouse_as_key_probe, 40
input: usbmouse as /devices/virtual/input/input0
usbcore: registered new interface driver usbmouse
/ # usb 4-1: USB disconnect, device number 2
run usbmouse_as_key_disconnect, 83
usb 4-1: new low-speed USB device number 3 using ohci-platform
bcdUSB = 200
VID = 0x17ef
PID = 0x608d
run usbmouse_as_key_probe, 40
input: usbmouse as /devices/virtual/input/input1

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

相关文章

编写USB鼠标驱动程序,并测试

转载自&#xff1a;https://www.cnblogs.com/lxl-lennie/p/10189188.html 8.1 编写USB鼠标驱动程序&#xff0c;并测试 学习目标&#xff1a;编写USB鼠标驱动程序&#xff0c;并测试&#xff08;将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键&#x…

USB鼠标驱动开发流程

USB驱动开发&#xff0c;针对某一个USB设备的某个功能&#xff08;接口&#xff09;构建的驱动程序。USB驱动并不直接和USB设备进行数据交互&#xff0c;而是通过USB总线驱动程序&#xff08;USB Core和USB HCD&#xff09;来操作USB设备的。一般构建USB设备驱动的流程为&#…

USB驱动之Android usb鼠标驱动

1. 前言 HID是Human Interface Devices的缩写&#xff0c;翻译成中文即为人机交互设备。这里的人机交互设备是一个宏观上面的概念&#xff0c;任何设备只要符合HID spec都可以称之为HID设备&#xff0c;常见的HID设备有鼠标键盘&#xff0c;游戏操纵杆等等。 usb鼠标在android代…

编写USB鼠标驱动程序

编写USB鼠标驱动程序 文章目录 编写USB鼠标驱动程序参考资料&#xff1a;1. 目标2. 编程2.1 驱动框架2.2 实现usb_driver2.2.1 id_table2.2.2 probe函数 2.3 实现输入设备2.4 实现数据传输 3. 上机实验 致谢 参考资料&#xff1a; Linux内核源码&#xff1a;include\linux\usb.…

usb鼠标驱动(一)

Linux USB 鼠标驱动程序详解 注册一个usb driver&#xff0c;这个drvier不是usb设备driver&#xff0c;而是接口driver。 /* use a define to avoid include chaining to get THIS_MODULE & friends */ #define usb_register(driver) \usb_register_driver(driver, THIS_M…

设计模式入门:策略模式

现有一套模拟鸭子游戏&#xff0c;可以一边游泳&#xff0c;一边呱呱叫。 每种鸭子都会呱呱叫和游泳&#xff0c;只是外观不同。因此&#xff0c;quack和swim放在父类中&#xff0c;display放在子类中实现。 增加新的功能&#xff1a;鸭子飞翔。 1 我们可能想到直接在父类中增…

条码软件如何制作GS1-128条形码

GS1是国际物品编码组织的英文名称&#xff0c;全称为GS1全球统一标识系统。GS1是整个一个系统&#xff0c;或者说架构&#xff0c;其架构内部所包含的条码&#xff0c;可以有很多种&#xff0c;比如内部的条码是Code 128的&#xff0c;叫做GS1-128&#xff0c;而内部是DataBar的…

亚马逊条码标签(SSCC/FBA)的制作打印

近日&#xff0c;亚马逊对所有商家提出统一要求&#xff0c;产品须按照亚马逊制定的新规范来打印条码标签。做亚马逊外贸的商户都清楚&#xff0c;货品进入亚马逊仓库都必须通过扫描入库&#xff0c;否则无法进行上市销售。 有很多客户最近联系我们请求提供技术指导&#xff0c…