以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

最新文章

  1. HttpClient 与 HtmlParser 简介 转载
  2. IE8 下 select option 内容过长 , 展开时信息显示不全解决办法
  3. python 多线程编程
  4. mybatis系列-12-多对多查询
  5. 给jdk写注释系列之jdk1.6容器(2)-LinkedList源码解析
  6. 影响pogo pin连接器使用寿命的因素
  7. JAVA 生成PDF报表()
  8. sql server使用说明
  9. ACdream 1020 The Game about KILL
  10. php 常用 常量集合
  11. GIT 查看 删除 添加远程库
  12. 【Debug】串口发送数据时部分字节被拉长,出现帧错误,原因MCU进入低功耗模式导致串口时钟停了!
  13. linux中安装gcc
  14. Kendo ui 入门知识点
  15. 【css】垂直居中的几种写法
  16. 12-关于DOM操作的相关案例
  17. pandas DataFrame(1)
  18. idea自己用得到的命令
  19. 微软职位内部推荐-Senior PM
  20. 每日英语:China to Move Slowly on One-Child Law Reform

热门文章

  1. Vue:Vue2.0搭建脚手架
  2. linux抓包命令之tcpdump
  3. 二叉树转换成森林&amp;amp;森林变成二叉树
  4. Golang中下划线的使用
  5. Linux内核 设备树操作常用API
  6. Power BI 报表服务器发布
  7. day_6.20动态加载py文件
  8. 使用 systemctl 创建 ss 开机
  9. 网络通信协议七之ARP工作过程及工作原理解析
  10. C语言迷题:有符号数与无符号数的问题(转)