(基于 Linux 3.4.2 内核)

可分为以下几个步骤来完成这个驱动:

1. 分配设置一个 usb_driver 结构体
2. 注册这个 usb_driver
(如果设备的 id_table 与驱动匹配的话会调用驱动程序的 probe 函数)
3. 在 probe 函数中分配 urb
4. 配置 urb
5. 调用 usb_submit_urb 启用 urb
6. 在 urb 中断函数内处理状态
7. 重新提交 urb

usb_driver 的配置与注册

/* 驱动的 id_table */
static struct usb_device_id usb_mouse_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_MOUSE) },
{ }
}; /* 分配设置 usb_driver */
static struct usb_driver mouse_monitor = {
.name = "MouseMonitor",
.probe = mouse_monitor_probe,
.disconnect = mouse_monitor_disconnect,
.id_table = usb_mouse_id_table,
}; /* 注册 usb_driver */
static int mouse_monitor_init(void)
{
usb_register(&mouse_monitor); return 0;
}

probe 函数

static int mouse_monitor_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
static struct usb_device *dev;
dma_addr_t usb_buf_phy;
int pipe;
int buffer_length; /* 得到 usb_device */
dev = interface_to_usbdev(intf); /* 得到当前的接口描述符与端点描述符 */
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc; /* 获取到设备数据长度 */
buffer_length = __le16_to_cpu(endpoint->wMaxPacketSize); len = buffer_length; /* 获取到通信的管道 */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); /* 分配一段连贯的内存 */
usb_buf = usb_alloc_coherent(dev, buffer_length, GFP_ATOMIC, &usb_buf_phy); /* 分配 urb */
MouseUrb = usb_alloc_urb(0, GFP_KERNEL); /* 配置 urb */
usb_fill_int_urb(MouseUrb, dev, pipe, usb_buf, (buffer_length > 8 ? 8 : buffer_length), usb_complete, NULL, endpoint->bInterval);
MouseUrb->transfer_dma = usb_buf_phy;
MouseUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* 提交调用 urb */
usb_submit_urb(MouseUrb, GFP_KERNEL); return 0;
}

urb 传输完成函数

static void usb_complete(struct urb *urb)
{
static unsigned char presta; #if 0
int i; for (i = 0; i < len; i++)
printk("%02x ", usb_buf[i]); printk("\n");
#endif if(presta != (usb_buf[1] & 0x01)){
if(presta)
printk("BTN_LEFT is released. \n");
else
printk("BTN_LEFT is pressed. \n");
} /* 保存状态 */
presta = usb_buf[1] & 0x01; /* 重新提交 urb */
usb_submit_urb(MouseUrb, GFP_KERNEL);
}

usb_complete 函数中注释掉的程序为测试使用,通过输出的数据找到鼠标左键对应的 usb_buf 与 bit 位。

测试驱动

make menuconfig 去掉原来的 USB 鼠标驱动
-> Device Drivers
-> HID Devices
<> USB Human Interface Device (full HID) support

编译当前驱动,传入开发板并安装。

按下松开鼠标左键,现象如下:

