USB(Universal Serial Bus ),通用串行总线,是一种外部总线标准,用于规范电脑与外部设备的连接和通讯。是在1994年底由英特尔、康柏、IBM、Microsoft等多家公司联合提出的,自1996年推出后,已成功替代串口和并口,成为当今个人电脑和大量智能设备的必配接口之一。

linux内核支持两种类型的USB驱动程序,一种是PC机的USB驱动程序控制插入其中的USB设备,另一种是USB设备和主机通信。

第一种软件架构                                                          第二种软件架构

                    

这里我学习的是第一种

对于每个USB系统来说,都有主机控制器的设备,该控制器和一个根Hub作为一个整体。这个根Hub下可以接多级的Hub,每个子Hub又可以接子Hub。每个USB设备作为一个节点接在不同级别的Hub上。每条USB总线上最多可以接127个设备。

常见的USB主控制器规格有:

OHCI:主要是非PC系统上的USB芯片,应用于嵌入式系统,遵循USB1.1规范

UHCI:大多是Intel和Via主板上的USB控制器芯片。他们都是由USB1.1规格的。

EHCI是由Intel等几个厂商研发,兼容OHCI UHCI ,遵循USB2.0规范。

设备基础

USB设备种类繁多,但遵循一些规范。接入电脑,USB总线驱动程序会发出命令获取设备信息(描述符),USB设备会返回描述符给PC,USB设备有5中描述符:设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。一个USB设备只有一个设备描述符。

在USB设备的逻辑组织中,包含设备、配置、接口和端点4个层次。设备通常有一个或多个配置,配置通常有一个或多个接口,接口有零或多个端点。

每个USB设备都可以包含一个或多个配置,不同的配置使设备表现不同的功能组合,配置由多个接口组成。一个USB设备驱动程序对应一个USB接口,一个功能复杂的USB设备可以具有多个接口,USB设备中的唯一可寻址的部分是设备端点,端点的作用类似于寄存器.

urb

Linux内核中USB代码通过urb(USB请求块)和USB设备通信,以异步方式往USB设备的 特定USB端点发送/接收数据,每个端点都可以处理一个urb。

urb生命周期

1. USB 设备驱动程序创建并初始化一个访问特定端点的urb,并提交给USB 核心;

2. USB 核心提交该urb到USB主控制器驱动程序;

3. USB 主控制器驱动程序根据该urb描述的信息,来访问USB设备;

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

HID协议

HID(Human Interface Device),属于人机交互类的设备,如USB鼠标,USB键盘,USB游戏操纵杆等。该类设备必须遵循HID设计规范

USB驱动程序步骤

1 usb驱动使用的是USB总线模式,所有usb驱动都必须创建主要结构体struct usb_driver结构体

static struct usb_driver usbmouse_as_key_driver = {

.name= "usbmouse_as_key_",

.probe= usbmouse_as_key_probe,

.disconnect= usbmouse_as_key_disconnect,

.id_table= usbmouse_as_key_id_table,

};

2 把struct usb_driver 注册到usb核心

usb_register(&usbmouse_as_key_driver);

3 注册设备

input_register_device(uk_dev);

4 分配一块缓冲池存放数据

  1. /* 获取USB设备的某个端点 */

  2. pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

  3. /* 获取传输的数据的长度 */

  4. len = endpoint->wMaxPacketSize;

  5. /* 分配一块缓冲区用来存放usb鼠标的数据 */

  6. usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);

5分配、设置、初始化、提交一个urb,urb是用来传递USB主机控制器驱动的数据。当插入的设备和这个usb_driver匹配时,它的probe函数将会调用,我们在probe函数当中实现对urb的一些列操作.

  1. /* 1、分配一个usb请求块 */

  2. usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);

  3. /* 2、初始化这个usb请求块 */

  4. usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval);

  5. uk_urb->transfer_dma = usb_buf_phys;

  6. uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

  7. /* 3、提交这个usb请求块 */

  8. usb_submit_urb(uk_urb, GFP_KERNEL);

USB端点有4中类型:控制端点,中断端点,批量端点,等时端点,对应相应urb。其中等时urb没有初始化函数

