usb总线驱动模型里也有struct usb_driver和struct  usb_device,这点与platform虚拟总线里的struct platform_device和struct platform_driver相似。不同之处是
platform模型中,需要写两个驱动文件,分别是driver.ko和device.ko,然后分别insmod。
usb驱动只需要写一个驱动文件driver,只insmod driver.ko即可,为什么不insmod device.ko了呢?因为没写,恩,不必写。因为usb是实际的总线,当有usb设备插入的时候usbcore就会自动对该设备执行枚举,枚举之后usbcore就获知了该设备的相关资源,然后把资源信息返回给能匹配的驱动。
简言之,
平台驱动的insmod device.ko是一个模仿usb设备插入的动作,device.ko中记录了资源信息,通过insmod device,平台核心获取device的资源信息返回给匹配的驱动。
usb驱动模型中资源信息在储存在设备中呢,在usb设备插入时通过枚举,usbcore把资源信息读出来塞进返回给匹配的驱动。
怎么匹配的呢?对于platform是通过driver的名字和device的名字匹配的。对于usb模型,us_driver中有usb_device_id  table,记录该驱动可以处理的设备  的idVerdor和idProduct
当usb设备插入时,usbcore通过枚举过程获知当前设备的信息,包括两个id,然后和注册在usb总线上的各个usb驱动里的usb_device_id  table比较,有相同的的话,就调用哪个驱动的probe函数,并把该设备的资源信息(inteface)作为参数交给probe.这样哪个驱动就达到处理这个设备的目的了.
当然,先插入usb设备再insmod driver.ko,这种情况下去匹配两者的实现跟上面类似。
一下是linux/drivers/hid/usbhid/usbmouse.c里的一个usb_device_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) },{ } };

在linux/include/hid.h

#define USB_INTERFACE_CLASS_HID        3//在usb协议的接口描述符的bInterfaceClass字段如果为3,表示该设备为hid设备
#define USB_INTERFACE_SUBCLASS_BOOT    1//在usb协议的接口描述符的bInterfaceSubClass字段如果为1,表示是hid的子类:支持bios引导的hid
#define USB_INTERFACE_PROTOCOL_MOUSE    2//在usb协议的接口描述符的bInterfaceProtocol字段如果为2,表示协议为鼠标(在支持bios引导时用的,键盘协议为1)

USB_INTERFACE_INFO在linux/include/usb.h中定义,如下

#define USB_INTERFACE_INFO(cl, sc, pr) \.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \.bInterfaceClass = (cl), \.bInterfaceSubClass = (sc), \.bInterfaceProtocol = (pr)

所以它表示只要是hid设备,且支持bios引导,且引导时的协议为mouse,则此驱动都可以处理。

如果只声明支持一个设备可以用如下宏
linux/include/usb.h

#define USB_DEVICE(vend,prod) \.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \.idVendor = (vend), \.idProduct = (prod)

比如在usb_device_id里 添加一项,USB_DEVICE(0606,0001)

*****************************************************************************************************************************************************************************
一下是一个最简单的usb测试程序(比较完整的见linux-2.6.32.2/drivers/usb/usb-skeleton.c),仅测试一下usbcore对设备枚举玩,是否能够成功和此驱动匹配而进入probe函数

#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>/** Version Information*/
#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "song"
#define DRIVER_DESC "usb test"
#define DRIVER_LICENSE "GPL"MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);static int test_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{printk("probe\n");return 0;
}static void test_usb_disconnect(struct usb_interface *intf)
{
printk("disconnect\n");
}static struct usb_device_id test_usb_id_table [] = {{USB_DEVICE(0x0606,0x0001) },  {}
};MODULE_DEVICE_TABLE (usb, test_usb_id_table);static struct usb_driver test_usb_driver = {.name        = "test_song",.probe        = test_usb_probe,.disconnect    = test_usb_disconnect,.id_table = test_usb_id_table,
};static int __init test_usb_init(void)
{int retval = usb_register(&test_usb_driver);if (retval == 0)printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"DRIVER_DESC "\n");return retval;
}static void __exit test_usb_exit(void)
{usb_deregister(&test_usb_driver);
}module_init(test_usb_init);
module_exit(test_usb_exit);

makefile

ifneq ($(KERNELRELEASE),)
obj-m :=  test_usb.o
else
KDIR := /opt/FriendlyARM/mini2440/linux-2.6.32.2
#KDIR := /lib/modules/`uname -r`/build
all:  make -C $(KDIR) M=$(PWD) modules
clean:  rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif  

而设备侧(我的是sic8051f320单片机,内含usb从接口)的设备描述符和接口描述符,报告描述符设置如下,一下是一个自定义hid设备的部分描述符的设置

