Program for Linux USB-devices driver
开始啃硬骨头~ 这里我打算一步步给出USB device driver 的demo,希望有心能能够共同交流学习. 希望认识更多对Linux有兴趣的geek.
目前由于环境和自身能力方面原因还没能做实物的测试,篇章的最后打算给出一个在x86上模拟USB读写的driver,以后能够做实物测试之后再更新this blog
我的联系方式:
jasonleaster@gmail.com(由于偶不能登QQ,所以thunder bird的邮件只要电脑开着就一直在线~)
测试环境:
Ubuntu 14.0
kernel: 3.13.0
下面我比较详细的对代码进行了注释,要点都在代码中啦~
这段代码仅仅是个例子,相当于第一个驱动设备hello world一样,力求最简单化概括性的给出USB设备插入,拔出相关的处理过程,后面慢慢的写的更深入的时候,代码也就越来越”复杂“
我整理了USB device driver 代码相关的结构体,做了目录便于查阅
/**************************************************************
code writer : EOF
code date : 2014.08.18
code file : ./USB_1/usb_1.c
e-mail : jasonleaster@gmail.com
code purpose:
This is a demo for how to code for a USB device driver.
If there is something wrong with my code, please touch
me by e-mail. Thank you.
*************************************************************/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
/*
** This two Macro used to create a structure --
** 'usb_device_id' by 'USB_DEVICE'
*/
#define VENDOR_ID 0x08f7
#define PRODUCT_ID 0x0002
#define DEVICE_NAME "usb_1"
MODULE_AUTHOR("EOF");
MODULE_LICENSE("Dual BSD/GPL");
/*
** id_table stored many USB device's 'usb_device_id' structure
*/
static struct usb_device_id id_table[] =
{
{ USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
{ },
};
/*
** The 'MODULE_DEVICE_TABLE' Macro marks device in the
** module image so that the module can be loaded on demand if
** the device is hotplugged.
*/
MODULE_DEVICE_TABLE(usb,id_table);
/*
** The probe() method is invoked by khubd after device enumeration.
**
** @interface :contains information gleaned during the
** enumeration process.
**
** @id : the entry in the driver's 'usb_device_id' table
** that matches the values read from the USB-device.
**
*/
static int usb_probe(struct usb_interface * interface,
const struct usb_device_id *id)
{
dev_info(&interface->dev,"USB device now attached\n");
return 0;
}
/*
** disconnect() method is called when the device is unplugged or
** when the module is unloaded.
*/
static void usb_disconnect(struct usb_interface* interface)
{
dev_info(&interface->dev,"USB device now disconnect\n");
}
/*
** Each USB device has a 'usb_driver' data structure.
*/
static struct usb_driver usb_driver =
{
.name = DEVICE_NAME,
.probe = usb_probe,
.disconnect = usb_disconnect,
.id_table = id_table,
};
static int usb_init(void)
{
return usb_register(&usb_driver);
}
static void usb_exit(void)
{
usb_deregister(&usb_driver);
}
module_init(usb_init);
module_exit(usb_exit);
update: 2014.08.18 14:25
逐步完善
这里旨在说明
'usb_get_dev()' and 'usb_set_intfdata'
http://blog.csdn.net/cinmyheart/article/details/38628387#t21
上面的link,按目录查找相关函数定义即可
/**************************************************************
code writer : EOF
code date : 2014.08.18
code file : ./USB_2/usb_2.c
e-mail : jasonleaster@gmail.com
code purpose:
This is a demo for how to code for a USB device driver.
I emphasize to demo for function 'usb_get_dev()' and 'usb_set_intfdata'
If there is something wrong with my code, please touch
me by e-mail. Thank you.
*************************************************************/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/slab.h>
#define VENDOR_ID 0x08f7
#define PRODUCT_ID 0x0002
static struct usb_device_id id_table[] =
{
{USB_DEVICE(VENDOR_ID,PRODUCT_ID)},
{ },
};
MODULE_DEVICE_TABLE(usb,id_table);
struct my_usb
{
struct usb_device *udev;
int temp;
};
static int usb_probe(struct usb_interface* interface,const struct usb_device_id*id)
{
struct usb_device* udev = interface_to_usbdev(interface);
struct my_usb * my_dev;
my_dev = kzalloc(sizeof(struct my_usb),GFP_KERNEL);
if(!my_dev)
{
dev_err(&interface->dev,"Out of memory\n");
return -ENOMEM;
}
/*
** increase the reference about probe() method
*/
my_usb->udev = usb_get_dev(udev);
usb_set_intfdata(interface,my_usb);
dev_info(&interface->dev,"USB device now attached\n");
return 0;
}
static void usb_disconnect(struct usb_interface * interface)
{
struct my_usb *my_dev;
/*
** Get 'struct my_usb' from interface and then free
** free 'my_dev->udev'.
*/
my_dev = usb_get_intfdata(interface);
/*
** decrease the reference about probe() method
*/
usb_put_dev(my_dev->udev);
kfree(my_dev);
dev_info(&interface->dev,"USB device now disconnected]n");
}
static struct usb_driver my_usb_driver =
{
.name = "usb_2",
.probe = usb_probe,
.disconnect = usb_disconnect,
.id_table = id_table,
};
static int usb_init(void)
{
return usb_register(&my_usb_driver);
}
static void usb_exit(void)
{
usb_deregister(&my_usb_driver);
}
MODULE_AUTHOR("EOF");
MODULE_LICENSE("Dual BSD/GPL");
module_init(usb_init);
module_exit(usb_exit);
衡山日出