USB驱动程序代码分析——检测设备插入拔出
2012-07-10 18:01
495 查看
我们先来看代码:
/*
* drivers\hid\usbhid\usbmouse.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>
/* 关于这个结构体我们在注释1里面会有分析 */
static struct usb_device_id usb_mouse_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_MOUSE) },
{ }
/* Terminating entry */
};
/* 匹配时会调用这个函数 */
static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
printk("found usbmouse!\n");
printk("bcdUSB = %x\n", dev->descriptor.bcdUSB);
printk("VID = 0x%x\n", dev->descriptor.idVendor);
printk("PID = 0x%x\n", dev->descriptor.idProduct);
return 0;
}
/* 拔出时会自动调用这个函数 */
static void usb_mouse_disconnect(struct usb_interface *intf)
{
printk("disconnect usbmouse!\n");
}
static struct usb_driver usb_mouse_driver = {
.name
= "usbmouse",
.probe
= usb_mouse_probe,
.disconnect
= usb_mouse_disconnect,
.id_table
= usb_mouse_id_table,
};
static int __init usb_mouse_init(void)
{
int retval = usb_register(&usb_mouse_driver);//注册
return retval;
}
static void __exit usb_mouse_exit(void)
{
usb_deregister(&usb_mouse_driver);//卸载
}
module_init(usb_mouse_init);
module_exit(usb_mouse_exit);
MODULE_LICENSE("GPL");
注释1:
上一节里我们已经知道,插上usb设备后会读取设备的信息,然后根据读取的设备的信息我们来判断驱动与设备是否匹配。下面我们开始来分析:
首先找到 USB_INTERFACE_INFO的定义:
#define USB_INTERFACE_INFO(cl,sc,pr) \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
.bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO:表示要匹配接口信息
bInterfaceClass = (cl),:表示接口的类必须是USB_INTERFACE_CLASS_HID
.bInterfaceSubClass = (sc),:表示子类必须是USB_INTERFACE_SUBCLASS_BOOT
.bInterfaceProtocol = (pr):表示协议必须是USB_INTERFACE_PROTOCOL_MOUSE
一旦匹配就调用probe函数了
关于本程序我们来总结一下:
当插入USB设备时,会根据usb_mouse_driver 里的id.table去判断驱动与设备是否匹配,如果匹配,就会调用probe函数,在这个函数里面我们打印出了设备的一些信息,这些信息已经被内核读了出来。当拔出设备时会调用disconnect函数。其实这个机制就和平台总线设备驱动机制相似,只不过平台总线设备驱动机制的匹配比较容易,只需要设备名与驱动名相同就可以,但是usb总线驱动相对要复杂了,上面已经讲过了。
测试:
1. make menuconfig去掉原来的USB鼠标驱动
-> Device Drivers
-> HID Devices
<> USB Human Interface Device (full HID) support
2. make uImage 并使用新的内核启动
3. insmod usbmouse_as_key.ko
4. 在开发板上接入、拔出USB鼠标
5. 打印出如下信息:
# usb 1-1: new low speed USB device using s3c2410-ohci and address 2
usb 1-1: configuration #1 chosen from 1 choice
found usbmouse!
bcdUSB = 110
VID = 0x93a
PID = 0x2510
usb 1-1: USB disconnect, address 2
disconnect usbmouse!
这里面有些信息是内核打印的
/*
* drivers\hid\usbhid\usbmouse.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>
/* 关于这个结构体我们在注释1里面会有分析 */
static struct usb_device_id usb_mouse_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_MOUSE) },
{ }
/* Terminating entry */
};
/* 匹配时会调用这个函数 */
static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
printk("found usbmouse!\n");
printk("bcdUSB = %x\n", dev->descriptor.bcdUSB);
printk("VID = 0x%x\n", dev->descriptor.idVendor);
printk("PID = 0x%x\n", dev->descriptor.idProduct);
return 0;
}
/* 拔出时会自动调用这个函数 */
static void usb_mouse_disconnect(struct usb_interface *intf)
{
printk("disconnect usbmouse!\n");
}
static struct usb_driver usb_mouse_driver = {
.name
= "usbmouse",
.probe
= usb_mouse_probe,
.disconnect
= usb_mouse_disconnect,
.id_table
= usb_mouse_id_table,
};
static int __init usb_mouse_init(void)
{
int retval = usb_register(&usb_mouse_driver);//注册
return retval;
}
static void __exit usb_mouse_exit(void)
{
usb_deregister(&usb_mouse_driver);//卸载
}
module_init(usb_mouse_init);
module_exit(usb_mouse_exit);
MODULE_LICENSE("GPL");
注释1:
上一节里我们已经知道,插上usb设备后会读取设备的信息,然后根据读取的设备的信息我们来判断驱动与设备是否匹配。下面我们开始来分析:
首先找到 USB_INTERFACE_INFO的定义:
#define USB_INTERFACE_INFO(cl,sc,pr) \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
.bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO:表示要匹配接口信息
bInterfaceClass = (cl),:表示接口的类必须是USB_INTERFACE_CLASS_HID
.bInterfaceSubClass = (sc),:表示子类必须是USB_INTERFACE_SUBCLASS_BOOT
.bInterfaceProtocol = (pr):表示协议必须是USB_INTERFACE_PROTOCOL_MOUSE
一旦匹配就调用probe函数了
关于本程序我们来总结一下:
当插入USB设备时,会根据usb_mouse_driver 里的id.table去判断驱动与设备是否匹配,如果匹配,就会调用probe函数,在这个函数里面我们打印出了设备的一些信息,这些信息已经被内核读了出来。当拔出设备时会调用disconnect函数。其实这个机制就和平台总线设备驱动机制相似,只不过平台总线设备驱动机制的匹配比较容易,只需要设备名与驱动名相同就可以,但是usb总线驱动相对要复杂了,上面已经讲过了。
测试:
1. make menuconfig去掉原来的USB鼠标驱动
-> Device Drivers
-> HID Devices
<> USB Human Interface Device (full HID) support
2. make uImage 并使用新的内核启动
3. insmod usbmouse_as_key.ko
4. 在开发板上接入、拔出USB鼠标
5. 打印出如下信息:
# usb 1-1: new low speed USB device using s3c2410-ohci and address 2
usb 1-1: configuration #1 chosen from 1 choice
found usbmouse!
bcdUSB = 110
VID = 0x93a
PID = 0x2510
usb 1-1: USB disconnect, address 2
disconnect usbmouse!
这里面有些信息是内核打印的
相关文章推荐
- 一个很有用的检测USB设备插入拔出的对象(from Torry's Dephi Pages)
- 一个用于监视USB设备插入拔出的程序代码
- 检测USB设备插入和拔出
- MFC 如何检测到USB设备插入拔出
- 一个很有用的检测USB设备插入拔出的对象
- 安卓检测USB设备插入之后回调用户代码的小框架编写
- windows CE下的USB设备驱动程序分析 .
- USB设备的插入检测机制(转自…
- netmap源码分析(一)插入 netmap 代码到驱动程序
- USB学习系列之二——USB设备的插入检测
- USB驱动程序代码分析——鼠标用作键盘
- QT编程--监听USB设备拔出和插入。
- windows CE下的USB设备驱动程序分析(二)
- USB设备的插入检测
- USB驱动程序代码分析——鼠标用作键盘
- Windows中USB设备插入的拔出和所产生的消息值
- Android日志系统分析之日志设备驱动程序代码阅读
- USB设备插入与拔出的响应
- 总线驱动程序如何捕获到相关设备插入拔出事件
- 检测USB设备的插入和拔出