Leesagacious原创,欢迎转载
#include <linux/moduel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/atomic.h>
#include <linux/semaphore.h>
DEFINE_SEMAPHORE(lock) //新版的改变了,定义一个互斥信号量,并初始化为1
static int lee_open(struct inode * inode,struct file * file)
{
/**
down_trylock(struct semaphore * sem):
试图获取信号量sem,如果能立即获取到,它就获得该信号量,并且返回0,
获取不到就返回非0值,它不会导致调用者睡眠。它可以在中断上下文中使用,但是mutex_trylock就不能用在中断上下文中
*/
if(!down_trylock(&lock)){
printk("has opened!\n");
return 0;
}else{
return -EBUSY;
}
}
static int lee_release(struct inode * inode,struct file * file)
{
pirntk("lee_release has calling\n");
/**
这个函数释放信号量,即把sem的值加1,如果sem的值为非正数,表明有任务等 待该信号量,因此唤醒这些等待者。
*/
up(&lock);
}
//file_operations,定义了字符设备驱动提供给VFS的接口函数
struct file_operations lee_misc_fops = {
.owner = THIS_MODULE,
.open = lee_open,
.release = lee_release,
};
/**
混杂设备结构体,
*/
struct miscdevice lee_misc = {
.name = "leesagacious",
.mode = 0777, //文件的权限
.minor = MISC_DYNAMIC_MINOR, //让内核动态分配次设备号
.fops = &lee_misc_fops,//file_operations
};
static int __init lee_init(void)
{
int ret;
ret = misc_register(&lee_misc);
if(ret < 0){
printk("注册失败\n");
}
return 0;
}
static void __exit lee_exit(void)
{
misc_deregigter(&lee_misc);
}
module_init(lee_init);
module_exit(lee_exit);
MODULE_LICENSE("GPL");
!