USB 驱动(监测鼠标左键的动作)
(基于 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 驱动(监测鼠标左键的动作)的更多相关文章
- Swing中如何比较好的判断鼠标左键双击
import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; im ...
- C# GDI绘制矩形框,鼠标左键拖动可移动矩形框,滚轮放大缩小矩形框
最近工作需要,要做一个矩形框,并且 用鼠标左键拖动矩形框移动其位置.网上查了一些感觉他们做的挺复杂的.我自己研究一天,做了一个比较简单的,发表出来供大家参考一下.如觉得简单,可路过,谢谢.哈哈. 先大 ...
- zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法
转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法: ze ...
- 【转】 js怎么区分出点击的是鼠标左键还是右键?
IE 下 onMouseDown 事件有个 events.button 可以返回一个数值,根据数值判断取得用户按了那个鼠标键 events.button==0 默认.没有按任何按钮. events. ...
- [Eclipse] eclipse中打开xml文件,使用ctrl+鼠标左键无法跳转至Java源文件【待解决】
eclipse中打开xml文件,使用ctrl+鼠标左键无法跳转至Java源文件: 1. 设置eclipse ctrl + 左键打开源文件代码,如下图,设置都正常 2. 在网上找了很多种办法,均失败,在 ...
- JavaScript经典代码【二】【javascript判断用户点了鼠标左键还是右键】
IE 下 onMouseDown 事件有个 events.button 可以返回一个数值,根据数值判断取得用户按了那个鼠标键 events.button==0 默认.没有按任何按钮. events.b ...
- win10 uwp 获取按钮鼠标左键按下
我们可以使用PointerPressed获得鼠标右键按下,但是我们如何获得左键? 其实UWP已经没有MouseLeftButtonDown,于是我们可以使用一个简单方法去获取鼠标左键按下. 我们在xa ...
- delphi Ctrl+鼠标左键或者Find Declaration不能定位到源文件
在Delphi代码编辑器中使用Ctrl+鼠标左键可跳转到鼠标下的类所在的定义处,但今天发现一个奇怪的问题,EhLib组件的类无法跳转(包括uses中的pas文件),重新安装也是如此,后来经过验证,发现 ...
- unity windowEditor平台下鼠标左键控制摄像机的视角
工作的原因,今天就只写了unity下的鼠标左键控制摄像机的视角左右上下调节:明天,补齐.[有诸多参考,着实是需要多多加油的] using System.Collections; using Syste ...
随机推荐
- 339. Nested List Weight Sum
https://leetcode.com/problems/nested-list-weight-sum/description/ Given a nested list of integers, r ...
- Effective C++ 笔记:条款 31 将编译关系降至最低
31 : Minimize compilation dependencies between files 1 这关乎C++的类(或说都是类惹的祸) 1.1 C++类定义式的问题 C++类定义式不只叙述 ...
- Unity、C#读取XML
有如下XML文件: <?xml version="1.0" encoding="UTF-8"?> <DataNode> <prov ...
- python闭包和延迟绑定
一.什么是闭包: 1.函数内定义函数. 2.外函数的返回时内函数的引用. 3.内函数使用外函数的局部变量(至少一个). 1 def outfunc(): 2 for num in range(4): ...
- winSocket编程(十)完成端口
//本篇为转贴 本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了,不知该如何提笔,所以这篇文档总是在酝酿之中……酝酿了两年之后,终于决定开始动笔了,但愿还不算晚….. 这篇文档我非 ...
- C语言中的语句
• 表达式语句 表达式后加 ; 构成表达式语句. a = b+c; x+y i++ • 控制语句 完成一定的控制功能. if(...){...}else{...} ...
- 安装VS2017后打开项目提示 asp.net 4.0尚未web服务器注册
Visual Studio 2017 出来了,手痒安装完成后打开原来的项目缺提示,asp.net 4.0尚未web服务器注册.郁闷了… 按照提示的方法,如何:将 ASP.NET Web 应用程序升级到 ...
- create-react-app创建的项目npm run build之后静态文件找不到
create-react-app创建的项目npm run build之后,运行build中的index.html,什么都没显示,打开浏览器的F12,发现了几个红色的报错,提示几个文件找不到. 查看生成 ...
- [CocoaPods]如何使用CocoaPods插件
CocoaPods +插件 CocoaPods是一个由极少数维护者运营的社区项目,需要维护大量的表面区域.可以肯定地说CocoaPods永远不会支持Xcode支持的每个功能,即使这样,团队也必须对许多 ...
- python中stack在实际中的简单应用之进制转换
计算机的世界是二进制的,而人类的世界是十进制的,当数学公式用计算机表达时,经常 要转换.这就用到了进制的转换. 首先,我们先了解一下二进制和十进制的发展历史: 二进制: 现代的二进制首先由大数学家莱布 ...