平台:mini2440

内核:linux 2.6.32.2

USB设备插入时。内核会读取设备信息,接着就把id_table里的信息与读取到的信息做比較。看是否匹配,假设匹配。就调用probe函数。

USB设备拔出时会调用disconnect函数。URB在USB设备驱动程序中用来描写叙述与USB设备通信时用到的基本载体和核心数据结构。

URB(usb request block)处理流程:

①USB设备驱动程序创建并初始化一个訪问特定USB设备特定端点的urb并提交给USB core。

②USB core把这个urb提交到USB主控制器驱动程序。

③USB主控制器驱动程序依据该urb描写叙述的信息来訪问usb设备。

④当设备訪问结束后,USB主控制器驱动程序通知USB设备驱动程序。

USB鼠标数据格式:

①bit0 ->左键,1->按下。0->松开

②bit1 ->右键,1->按下。0->松开

③bit2 ->中键,1->按下,0->松开

驱动代码清单:

usb_mouse_input_test.c:

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h> static struct urb *uk_urb;
static char *usb_buf;
static int len;
static struct input_dev *uk_dev;
static dma_addr_t usb_buf_phys; static struct usb_device_id usb_mouse_input_test_id_table [] =
{
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,
USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_MOUSE)
}
}; static void usb_mouse_input_test_irq(struct urb *urb)
{
static unsigned char pre_val;//USB鼠标将它的数据写到驱动缓冲区usb_buf
if ((pre_val & (1<<0)) != (usb_buf[0] & (1<<0)))
{
//状态变化
printk("left !\n");
} if ((pre_val & (1<<1)) != (usb_buf[0] & (1<<1)))
{
//状态变化
printk("right !\n");
} if ((pre_val & (1<<2)) != (usb_buf[0] & (1<<2)))
{
//状态变化
printk("middle !\n");
} pre_val = usb_buf[0];
usb_submit_urb(uk_urb, GFP_KERNEL);
} static int usb_mouse_input_test_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);//获取usb接口结构体中的usb设备结构体
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe; interface = intf->cur_altsetting; //获取usb接口结构体中的usb host接口结构体
endpoint = &interface->endpoint[0].desc;//获取usb host接口结构体中的端点描写叙述结构体
uk_dev = input_allocate_device(); set_bit(EV_KEY, uk_dev->evbit);//设置
set_bit(EV_REP, uk_dev->evbit);
set_bit(KEY_L, uk_dev->keybit);
set_bit(KEY_S, uk_dev->keybit);
set_bit(KEY_ENTER, uk_dev->keybit); input_register_device(uk_dev);//注冊
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
len = endpoint->wMaxPacketSize;
usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
uk_urb = usb_alloc_urb(0, GFP_KERNEL);//分配usb request block
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usb_mouse_input_test_irq, NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys; //源,目的。长度。设置URB
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_submit_urb(uk_urb, GFP_KERNEL);//把URB提交到USB主控制器驱动 return 0;
} static void usb_mouse_input_test_disconnect(struct usb_interface *intf)
{
struct usb_device *dev = interface_to_usbdev(intf);
printk("disconnect mouse!\n");
usb_kill_urb(uk_urb);
usb_free_urb(uk_urb);
usb_buffer_free(dev, len, usb_buf, usb_buf_phys);
input_unregister_device(uk_dev);
input_free_device(uk_dev);
} static struct usb_driver usb_mouse_input_test_driver = {
.name = "usb_mouse_input_test_",
.probe = usb_mouse_input_test_probe,
.disconnect = usb_mouse_input_test_disconnect,
.id_table = usb_mouse_input_test_id_table,
}; static int usb_mouse_input_test_init(void)
{
usb_register(&usb_mouse_input_test_driver);
return 0;
} static void usb_mouse_input_test_exit(void)
{
usb_deregister(&usb_mouse_input_test_driver);
} MODULE_LICENSE("GPL");
module_init(usb_mouse_input_test_init);
module_exit(usb_mouse_input_test_exit);

Makefile:

obj-m	+= usb_mouse_input_test.o

KERN_DIR = /home/***/linux-2.6.32.2

all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order

測试前去掉linux内核中鼠标功能:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3UyMDA5MzM0Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

insmod usb_mouse_input_test.ko

插入USB鼠标

点击鼠标三个按键

终端可见信息打印:

left !

right !

middle !