code DEVICE_DESCRIPTOR DeviceDesc =
{18,                  // bLength0x01,                // bDescriptorTypeSWAP16(0x0200),      // bcdUSB0x00,                // bDeviceClass0x00,                // bDeviceSubClass0x00,                // bDeviceProtocolEP0_PACKET_SIZE,     // bMaxPacketSize0SWAP16(USB_HID_VID),      // idVendor  0x0606 和linux侧驱动中的对应SWAP16(USB_HID_PID),              // idProduct  0x0001 和linux侧驱动中的对应0x0001,              // bcdDevice0x01,                // iManufacturer0x02,                // iProduct0x03,                // iSerialNumber0x01                 // bNumConfigurations
}; //end of DeviceDesc
    {0x09,                // bLength0x04,                // bDescriptorType0x00,                // bInterfaceNumber0x00,                // bAlternateSetting0x02,                // bNumEndpoints0x03,                // bInterfaceClass 指定为hid类0x00,                // bInterfaceSubClass  非鼠标键盘 00x00,                // bInterfaceProcotol 非鼠标键盘 00x00                 // iInterface}, //end of InterfaceDesc
//Report descriptor
code unsigned char ReportDesc[] =
{// 0x06, 0x00, 0xFF,//                         ; Usage Page0x05, 0x01,                              //桌面设备// 0x09, 0x01,//                              ; Usage0x09, 0x00,                             //未定义用途,结合接口描述符的bInterfaceClass=03,则为自动以hid0xA1, 0x01,  //                            ; Collection//用未定义用途开集合0x09, 0x01,//                              ; Usage0x95, 0x20,//                              ; Report Count0x75, 0x08,//                              ; Report Size0x15, 0x00,//                              ; Logical Minimum0x26, 0xFF, 0x00,//                         ; Logical Maximum0x81, 0x02,//                              ; Input0x09, 0x02,//                              ; Usage0x95, 0x20,//                              ; Report Count0x75, 0x08,//                              ; Report Size0x91, 0x02,//                              ; Output0xC0
};

在板子上,先不要插usb设备

[root@FriendlyARM plg]# insmod test_usb.ko
usbcore: registered new interface driver test_song
test_usb: v1.0:usb test

插上设备,信息如下,出现probe信息,说明成功匹配到驱动

[root@FriendlyARM plg]# usb 1-1.1: new full speed USB device using s3c2410-ohci and address 8
usb 1-1.1: New USB device found, idVendor=0606, idProduct=0001//厂商和产品id。不要受迷惑,是0x0606和0x0001
usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1.1: Product: nRF24LU1 ADapter
usb 1-1.1: Manufacturer: Weisdigital
usb 1-1.1: SerialNumber: Ver1.0 N000
usb 1-1.1: configuration #1 chosen from 1 choice//以上这些信息由usbcore在枚举完设备打印出来
probe

拔出设备,触发函数test_usb_disconnect,信息如下

usb 1-1.1: USB disconnect, address 8
disconnect

****************************************************************************************************************************************************************
另外在mini2440上已经有一个配置,
 Device Drivers  ---> [*] HID Devices  --->  <*>   USB Human Interface Device (full HID) support
这个驱动貌似通吃所有hid设备,包括mouse kbd,自定义hid等。所以如果我插入我的自定义hid设备时,就会被usbcore把我的设备优先匹配给这个驱动(即使我自己写的驱动已经insmod),这个驱动会在其probe函数中为我的设备自动创建一个input驱动,设备文件在/dev/input/eventx(x=1 2 3 ...)。但是我的设备没有按鼠标或键盘的数据格式给主机usbcore传送数据(当然我也不想这样传输,因为我的设备是自定义hid设备,当然要自定义的数据及格式,当然也不想让这个驱动去处理我的设备发来的数据)。
目前的解决办法是把这个选项给禁掉。这样usbcore就会把我的自定义hid设备匹配给我自己写的驱动了。
当然禁掉之后,usb鼠标 键盘都不能用了。不过可以配置一下另外一个鼠标和键盘的驱动,也可用的。如下
 Device Drivers  ---> [*] HID Devices  --->USB HID Boot Protocol drivers  --->  <*> USB HIDBP Keyboard (simple Boot) support
                                                                                                                              <*> USB HIDBP Mouse (simple Boot) support

不过要想出现USB HID Boot Protocol drivers项目,需要一些操作,在Kconfig文件line 47如下

menu "USB HID Boot Protocol drivers"depends on USB!=n && USB_HID!=y && EMBEDDED


USB符号不要选择为空(要选择m或y),USB_HID符号不要选择为y。最后那个符号EMBEDDED暂时没找到在哪里配的,就删掉了。即

menu "USB HID Boot Protocol drivers"
depends on USB!=n && USB_HID!=y

按照上面设置以后就会make menuconfig里就会出现USB HID Boot Protocol drivers项目。

再看一下/linux-2.6.32.2/drivers/hid/usbhid/Makefile,

# Multipart objects.
usbhid-objs    := hid-core.o hid-quirks.o# Optional parts of multipart objects.ifeq ($(CONFIG_USB_HIDDEV),y)usbhid-objs    += hiddev.o
endif
ifeq ($(CONFIG_HID_PID),y)usbhid-objs    += hid-pidff.o
endifobj-$(CONFIG_USB_HID)        += usbhid.o
obj-$(CONFIG_USB_KBD)        += usbkbd.o
obj-$(CONFIG_USB_MOUSE)        += usbmouse.

可知
<*>   USB Human Interface Device (full HID) support 对应的驱动应该是/linux-2.6.32.2/drivers/hid/usbhid/usbhid.c

<*> USB HIDBP Keyboard (simple Boot) support 对应的驱动是/linux-2.6.32.2/drivers/hid/usbhid/usbkbd.c
<*> USB HIDBP Keyboard (simple Boot) support 对应的驱动是/linux-2.6.32.2/drivers/hid/usbhid/usbmouse.c
后两者还好说,目录下确实有usbkbd.c和usbmouse.c,但是没有usbhid.c文件,那么usbhid.o哪里来的呢?恩,没人规定usbhid.o非得只由usbhid.c才能生成。

同目录下有一个文件.usbhid.o.cmd ,记录了usbhid.o由hid-quirks.o和hid-core.o生成。目前为止感觉很麻烦の。

arm-linux-ld -EL    -r -o drivers/hid/usbhid/usbhid.o drivers/hid/usbhid/hid-core.o drivers/hid/usbhid/hid-quirks.o 

转载于:https://www.cnblogs.com/-song/archive/2011/10/31/3331936.html

usb5-写成usb驱动相关推荐

  1. rfid3-micro2440,linux2.6.32.2,写成misc驱动

    接上文的进度,将keil下已经成功的读卡程序写成linux驱动的形式 采用misc来写比较方便简单,仅是为了方便测试,好多都在驱动中实现. 主文件是rfid.c #include "rc52 ...

  2. 10 怎么写USB驱动,Cadence USB 2.0 Controller和PHY IP驱动移植

    怎么写USB驱动,Cadence USB 2.0 Controller和PHY IP驱动移植 作者 将狼才鲸 日期 2022-03-26 本子文档所属的上级文档(Gitee仓库): 才鲸 / 嵌入式知 ...

  3. linux usb驱动 probe,linux USB设备驱动之2:usb设备的probe全过程

    本文将详细讲述2.6.22下的一个USB设备插上linux系统的PC后是如何一步一步调到我们的usb设备驱动的probe函数的,我们知道我们的USB驱动的probe函数中的一个参数是interface ...

  4. linux鼠标驱动程序,Linux usb子系统(一) _写一个usb鼠标驱动

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

  5. 旗舰版ndows7bios设置,戴尔成铭 3988台式机装win7系统的方法(intel 9代BIOS设置方法和USB驱动)...

    戴尔成铭 3988是一个台式机电脑,这台电脑就在出厂的时候采用的处理器是intel的第9代系列平台,这代平台的话官方是没有兼容win7系统的usb驱动的,因而用普通的方法安装完成了Win7后,全部的u ...

  6. Linux下烧写工具DNW和USB驱动安装

    Linux下编译记录: 编译PC端USB驱动和写入工具 dnw_linux.tgz压缩包文件结构如下 dnw_linux/ dnw_linux/secbulk/ dnw_linux/secbulk/M ...

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

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

  8. 通用usb驱动libusb介绍和使用示例

    小知识: sudo insmod /lib/modules/2.6.22-14-generic/kernel/drivers/usb/serial/usbserial.ko vendor=0x8086 ...

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

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

最新文章

  1. 伦理困境:人工智能浪潮与“AI威胁论”之争
  2. C++__min_element()和max_element()函数的使用
  3. 软件架构:5种你应该知道的模式
  4. 工业用微型计算机笔记(2)-二进制有符号数
  5. java抽象类的构造函数如何定义_我们可以在Java的抽象类中定义参数化的构造函数吗?...
  6. controlleradvice 参数_Spring MVC之@ControllerAdvice详解
  7. HDFS常用的Api
  8. ESP8266-01学习笔记01:如何使用USB转串口对ESP-01进行入门调试、烧录固件?
  9. python打印菱形星号代码_Python打印“菱形”星号代码
  10. 为普通用户添加root权限
  11. AntTweakBar with OpenGL
  12. 如何判断两物体加速度相等_高中物理知识点总结解题技巧:关联物体问题的求解方法...
  13. zmap扫描mysql_网站安全扫描工具 zmap怎么进行全网检测 - 驱动管家
  14. html页面怎么加入qq群,qq群申请
  15. 人工合成生命的最新进展比AI还快
  16. PowerBI 实现中国式报表
  17. 关于Python爬取热搜的另一种方法
  18. 微信小程序时间显示几分钟前、几小时前、几天前....
  19. Docker Image 基础使用命令
  20. 记录-关于网站的欢迎页,初次进入可见欢迎页,再次进入就直接显示主页了

热门文章

  1. WMI使用的WIN32_类库名
  2. Configuring Locales
  3. java.util.ConcurrentModificationException
  4. 解决Unable to create group (name already exists)
  5. git个人使用总结 —— idea命令行、撤销commit (未完待续)
  6. python 游戏 —— 汉诺塔(Hanoita)
  7. vs2015网站发布时,设置页面合并后程序集的文件版本
  8. 项目拆分子工程(简单版)
  9. Fiddler插件开发 - 实现网站离线浏览功能
  10. Python中的生成器与yield