USB 驱动(监测鼠标左键的动作)的更多相关文章

  1. Swing中如何比较好的判断鼠标左键双击

    import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; im ...

  2. C# GDI绘制矩形框,鼠标左键拖动可移动矩形框,滚轮放大缩小矩形框

    最近工作需要,要做一个矩形框,并且 用鼠标左键拖动矩形框移动其位置.网上查了一些感觉他们做的挺复杂的.我自己研究一天,做了一个比较简单的,发表出来供大家参考一下.如觉得简单,可路过,谢谢.哈哈. 先大 ...

  3. zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法

    转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法: ze ...

  4. 【转】 js怎么区分出点击的是鼠标左键还是右键?

    IE 下 onMouseDown 事件有个 events.button 可以返回一个数值,根据数值判断取得用户按了那个鼠标键 events.button==0  默认.没有按任何按钮. events. ...

  5. [Eclipse] eclipse中打开xml文件,使用ctrl+鼠标左键无法跳转至Java源文件【待解决】

    eclipse中打开xml文件,使用ctrl+鼠标左键无法跳转至Java源文件: 1. 设置eclipse ctrl + 左键打开源文件代码,如下图,设置都正常 2. 在网上找了很多种办法,均失败,在 ...

  6. JavaScript经典代码【二】【javascript判断用户点了鼠标左键还是右键】

    IE 下 onMouseDown 事件有个 events.button 可以返回一个数值,根据数值判断取得用户按了那个鼠标键 events.button==0 默认.没有按任何按钮. events.b ...

  7. win10 uwp 获取按钮鼠标左键按下

    我们可以使用PointerPressed获得鼠标右键按下,但是我们如何获得左键? 其实UWP已经没有MouseLeftButtonDown,于是我们可以使用一个简单方法去获取鼠标左键按下. 我们在xa ...

  8. delphi Ctrl+鼠标左键或者Find Declaration不能定位到源文件

    在Delphi代码编辑器中使用Ctrl+鼠标左键可跳转到鼠标下的类所在的定义处,但今天发现一个奇怪的问题,EhLib组件的类无法跳转(包括uses中的pas文件),重新安装也是如此,后来经过验证,发现 ...

  9. unity windowEditor平台下鼠标左键控制摄像机的视角

    工作的原因,今天就只写了unity下的鼠标左键控制摄像机的视角左右上下调节:明天,补齐.[有诸多参考,着实是需要多多加油的] using System.Collections; using Syste ...

随机推荐

  1. 初识XMind基本操作

    花了一些时间来学习了XMind,梳理了一下学习基础部分的内容,分为输入文字,添加分支,超级链接或附件,以及美化操作四个部分.

  2. [MACHINE LEARNING] Can we predict voting outcomes?

    1. CART Tree library(rpart)library(rpart.plot)CTree = rpart(Party ~ . -USER_ID, data = train, method ...

  3. Apache ab性能测试结果分析

    Apache ab性能测试结果分析 测试场景:模拟10个用户,对某页发起总共100次请求. 测试命令: ab -n 100 -c 10 地址 测试报告: Server Software: 被测服务器软 ...

  4. PHP-自定义数组-预定义数组-自定义函数-预定义函数

    (1)自定义数组 —— 项目中的重点 (2)PHP预定义数组 —— 重点&难点 (3)自定义函数 —— 了解 (4)PHP预定义函数 —— 项目中的重点 1.自定义数组 数组:array,一个 ...

  5. dom4j 使用原生xpath 处理带命名空间的文档

    测试文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o ...

  6. 浅析软件工程中的UML建模技术

    一.基本信息 标题:浅析软件工程中的UML建模技术 时间:2018 出版源:电子世界 领域分类:软件工程:UML建模技术:需求分析 二.研究背景 问题定义:软件工程中UML建模技术的研究 难点:明确软 ...

  7. PHP几种加密方式

    1.MD5() 2.Sha1() 3.urlencode()方法用于加密,urldecode()方法用于解密 4.base64_encode (  )  64位加密   base64_decode ( ...

  8. linux安装方式

    一.rpm包安装方式步骤:  1.找到相应的软件包,比如soft.version.rpm,下载到本机某个目录: 2.打开一个终端,su -成root用户: 3.cd soft.version.rpm所 ...

  9. Swift5 语言指南(十四) 下标

    类,结构和枚举可以定义下标,下标是用于访问集合,列表或序列的成员元素的快捷方式.您可以使用下标按索引设置和检索值,而无需单独的设置和检索方法.例如,您可以访问在元素Array实例作为someArray ...

  10. mac的safari浏览器调试ios手机网页

    iOS 6给Safari带来了远程的Web检查器工具. 一.参考链接 ios开发者文档 safari开发者工具 remote debugging safari 二.设置iphone 设置 -> ...