6 usb鼠标获取数据的中断处理函数,这个函数是在urb初始化的时候传递进来的回调函数,鼠标发生动作时便会触及这个函数的调用,把鼠标的数据传递进来。

  1. /* usb鼠标的中断处理函数 */

  2. static void yl_usbmouse_irq(struct urb *urb)

  3. {

  4. int i = 0;

  5. /* 依次把数据打印出来 */

  6. printk("yl_usbmouse data : ");

  7. for(i = 0; i < g_yl_usbmouse.usb_buf_len; i++)

  8. {

  9. printk("0x%x ", g_yl_usbmouse.usb_buf_virt[i]);

  10. }

  11. printk("\n");

  12. /* 再次提交urb */

  13. usb_submit_urb(g_yl_usbmouse.urb, GFP_ATOMIC);

  14. }

总程序

  1. #include <linux/kernel.h>

  2. #include <linux/slab.h>

  3. #include <linux/module.h>

  4. #include <linux/init.h>

  5. #include <linux/usb/input.h>

  6. #include <linux/hid.h>

  7. static struct input_dev *uk_dev;

  8. static char *usb_buf;

  9. static dma_addr_t usb_buf_phys;

  10. static int len;

  11. static struct urb *uk_urb;

  12. static struct usb_device_id usbmouse_as_key_id_table [] = {

  13. { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,

  14. USB_INTERFACE_PROTOCOL_MOUSE) },

  15. //{USB_DEVICE(0x1234,0x5678)},

  16. { }/* Terminating entry */

  17. };

  18. static void usbmouse_as_key_irq(struct urb *urb)

  19. {

  20. static unsigned char pre_val;

  21. int i;

  22. static int cnt = 0;

  23. printk("data cnt %d: ", ++cnt);

  24. for (i = 0; i < len; i++)

  25. {

  26. printk("%02x ", usb_buf[i]);

  27. }

  28. printk("\n");

  29. }

  30. static int usbmouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)

  31. {

  32. struct usb_device *dev = interface_to_usbdev(intf);

  33. struct usb_host_interface *interface;

  34. struct usb_endpoint_descriptor *endpoint;

  35. int pipe;

  36. interface = intf->cur_altsetting;

  37. endpoint = &interface->endpoint[0].desc;

  38. /* a. 分配一个input_dev */

  39. uk_dev = input_allocate_device();

  40. /* b. 设置 */

  41. /* b.1 能产生哪类事件 */

  42. set_bit(EV_REP, uk_dev->evbit);

  43. /* c. 注册 */

  44. input_register_device(uk_dev);

  45. /* d. 硬件相关操作 */

  46. /* 数据传输3要素: 源,目的,长度 */

  47. /* 源: USB设备的某个端点 */

  48. pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

  49. /* 长度: */

  50. len = endpoint->wMaxPacketSize;

  51. /* 目的: */

  52. usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);

  53. /* 使用"3要素" */

  54. /* 分配usb request block */

  55. uk_urb = usb_alloc_urb(0, GFP_KERNEL);

  56. /* 使用"3要素设置urb" */

  57. usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval);

  58. uk_urb->transfer_dma = usb_buf_phys;

  59. uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

  60. /* 使用URB */

  61. usb_submit_urb(uk_urb, GFP_KERNEL);

  62. return 0;

  63. }

  64. static void usbmouse_as_key_disconnect(struct usb_interface *intf)

  65. {

  66. struct usb_device *dev = interface_to_usbdev(intf);

  67. //printk("disconnect usbmouse!\n");

  68. usb_kill_urb(uk_urb);

  69. usb_free_urb(uk_urb);

  70. usb_buffer_free(dev, len, usb_buf, usb_buf_phys);

  71. input_unregister_device(uk_dev);

  72. input_free_device(uk_dev);

  73. }

  74. /* 1. 分配/设置usb_driver */

  75. static struct usb_driver usbmouse_as_key_driver = {

  76. .name= "usbmouse_as_key_",

  77. .probe= usbmouse_as_key_probe,

  78. .disconnect= usbmouse_as_key_disconnect,

  79. .id_table= usbmouse_as_key_id_table,

  80. };

  81. static int usbmouse_as_key_init(void)

  82. {

  83. /* 2. 注册 */

  84. usb_register(&usbmouse_as_key_driver);

  85. return 0;

  86. }

  87. static void usbmouse_as_key_exit(void)

  88. {

  89. usb_deregister(&usbmouse_as_key_driver);

  90. }

  91. module_init(usbmouse_as_key_init);

  92. module_exit(usbmouse_as_key_exit);

  93. MODULE_LICENSE("GPL");

