USB鼠标按键驱动

news/2024/11/7 8:38:35/

怎么写USB驱动:
在这里插入图片描述
1. 分配/设置usb_driver结构体

/* 1. 分配/设置usb_driver结构体 */
static struct usb_driver usbmouse_as_key_driver = {.name		= "usbmouse_as_key",.probe		= usbmouse_as_key_probe,.disconnect	= usbmouse_as_key_disconnect,.id_table	= usbmouse_as_key_id_table,
};

设置id_table

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 */
};

在usb_driver中的probe函数中分配、设置、注册input_dev结构体,使其支持按键类事件

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_host_interface *interface;struct usb_endpoint_descriptor *endpoint;int pipe;/* a.分配一个input_dev结构体 */uk_dev = input_allocate_device();interface = intf->cur_altsetting;endpoint = &interface->endpoint[0].desc;/* b.设置 *//* b.1 能产生哪类事件 */set_bit(EV_KEY, uk_dev->evbit);set_bit(EV_KEY,uk_dev->evbit);//能产生按键类事件set_bit(EV_REP,uk_dev->evbit);//能产生重复类事件set_bit(EV_KEY,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.硬件相关操作 *//* 数据传输三要素  源  目的  长度* 源: USB设备的某个端点 */	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);/* 长度  */len = endpoint->wMaxPacketSize;/* 目的  2.6版本中使用usb_buffer_alloc* 3.4.2版本中使用usb_alloc_coherent函数 */usb_buffer = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);/* 使用3要素 * 分配USB请求块URB*/uk_urb = usb_alloc_urb(0, GFP_KERNEL);/* 使用3要素 设置URB */usb_fill_int_urb(uk_urb, dev, pipe, usb_buffer, 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;
}

当提交了urb之后,usb传输就已经开始工作了,当USB主控制器得到数据之后就会产生中断,之后就会进入注册的中断函数usbmouse_as_key_irq中去执行解析数据,并上报产生的鼠标事件。

static void usbmouse_as_key_irq(struct urb *urb)
{static unsigned char pre_val;//用来保存上一次的值if((pre_val & (1<<0)) != (usb_buffer[0] & (1<<0)))//说明左键值发生了改变{input_event(uk_dev, EV_KEY, KEY_L, (usb_buffer[0] & (1<<0)) ? 1 : 0);input_sync(uk_dev);}if((pre_val & (1<<1)) != (usb_buffer[0] & (1<<1)))//说明右键值发生了改变{input_event(uk_dev, EV_KEY, KEY_S, (usb_buffer[0] & (1<<1)) ? 1 : 0);input_sync(uk_dev);}if((pre_val & (1<<2)) != (usb_buffer[0] & (1<<2)))//说明中键值发生了改变{input_event(uk_dev, EV_KEY, KEY_ENTER, (usb_buffer[0] & (1<<2)) ? 1 : 0);input_sync(uk_dev);}pre_val = usb_buffer[0];//pre_val记录上一次的值,供上面进行比较/* 重新提交urb */usb_submit_urb(uk_urb, GFP_KERNEL);
}

下面是usbmouse_as_key_disconnect函数

static void usbmouse_as_key_disconnect(struct usb_interface *intf)
{//printk("disconnect usbmouse!\n");usb_kill_urb(uk_urb);usb_free_urb(uk_urb);usb_free_coherent(dev, len, usb_buffer, usb_buf_phys);input_unregister_device(uk_dev);input_free_device(uk_dev);
}

下面是定义的全局变量

static struct input_dev *uk_dev; 
static char *usb_buffer;
static dma_addr_t * usb_buf_phys;
static int len;
static struct urb *uk_urb;

总结

根据“总线–驱动–设备”模型
在这里插入图片描述usb_bus_type结构体中有一个match函数,用于匹配设备和驱动
当一个新的USB设备接入时,USB总线驱动程序会帮我们发现并创建一个新设备,并获得设备的描述符信息并解析
把device放入usb_bus_type的dev链表, 从usb_bus_type的driver链表里取出usb_driver,
把usb_interface(逻辑上的设备)和usb_driver的id_table比较,如果能匹配,调用usb_driver的probe函数
这里是在probe函数中分配、设置、注册input_dev结构体,使其支持按键类事件,并通过USB总线提供的
函数获取数据,然后在中断中处理数据并上报事件。这里要注意,USB设备并不能主动地上报数据,它是通过
USB主控制器不断轮询来获取USB设备的数据,一旦接收到数据,USB控制器就会触发中断,来上报事件。


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

相关文章

USB驱动--USB鼠标

其实光看USB鼠标的驱动&#xff0c;不知道USB插到开发板上发生了什么事&#xff0c;感觉还是没有掌握。 一、USB插到开发板上发生了什么&#xff1a; 在linx 系统中&#xff0c;usb热插拔由两部分方面共同实现&#xff0c;即内核空间和用户空间&#xff0c;内核由一个守护进程…

usb hid驱动 - usb鼠标

usb鼠标符合usb hid协议, 一般是单一功能(即一个usb 接口) 该接口下有一个默认的双向控制端点, 以及1个中断 in端点 bulk in端点读取数据定义: (具体定义需参考hid report描述符, https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/) 通常大部分usb鼠标…

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鼠标…