您的位置:首页 > 运维架构 > Linux

linux下USB驱动及其相关研究(三) --驱动模块的编写

2008-03-28 11:32 239 查看
驱动模块的编写有一定的结构,看起来十分复杂,其实很简单。 首先就是模块的初始化函数,退出函数。初始化函数就是进行注册。

一 最简单的驱动结构:

1.1 申明一个结构体

static struct usb_driver naked_usb_driver = {
name : "nakedusb"
};

1.2 然后在init_module中加入:usb_register(&naked_usb_driver);
在cleanup_module中加入:usb_deregister(&naked_usb_driver);

二 一个即插即用的驱动

前提是打开拉linux内核的即插即用选项.插上usb之后,/proc/bus/usb中的devices 最下面会多出一个设备。在/proc/scsi/usb-storage 也可以查看当前设备的情况。

2.1 定义一个结构体struct usb_device_id

static struct usb_device_id my_usb_id =
{ idVendor : 0xXXXX,
idProduct : 0xXXXX
};

2.2 定义另外一个结构体 struct usb_driver

static struct usb_driver naked_usb_driver = {
name : "nakedusb",
probe : naked_usb_probe,
disconnect : naked_usb_disconnect,
id_table : &my_usb_id
};

2.3 定义结构体中的成员函数

static void* naked_usb_probe(struct usb_device *dev)
{
printk("<5>usb device probe./n");
if(dev->descriptor.idVendor == 0xXXXX && dev->descriptor.idProduct == 0xXXXX)
{
printk("<5>My usb device pluged in./n");
}
}

static void naked_usb_disconnect(struct usb_device *dev)
{
printk("<5>usb device disconnected./n");
if(dev->descriptor.idVendor == 0xXXXX && dev->descriptor.idProduct == 0xXXXX)
{
printk("<5>My usb device pluged out./n");
}
}

三 应用程序接口

就是说模块需要同应用层做通讯,应该实现一组接口。

3.1 定义一个结构体 struct file_operations

static struct file_operations usb_fops =
{
open : usb_open,
release : usb_close,
ioctl : usb_ioctl,
}

3.2 重新定义usb_driver结构体,增加fops : &usb_fops

static struct usb_driver naked_usb_driver = {
name : "nakedusb",
probe : naked_usb_probe,
disconnect : naked_usb_disconnect,
fops : &usb_fops,
id_table : &my_usb_id
};

3.3 在probe例程中加入注册设备文件的代码

static void* naked_usb_probe(struct usb_device *dev)
{
printk("<5>usb device probe./n");
if(dev->descriptor.idVendor == 0xXXXX && dev->descriptor.idProduct == 0xXXXX)
{
printk("<5>My usb device pluged in./n");
myusb_devfs_handle = devfs_register(
usb_devfs_handle,
"nakeusb",
DEVFS_FL_DEFAULT,
USB_MAJOR,
0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP | S_IROTH | S_IWOTH ,
&usb_fops,
NULL);
}
}
或者用register_chrdev()替代devfs_register()也可以。register_chrdev(USB_MAJOR,nakeusb,&usb_fops);

3.4 分别定义open、close、ioctl例程。

3.5 在命令行敲:mknod /dev/usb/nakeusb c 180 0其中nakeusb是在devfs_register的第二个参数,180是USB_MAJOR定义,0是第5个参数,c表示是字符型设备。

3.6 使用如下代码,就可以在用户层访问内核层的模块

int fd = open("/dev/usb/nakeusb",O_RDWR);
if(fd == -1)
{
printf("open w682 failed!/n");
return -1;
}
ioctl(fd,
  cmd,//定义参数,就是usb_ioctl中的cmd
  &arg//传给驱动程序的参数。
);
close(fd);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: