关于IO多路复用的字符设备驱动(自我记录)

#include<linux/init.h>
#include<linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/poll.h>
struct cdev* cdev;
struct device* dev;
struct class* cls;
int major=0;
int minor=0;
const int countt=1;
#define LNAME "meleds"
char kbuf[128]={0};
wait_queue_head wq;
int condition=0;
ssize_t myy_read(struct file *file, char __user *ubuf, size_t size, loff_t * offs)
{
	int ret;
	if(size > sizeof(kbuf))
		{
		size=sizeof(kbuf);
	}
	ret=copy_to_user(ubuf,kbuf,size);
	if(ret)
		{
		printk("copy to user error\n");
		return -EIO;
	}
	condition=0;
	return size;
}
ssize_t myy_write(struct file *file, const char __user *ubuf, size_t size, loff_t * offs)
{
	int ret;
		if(size > sizeof(kbuf))
			{
			size=sizeof(kbuf);
		}
		ret=copy_from_user(kbuf,ubuf,size)
		if(ret)
			{
			printk("copy from user error\n");
			return -EIO;
		}
	wake_up_interruptible(&wq);
	condition=1;
return size;
}
int myy_open(struct inode *inode, struct file *file)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
	return 0;
}
int myy_close(struct inode *inode, struct file *file)
{
	printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
		return 0;
}
__poll_t myy_poll(struct file *file, struct poll_table_struct * wait)
{
	__poll_t mask=0;
	poll_wait(file,&wq,wait);
	if(condition)
	{
		mask |=	EPOLLIN;
	}
	return mask;
}
const struct file_operations fops={
	.open=myy_open,
	.release=myy_close,
	.read=myy_read,
	.write=myy_write,
	.poll=myy_poll,
};
static int __init   ioduolu_init(void)
{
	int i,ret;
	dev_t devno;
	cdev=cdev_alloc();
	if(cdev == NULL)
		{
		printk("cdev error\n");
		ret=-ENOMEM;
		goto ERR1;
	}
	cdev_init(cdev,&fops);

	ret=alloc_chrdev_region(devno,minor,countt,LNAME);
	if(ret)
		{
	printk("alloc error\n");
	goto ERR2;

	}
	major=MAJOR(devno);
	minor=MINOR(devno);
	ret=cdev_add(cdev,MKDEV(major,minor),countt)
		if(ret)
		{
			printk("cdev add error\n");
			goto ERR3;

		}
		cls=class_create(THIS_MODULE,LNAME);
		if(IS_ERR(cls))
		{
			printk("class error\n");
			ret=PTR_ERR(cls);
			goto ERR4;
		}
		
		dev=device_create(cls,NULL,MKDEV(major,minor),NULL,"myledss",i);
		if(IS_ERR(dev))
		{
			printk("dev error\n");
			ret=PTR_ERR(dev);
			goto ERR5;
		}
		init_waitqueue_head(&wq);

		
		return 0;
	ERR5:
		device_destroy(cls,MKDEV(major,minor));
		class_destroy(cls);	
	ERR4:
		cdev_del(cdev);
	ERR3:
		unregister_chrdev_region(MKDEV(major,minor),countt);
	ERR2:
		kfree(cdev);
	ERR1:
		return ret;
}

static  void __exit ioduolu_exit(void)
{
		device_destroy(cls,MKDEV(major,minor));
		class_destroy(cls); 
		cdev_del(cdev);
		unregister_chrdev_region(MKDEV(major,minor),countt);
		kfree(cdev);
}
module_init(ioduolu_init);
module_exit(ioduolu_exit);
MODULE_LICENSE("GPL")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值