一、填充file_operations结构体
file_operations结构体就是设备的具体操作函数,file_operations结构体类型的变量test_fops,但是还没对其进行初始化,也就是初始化其中的open、release、read和write等具体的设备操作函数。现在就来完成变量test_fops的初始化,设置好针对chrtest设备的操作函数。在初始化test_fops之前需要分析一下需求,也就是要对chrtest这个设备进行哪些操作,只有确定了需求以后才知道我们应该实现哪些操作函数。假设
对chrtest这个设备有如下两个要求:
1、能够对chrtest进行打开和关闭操作
设备打开和关闭是最基本的要求,几乎所有的设备都得提供打开和关闭的功能。因此需要实现file_operations中的open和release这两个函数。
2、对chrtest进行读写操作
假设chrtest这个设备控制着一段缓冲区(内存),应用程序需要通过read和write这两个函数对chrtest的缓冲区进行读写操作。所以需要实现file_operations中的read和write这两个函数。在其中加入test_fops这个结构体变量的初始化操作,完成以后的内容如下所示:
/*打开设备*/
static int chrtest_open(struct inode *inode, struct file *filp)
{
/*用户实现具体功能*/
return 0;
}
/*从设备读取*/
static ssize_t chrtest_read(struct file *filp, char __user *buf,
size_t cnt, loff_t *offt)
{
/*用户实现具体功能*/
return 0;
}
/*向设备写数据*/
static ssize_t chrtest_write(struct file *filp,
const char_user*buf,size_t cnt,loff_t *offt)
{
/*用户实现具体功能*/
return 0;
}
/*向设备写数据*/
static ssize_t chrtest_write(struct file *filp,
const char_user*buf,size_t cnt, loff_t *offt)
{
/*用户实现具体功能*/
return 0;
}
/*关闭/释放设备*/
static int chrtest_release(struct inode *inode,struct file*filp)
{
/*用户实现具体功能*/
return 0;
}
static struct file_operations test_fops ={
.owner = THIS_MODULE ,
.open=chrtest_open,
.read=chrtest_read,
.write=chrtest_write,
.release=chrtest_release,
};
/*驱动入口函数*/
static int __init xxx_init (void)
{
/*入口函数具体内容*/
int retvalue = 0;
/*注册字符设备驱动*/
retvalue = register_chrdev(200,"chrtest", &test_fops);
if(retvalue < 0){
/*字符设备注册失败,自行处理*/
}
return 0;
}
/*驱动出口函数*/
static void _ exit xxx _ exit ( void )
{
/*注销字符设备驱动*/
unregister_chrdev(200,"chrtest");
}
/*将上面两个函数指定为驱动的入口和出口函数*/
module_init(xxx_init);
module_exit(xxx_exit);
二、添加LICENSE和作者信息
最后需要在驱动中加入LICENSE信息和作者信息,其中LICENSE是必须添加的,否则的话编译的时候会报错,作者信息可以添加也可以不添加。LICENSE和作者信息的添加使用如下两个函数:
MODULE_LICENSE()//添加模块LICENSE信息
MODULE_AUTHOR()//添加模块作者信息