以USB鼠标驱动为例

框架入口源文件: usb_mouse.c  hub.c

(可根据入口源文件,再按着框架到内核走一遍)

内核版本:linux_2.6.22.6    硬件平台:JZ2440

以下是驱动框架:

以下是驱动代码 usb_mouse.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> //定义一个input_dev 结构体
static struct input_dev *usb_mouse_dev; static int usb_pipe;
static char *usb_buff;
static int usb_len;
static struct urb *usb_urb;
static dma_addr_t usb_buff_phy; // id_table .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
static struct usb_device_id usb_mouse_driver_id_table[] =
{
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE)},
}; //usb 中断
static void usb_mouse_int(struct urb *urb) {
#if 0
int i=;
static int cnt=;
printk("cnt = %d",++cnt);
for (i = ; i < usb_len; i++)
{
printk("%02x ", usb_buff[i]);
}
printk("\n");
#endif #if 1
static unsigned char pre_val; /* bit[0] 左 bit[1] 右 bit[3] 滑轮安下
*/ if ((pre_val & (<<)) != (usb_buff[] & (<<)))
{
input_event(usb_mouse_dev, EV_KEY, KEY_L, (usb_buff[] & (<<)) ? : );
input_sync(usb_mouse_dev);
} if ((pre_val & (<<)) != (usb_buff[] & (<<)))
{
input_event(usb_mouse_dev, EV_KEY, KEY_S, (usb_buff[] & (<<)) ? : );
input_sync(usb_mouse_dev);
} if ((pre_val & (<<)) != (usb_buff[] & (<<)))
{
input_event(usb_mouse_dev, EV_KEY, KEY_ENTER, (usb_buff[] & (<<)) ? : );
input_sync(usb_mouse_dev);
} pre_val = usb_buff[];
#endif //重新提交
usb_submit_urb(usb_urb, GFP_KERNEL);
} static int usb_mouse_driver_probe(struct usb_interface *intf,const struct usb_device_id *id)
{ struct usb_device *usb_dev;
//接口 端点
struct usb_host_interface *usb_interface;
struct usb_endpoint_descriptor *usb_endpoint; usb_interface = intf->cur_altsetting;
usb_endpoint = &usb_interface->endpoint[].desc; //输入子系统
//分配一个input_dev
usb_mouse_dev = input_allocate_device(); //初始化 input_dev 结构体
set_bit(EV_KEY,usb_mouse_dev->evbit);
set_bit(EV_REP,usb_mouse_dev->evbit); set_bit(KEY_L,usb_mouse_dev->keybit);
set_bit(KEY_S,usb_mouse_dev->keybit);
set_bit(KEY_ENTER,usb_mouse_dev->keybit); //注册 input_dev 结构体
input_register_device(usb_mouse_dev); //USB
// 起点:usb_dev usb_pipe 终点:usb_urb usb_buff 长度:usb_len 函数:usb_mouse_int
usb_dev = interface_to_usbdev(intf);
usb_pipe = usb_rcvintpipe(usb_dev, usb_endpoint->bEndpointAddress); usb_len = usb_endpoint->wMaxPacketSize; usb_urb = usb_alloc_urb(,GFP_KERNEL);
usb_buff = usb_buffer_alloc(usb_dev, usb_len, GFP_ATOMIC,&usb_buff_phy); //设置 URB
usb_fill_int_urb(usb_urb,usb_dev,usb_pipe,usb_buff, usb_len, usb_mouse_int, NULL, usb_endpoint->bInterval); usb_urb->transfer_dma = usb_buff_phy;
usb_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; //提交 URB
usb_submit_urb(usb_urb, GFP_KERNEL);
return ; } static void usb_mouse_driver_disconnect(struct usb_interface *intf)
{
struct usb_device *usb_dev= interface_to_usbdev(intf);
//usb
usb_kill_urb(usb_urb);
usb_free_urb(usb_urb);
usb_buffer_free(usb_dev, usb_len, usb_buff, usb_buff_phy);
// input_dev
input_unregister_device(usb_mouse_dev);
input_free_device(usb_mouse_dev);
} //定义一个usb_driver结构体
static struct usb_driver usb_mouse_driver =
{
.name = "usb_mouse_driver",
.probe =usb_mouse_driver_probe,
.disconnect =usb_mouse_driver_disconnect,
.id_table = usb_mouse_driver_id_table,
}; static int usb_mouse_driver_init(void)
{
usb_register(&usb_mouse_driver);
return ;
} static void usb_mouse_driver_exit(void)
{
usb_deregister(&usb_mouse_driver);
} module_init(usb_mouse_driver_init);
module_exit(usb_mouse_driver_exit);
MODULE_LICENSE("GPL");

