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 ...
随机推荐
- idea执行mapreduce报错 Could not locate Hadoop executable: C:\hadoop-3.1.1\bin\winutils.exe
window执行mapreduce报错 Exception in thread "main" java.lang.RuntimeException: java.io.FileNot ...
- 简单易用的图像库stb_image
最近又回到了选择图像库的老问题上,之前用过FreeImage,DevIL,libpng. FreeImage的问题是他的Licence有点迷,双证书,除了GPL还有个自己的没读懂,不商用的话随便折腾, ...
- visual studio 2017使用技巧
visual studio 2017使用技巧 批量删除代码中的空白行 Ctrl + H, 查找: ^(?([^\r\n])\s)*\r?$\r?\n 替换: 使用正则表达式 当前文档 常用快捷键 注释 ...
- Servlet 中,out.print()与out.write()的区别
最近刚学习了Ajax,其中有通过$.getJSON的实现方式 由于前后端传递值的时候会通过流的方式进行传递,这就不得不涉及到这方面的知识了 PrintWrite out=response.getWri ...
- Dynamic Programming | Set 1 (Overlapping Subproblems Property)
动态规划是这样一种算法范式:将复杂问题划分为子问题来求解,并且将子问题的结果保存下来以避免重复计算.如果一个问题拥有以下两种性质,则建议使用动态规划来求解. 1 重叠子问题(Overlapping S ...
- 关于 redis的操作
1.修改配置文件 redis.conf是redis的配置文件,redis.conf在redis源码目录. 注意修改port作为redis进程的端口,port默认6379.如果需要搭建redis集群,千 ...
- libRTMP 整体说明
函数结构 (libRTMP)的整体的函数调用结构图如下图所示: 原图地址:http://img.my.csdn.net/uploads/201602/10/1455087168_7199.png 基本 ...
- 使用FFmpeg如何转发一个RTSP视频流
版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/6930221.html 转发RTSP流,这类需求一般出现于转发一些摄像头采集视频,并在摄像头上做RTSP ...
- 3.复杂的viewpager
实现这样的效果: 1.主页面布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quo ...
- Java 数组的创建
与C.C++不同,Java在定义数组时并不为数组元素分配内存,因此[ ]中无需指定数组元素的个数,即数组长度. 定义一个数组有两种方式: int[] array; int array[]; 对于如上定 ...