驱动模板
1.文件操作
/*与一些其他函数,特殊功能需求的实现函数*/
2.核心数据结构体
/*主要是文件操作对应的结构体*/
3./*加载函数*/
static int __init misc_device_init(void)
{
/*实现对应驱动设备的注册*/
}
4./*卸载函数*/
static void __exit misc_device_exit(void)
{
/*实现对应驱动设备的卸载*/
}
5. 模块说明与开源协议
module_init();
module_exit();
MODULE_LICENSE("GPL");
**---------------------------------------------------------
一.杂项设备驱动编写——基于上面驱动架构
***1.模板步骤一实现文件操作函数***
loff_t My_lseek(struct file *myfile, loff_t off, int num)
{
printk("My_lseek is ok\n");
return 0;
}
//编写read 对应接口函数
ssize_t My_read (struct file *myfile, char __user *buf, size_t num, loff_t * off)
{
printk("My_read is ok\n");
return 0;
}
//编写write对应接口函数
ssize_t My_write (struct file *myfile, const char __user *buf, size_t num, loff_t * off)
{
printk("My_write is ok\n");
return 0;
}
//编写open对应接口函数
int My_open(struct inode * myinode, struct file * myfile)
{
printk("My_open is ok\n");
return 0;
}
//编写close对应接口函数
int My_close (struct inode *myinode, struct file *myfile)
{
printk("My_close is ok\n");
return 0;
}
***2.模板步骤二——核心数据结构体列举***
//定义并初始化文件操作数据结构
const struct file_operations Myfile={
.llseek = My_lseek,
.read = My_read,
.write = My_write,
.open = My_open,
.release = My_close,
};
//定义并初始化杂项核心数据结构
struct miscdevice Mymisc={
.minor =255,
.name ="my_misc",
.fops =&Myfile,
};
***3.模板步骤三——加载函数&注册驱动设备***
//加载匹配函数
static int __init Misc_device_init(void)
{
int ret;
//向内核注册一个杂项设备
ret =misc_register(&Mymisc);
if(ret <0)
{
printk("misc_register error\n");
return -1;
}
printk("misc_register ok\n");
return 0;
}
***4.模板步骤四——卸载函数&注销驱动设备***
//卸载匹配函数
static void __exit Misc_device_exit(void)
{
//注销杂项设备
misc_deregister(&Mymisc);
printk("misc_deregister ok\n");
}
***5.模板步骤五——模块说明与开源协议***
module_init(Misc_device_init);
//卸载函数声明
module_exit(Misc_device_exit);
//开源协议
MODULE_LICENSE("GPL");
二. 基于Linux2.6的字符设备驱动——基于上面模板
***1. 必要的接口函数与***
ssize_t dev_write(struct file *file, const char __user * user, size_t count, loff_t * lof)
{
printk("dev_write is ok\n");
return 0;
}
int dev_open(struct inode * myinode, struct file * myfile)
{
printk("dev_open is ok\n");
return 0;
}
***2. 必要的核心数据结构体***
const struct file_operations Myops={
.open = dev_open,
.write = dev_write,
};
***3. 加载设备函数&一些注册设备用到的全局变量***
//因为是动态的内存
dev_t dev;
struct cdev *p;
static int __init DE_HAL_ADD(void)
{
int ret;
***/*动态获取设备号*/***
ret = alloc_chrdev_region(&dev,0,1,DEV_NAME);
if(ret==0)
{
printk("get dev success");
printk("main id major = %d",MAJOR(dev));
printk("second id minor = %d",MINOR(dev));
}
/*动态开辟核心结构体空间*/
p = cdev_alloc();
/*给dev中的核心结构体ops赋值*/
cdev_init(p,&Myops);
/*对申请的结构体和设备号进行注册*/
cdev_add(p,dev,1);
printk("dev is runing******\n");
return 0;
}
***4. 卸载函数&注销驱动设备***
static int __exit DH_HAL_DEL(void)
{
cdev_del(p);
unregister_chrdev_region(dev,1);
printk("exit is runing*****\n");
kfree(p);
return 0;
}
***5. 开源协议***
module_init(DE_HAL_ADD);
module_exit(DH_HAL_DEL);
MODULE_LICENSE("GPL");