USB鼠标驱动简单设计相关推荐

  1. USB驱动程序设计之三USB鼠标驱动程序设计

    文章目录 USB驱动程序简介 USB驱动程序描述 USB设备列表 注册驱动 Linux USB 描述符 设备描述 设备描述 **配置描述:** 接口描述 接口设置 接口描述符 端点描述 USB URB ...

  2. win10万能触摸屏驱动_教你win10系统设置usb鼠标驱动的方法

    鼠标也有相对应的品牌,在不知道自己使用鼠标设备是什么品牌的情况下,下载安装usb鼠标万能驱动,该软件支持的usb鼠标品牌有罗技,雷蛇,多彩,微软,雷柏,双飞燕等.该驱动还能够适用于各种2.4G.蓝牙5 ...

  3. USB鼠标驱动开发流程

    USB驱动开发,针对某一个USB设备的某个功能(接口)构建的驱动程序.USB驱动并不直接和USB设备进行数据交互,而是通过USB总线驱动程序(USB Core和USB HCD)来操作USB设备的.一般 ...

  4. S3C2440 USB鼠标驱动(十九)

    http://www.cnblogs.com/lifexy/p/7641602.html 在上一章分析完USB总线驱动程序后,接下来开始写一个USB驱动: 本节目的:将USB鼠标的左键当作L按键,将U ...

  5. 十五、Linux驱动之USB鼠标驱动

    1. 如何编写USB鼠标驱动 结合十四.Linux驱动之USB驱动分析中的分析,我们开始写一个USB鼠标驱动.      USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动, ...

  6. Linux下的USB总线驱动(03)——USB鼠标驱动 usbmouse.c

    USB鼠标驱动 usbmouse.c 原文链接:http://www.linuxidc.com/Linux/2012-12/76197p7.htm drivers/hid/usbhid/usbmous ...

  7. USB鼠标驱动源代码分析

    学了URB,试着去分析了一下USB鼠标驱动源代码,更好去理解URB处理流程. /** $Id: usbmouse.c,v 1.15 2001/12/27 10:37:41 vojtech Exp $* ...

  8. linux3.4.2 之usb鼠标驱动,键盘驱动

    目录 1  USB相关基本知识 2  USB鼠标编程指导 3 USB鼠标驱动程序完整源码 4  USB鼠标驱动测试 5  USB键盘基本知识 6 USB键盘驱动程序 4  USB键盘驱动测试 1  U ...

  9. 从零开始学USB(二十六、usb鼠标驱动驱动实例分析[1]简介)

    这个驱动是在上一节的最简单的usb驱动基础上增加了输入子系统和usb包的获取和请求. 首先先给出一个稍微简化了一下的usb的鼠标驱动,这里只做了鼠标的三个按键.为了方便验证,这里用鼠标的左键,右键和中 ...

最新文章

  1. Python如何优化列表接口进行分页
  2. [UI] 精美UI界面欣赏[1]
  3. Android 存储路径选择
  4. 使用Spring AOP中MethodInterceptor记录日志
  5. 如何看懂dtd文档?
  6. 实例化讲解 RunLoop
  7. mysql被除数为0不报错_SQLServer中进行sql除法运算结果为小数时显示0的解决方案...
  8. 14.Excel vba开发-随机点名
  9. 钻井液中PHP是指什么,关于钻井液,你必须知道这些…
  10. Skew Heaps
  11. QQ出现大规模盗号,qq被盗发布不良信息怎么办
  12. mfs java_mfs权威指南
  13. 电子元器件的基本介绍
  14. Vue组件编写之Alert提示框组件编写
  15. 实时操作系统和分时操作系统
  16. EditPlus中文版下载
  17. Linux宝塔控制面板如何实现多个二级域名301重定向跳转
  18. Matrix Admin html5网站管理后台源码 Bootstrap响应式模板主题
  19. Project Web Access ActiveX控件 安装
  20. 游戏的衰落,更迭的结果

热门文章

  1. 计算机组成原理——MIPS指令概述
  2. 洛谷P5738【深基7.例4】歌唱比赛 C语言
  3. Python隐形马尔科夫实战_隐马尔科夫模型的Python3实现代码
  4. 多对一,多对多RNN例子(摘抄笔记)
  5. Cookie保存登录状态
  6. python 自动发微博_GitHub - RisingStar20/pf_send_weibo: 通过爬虫自动发微博的Python项目...
  7. U盘防毒,我有绝招。。。
  8. 组装一台计算机需要的配件,组装一台电脑需要哪些配件【详细列举】
  9. 深度神经网络入门--学习环境搭建
  10. java socket调用接口_Java中socket接口调用