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 ...
随机推荐
- android 可以在程序代码中设置样式:style
<style name="text_style"> <item name="android:textStyle">bold</it ...
- Linux学习笔记:常用软件
Linux系统下常用软件(针对CentOS,其他系统类似) lrzsz 可用于上传和下载,安装 yum -y install lrzsz ,使用 上传 rz 下载 sz mysql 安装 yum -y ...
- [uboot] (第四章)uboot流程——uboot编译流程
http://blog.csdn.net/ooonebook/article/details/53000893 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...
- sock5客户端解密数据流
一.安装 略 二.配置 vi /etc/shadowsocks.json { "server":"x.x.x.x", , , "password&qu ...
- 2019.02.12 bzoj5294: [Bjoi2018]二进制(线段树)
传送门 题意简述: 给出一个长度为nnn的二进制串. 你需要支持如下操作: 修改每个位置:1变0,0变1 询问对于一个区间的子二进制串有多少满足重排之后转回十进制值为333的倍数(允许前导000). ...
- spring深入学习(五)-----spring dao、事务管理
访问数据库基本是所有java web项目必备的,不论是oracle.mysql,或者是nosql,肯定需要和数据库打交道.一开始学java的时候,肯定是以jdbc为基础,如下: private sta ...
- 中标麒麟(linux)下Qt调用python
转自:https://blog.csdn.net/lwlgzy/article/details/83857297 http://www.cnblogs.com/jiaping/p/6321859.ht ...
- HDU 4309 Seikimatsu Occult Tonneru (状压 + 网络流)
题意:输入 n 个城市 m 条边,但是边有三种有向边 a b c d,第一种是 d 是 0,那么就是一条普通的路,可以通过无穷多人,如果 d < 0,那么就是隧道,这个隧道是可以藏 c 个人, ...
- 【慕课网实战】一、以慕课网日志分析为例 进入大数据 Spark SQL 的世界
课程整套CDH相关的软件下载地址:http://archive.cloudera.com/cdh5/cdh/5/ cdh-5.7.0 生产或者测试环境选择对应CDH版本时,一定要采用尾号是一样的版本 ...
- uniGUI动态建立Form及释放
uniGUI动态建立Form及释放 (2015-10-01 14:51:12) 转载▼ 分类: uniGUI 用uniGUI开发的项目中,难免要遇到动态建立一个Form,再释放掉,与传统Delph ...