以下是编译驱动的Makefile:

KERN_DIR = /work/systems/kernel/linux-/linux-2.6.22.6

all:
make -C $(KERN_DIR) M=`pwd` modules clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order obj-m += usb_mouse.o

USB驱动框架的更多相关文章

  1. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  2. Linux USB驱动框架分析【转】

    转自:http://blog.csdn.net/jeffade/article/details/7701431 Linux USB驱动框架分析(一) 初次接触和OS相关的设备驱动编写,感觉还挺有意思的 ...

  3. Linux USB驱动框架分析(2)【转】

    转自:http://blog.chinaunix.net/uid-23046336-id-3243543.html   看了http://blog.chinaunix.net/uid-11848011 ...

  4. Linux下USB驱动框架分析【转】

    转自:http://blog.csdn.net/brucexu1978/article/details/17583407 版权声明:本文为博主原创文章,未经博主允许不得转载. http://www.c ...

  5. am335x USB 驱动框架记录

    参考: http://processors.wiki.ti.com/index.php/AM335x_USB_Driver%27s_Guide http://processors.wiki.ti.co ...

  6. 【驱动】USB驱动·入门

    [驱动]USB驱动·入门 Preface USB是目前最流行的系统总线之一.随着计算机周围硬件的不断扩展,各种设备使用不同的总线接口,导致计算机外部总线种类繁多,管理困难.USB总线正是因此而诞生的. ...

  7. 【驱动】USB驱动·入门【转】

    转自:http://www.cnblogs.com/lcw/p/3159371.html Preface USB是目前最流行的系统总线之一.随着计算机周围硬件的不断扩展,各种设备使用不同的总线接口,导 ...

  8. linux usb驱动记录(一)

    一.linux 下的usb驱动框架 在linux系统中,usb驱动可以从两个角度去观察,一个是主机侧,一个是设备侧.linux usb 驱动的总体框架如下图所示:   从主机侧看usb驱动可分为四层: ...

  9. Android USB驱动源码分析(-)

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

随机推荐

  1. SpringMVC Jsp include 错误404 不显示页面

    一.问题描述: 1. 新建了taglibs.jsp存放jstl标签库和 jsp建站基本变量ctx 和basPath 如下  (位置WEB-INF\common) <%@ page import= ...

  2. shell中的函数 shell中的数组 告警系统需求分析

     

  3. Make ProgressBar Vertical

    Create a drawable in your Drawable folder called vertical_progress_bar.xml: <?xml version="1 ...

  4. SpringMVC注解@RequestParam与RequestMapping全面解析

    1.@RequestParam用法: SpringMVC后台控制层获取参数的方式主要有两种, 一种是request.getParameter("name"), 另外一种是用注解@R ...

  5. android 软键盘自动弹出和关闭

     一.布局中软键盘自动弹出 bargain_dialog_offer_edit.requestFocus(); bargain_dialog_offer_edit.setFocusable(true) ...

  6. [React] 13 - Redux: react-redux

    Ref: Redux 入门教程(三):React-Redux 的用法 组件拆分规范 使用 React-Redux,需要掌握额外的 API,并且要遵守它的组件拆分规范. React-Redux 将所有组 ...

  7. 【代码审计】五指CMS_v4.1.0 后台存在SQL注入漏洞分析

      0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...

  8. C#利用反射实现两个类的对象之间相同属性的值的复制

    http://blog.csdn.net/u013093547/article/details/53584591 今天在拷贝对象的时候,看着代码实在是有点烦,一堆一样的代码,还是找找有没有直接反射拷贝 ...

  9. 中检测到有潜在危险的 Request.Form 值。

    两步 一.在</system.web>之前加上<httpRuntime requestValidationMode="2.0" /> <httpRun ...

  10. Android定时执行和停止某任务

    一.定义全局变量 int runCount = 0;// 全局变量,用于判断是否是第一次执行 Handler handlerCount = new Handler(); 二.创建Runnable Ru ...