linux驱动15:open和release

open

int (*open) (struct inode *, struct file *);
open用于驱动程序的初始化,open主要的工作:

  • 检查设备特定的错误(如设备未就绪或硬件问题)
  • 如果设备是首次打开,则进行初始化(如果维护打开计数)
  • 如有必要,更新f_op指针
  • 分配并填写置于filp->private_data里的数据

release

int (*release) (struct inode *, struct file *);
主要完成以下工作:

  • 释放由open分配的、保存在file->private_data中的数据
  • 在最后一次关闭操作时关闭设备(如果维护打开计数)

当关闭一个设备的次数比打开的次数多时,系统发送什么情况?

        并不是每个close系统调用都会引起release方法的调用。只有那些真正释放设备数据结构的close调用才会调用release方法。内核对每个file结构维护其被使用多少次的计数器。只有open创建新的数据结构,其他操作如fork、dup只是增加已有结构的计数。file结构的计数归零时,close才调用release,这只在删除这个结构时发生。close和release的关系保证了每次open只有一次release。

flush方法在应用程序每次调用close时都会被调用。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>

static int major = 277;
static int minor = 0;
static dev_t devnum1;
static struct cdev cdev1;

int hello_open(struct inode *pinode, struct file *pfile)
{
	printk("hello_open, minor:%d, major:%d\n", iminor(pinode), imajor(pinode));
	return 0;
}

int hello_release(struct inode *pinode, struct file *pfile)
{
	printk("hello_release, minor:%d, major:%d\n", iminor(pinode), imajor(pinode));	
	return 0;
}

static struct file_operations hello_ops = {
	.open = hello_open,
	.release = hello_release,
};

static int hello_init(void)
{
	printk("hello_init\n");
	devnum1 = MKDEV(major,minor);
	printk("major:%d, minor:%d\n", MAJOR(devnum1), MINOR(devnum1));
	if (register_chrdev_region(devnum1, 1, "hello1"))//分配设备号
	{
		printk("register_chrdev_region failed\n");
		return -1;
	}

	cdev_init(&cdev1, &hello_ops);//初始化cdev,绑定fops
	if (cdev_add(&cdev1, devnum1, 1) < 0)//添加设备到内核
	{
		printk("cdev_add failed\n");
		unregister_chrdev_region(devnum1, 1);
		return -1;
	}

	return 0;
}

static void hello_exit(void)
{
	printk("hello_exit\n");
	cdev_del(&cdev1);
	unregister_chrdev_region(devnum1, 1);
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

在insmod后创建设备节点:mknod /dev/hello1 c 277 0   (mknod 节点名 c 主设备号 次设备号)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char * argv [ ])
{
	int fd = open("/dev/hello1", O_RDWR, 666);
	if (fd < 0)
	{
		perror("open faied");
		return -1;
	}

	printf("open successed: %d\n", fd);

	sleep(2);
	close(fd);
    return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值