Linux USB 鼠标输入驱动具体解释的更多相关文章

  1. Linux USB 鼠标驱动程序详解(转)

    Linux USB 鼠标驱动程序详解 USB 总线引出两个重要的链表!一个 USB 总线引出两个重要的链表,一个为 USB 设备链表,一个为 USB 驱动链表.设备链表包含各种系统中的 USB 设备以 ...

  2. Linux USB ECM Gadget 驱动介绍

    ​1 USB ECM介绍 USB ECM,属于USB-IF定义的CDC(Communication Device Class)下的一个子类:Ethernet Networking Control Mo ...

  3. Linux usb子系统(一) _写一个usb鼠标驱动

    USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...

  4. Linux usb子系统(一):子系统架构

    一.USB协议基础知识   前序:USB概念概述 USB1.0版本速度1.5Mbps(低速USB) USB1.1版本速度12Mbps(全速USB)  USB2.0版本速度480Mbps(高速USB). ...

  5. Linux USB 和 sysfs

    由于单个 USB 物理设备的复杂性, 设备在 sysfs 中的表示也非常复杂. 物理 USB 设备 (通过 struct usb_device 表示)和单个 USB 接口(由 struct usb_i ...

  6. Linux驱动之USB鼠标驱动编写

    本篇博客分以下几部分讲解 1.介绍USB四大描述 2.介绍USB鼠标驱动程序功能及框架 3.介绍程序用到的结构体 4.介绍程序用到的函数 5.编写程序 6.测试程序 1.介绍USB四大描述符 USB设 ...

  7. 学习Linux下s3c2440的USB鼠标驱动笔记

    1.ARM-Linux下USB驱动程序开发1.1.1.linux下USB配置:*********(MassStorage:存储设备)********************************** ...

  8. Linux USB驱动学习总结(三)---- USB鼠标的加载、初始化和通信过程

    1.usbmouse的定义:usb鼠标既包含usb设备(usb_device)的属性也包含input输入设备(input_dev)的属性 struct usb_mouse { ];///USB鼠标设备 ...

  9. Linux usb子系统(二):USB设备驱动usb-skeleton.c

    usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...

随机推荐

  1. java程序main方法的参数String[] args

    public class ArgsTest { public static void main(String[] args) { System.out.println(args.length); fo ...

  2. Sublime Text 如何一个代码双屏显示代码上下部分?

    Sublime Text 如何一个代码双屏显示代码上下部分? sublime text如何一个代码双屏显示代码上下部分 先显示2行实图 把想要分屏显示的文件,打开新窗口,然后再拖过去就可以了. 快捷操 ...

  3. 关于天津中软国际ETC培训中心的见与闻

    半个月的时间转眼即逝,在中软国际天津ETC的实训的两个星期就这样过去了,在中软国际天津站的这段时间也收获了非常多.明确了非常多,了解了很多关于社会就业的知识以及关于软件培训的一些事情.尽管我的了解可能 ...

  4. 关于同一线程两次调用EnterCriticalSection的测试

    #include "stdafx.h" #include <iostream> using namespace std; #include <windows.h& ...

  5. linux ps查看进程命令详解

    http://linux.net527.cn/Linuxwendang/xitongguanliyuan/39094.htmlLinux操作系统PS命令详细解析 要对系统中进程进行监测控制,用 ps ...

  6. TypeScript 映射类型

    typescript支持定义类型加入推导式后产生新的类型 属性不变 但会改变对象的使用方式 这个是类型Person中加入ReadOnly推导出的新类型 他的属性全部是只读的 这个是推导出部分属性 这是 ...

  7. 本体论与OWL

    http://semanticweb.org/wiki/Main_Page.html http://owl.man.ac.uk/documentation.shtml  https://zh.wiki ...

  8. H5 获取地理位置

    只能通过手机浏览器访问,并且用户必须允许访问才可以生效 <!doctype html> <html> <head> <title>Mobile Cook ...

  9. Jquery学习笔记(1)--JQuery原理,与JS对象互换,核心函数

    js对象转jQuery对象,$('num'), jQuery对象转js对象,$('num')[0],或$('num').get(0). 1.点击换行,each(),html(),attr(),每个h1 ...

  10. 免安装Oracleclient和PL/SQL

    写在前面: Oracle是典型的C/S结构,服务端提供oracle服务的实例,主要用于数据库的管理,对象的管理与存储.数据的 存储.查询.数据库资源的监控.监听等一些服务. 而client仅仅是一个与 ...