Linux 新字符设备驱动代码示例

1、定义LED设备结构体,成员变量为设备的相关属性

2、定义file_operations 操作集,完成open,read,write,release函数

3、加载驱动时,完成设备注册和自动创建设备节点

 字符设备注册方法:先创建设备号,再初始化cdev,再添加cdev
 自动创建设备节点:先创建类,再创建设备

4、卸载驱动时,依次进行以下操作

删除字符设备,注销设备号,摧毁设备,摧毁类

 

#define NEWCHRLED_NAME "newchrled"
#define NEWCHRLED_COUNT 1



/*LED 设备结构体*/
struct newchrled_dev
{
	struct cdev cdev; 		/*字符设备*/
	dev_t devid; 			/*设备号*/
	struct class *class; 	/*类*/
	struct device *device;  /*设备*/
	int major;	 			/*主设备号*/
	int minor;	 			/*此设备号*/
};

struct newchrled_dev newchrled; /*led 设备*/



static int newchrled_open(struct inode *inode, struct file *filp)
{
	filp->private_data = &newchrled;
	return 0;
}

static int newchrled_release(struct inode *inode, struct file *filp)
{
	struct newchrled_dev *dev = (struct newchrled_dev*)filp->private_data;
	return 0;
}

static ssize_t newchrled_write(struct file *filp, const char __user *buf,
						 size_t count, loff_t *ppos)
{
	int retvalue;
    struct newchrled_dev *dev = (struct newchrled_dev*)filp->private_data;
	
	return 0;
}

static const struct file_operations newchrled_fops={
	.owner 	= THIS_MODULE,
	.write 	= newchrled_write,
	.open 	= newchrled_open,
	.release= newchrled_release,
};

/*入口*/
static int __init newchrled_init(void)
{
	int ret = 0;
	unsigned int val = 0;
	printk("newchrled_init\r\n");

/********新的字符设备注册方法,先创建设备号,再初始化cdev,再添加cdev***********/	
    /*注册字符设备*/
    /* 1、创建设备号 */
	newchrled.major=0; /*设置为0,表示由系统申请设备号*/
	if (newchrled.major)/*给定主设备号*/
	{
		newchrled.devid = MKDEV(newchrled.major,0);
		ret = register_chrdev_region(newchrled.devid, NEWCHRLED_COUNT, NEWCHRLED_NAME);
	}
	else				/*没有给定主设备号*/
	{
		ret = alloc_chrdev_region(&newchrled.devid,0, NEWCHRLED_COUNT,NEWCHRLED_NAME);
		newchrled.major =MAJOR(newchrled.devid);
		newchrled.minor =MINOR(newchrled.devid);
	}
	if(ret<0)
	{
		printk("newchrled chrdev_region err!\r\n");
		goto fail_devid;
	}
	printk("newchrled major = %d,minor=%d\r\n",newchrled.major,newchrled.minor);
	

	/* 2、初始化 cdev */
	newchrled.cdev.owner = THIS_MODULE;
    cdev_init(&newchrled.cdev,&newchrled_fops);

	/* 3、添加一个 cdev */
	ret= cdev_add(&newchrled.cdev, newchrled.devid, NEWCHRLED_COUNT);
	if(ret<0)
	{
		goto fail_cdev;
	}

/********加载驱动时,自动创建设备节点,先创建类,再创建设备***********/

	/* 4、创建类 */
	newchrled.class = class_create(THIS_MODULE,NEWCHRLED_NAME);
	if (IS_ERR(newchrled.class))
	{
		ret = PTR_ERR(newchrled.class);
		goto fail_class;
	}
		

	/*5.创建设备*/
	newchrled.device = device_create(newchrled.class, NULL,
			     newchrled.devid, NULL, NEWCHRLED_NAME);

	if (IS_ERR(newchrled.device))
	{
		ret=PTR_ERR(newchrled.device);
		goto fail_device;
	}

	return 0;

fail_device:
	class_destroy(newchrled.class);
fail_class:
	cdev_del(&newchrled.cdev);
fail_cdev:
	unregister_chrdev_region(newchrled.devid, NEWCHRLED_COUNT);
fail_devid:
	return ret;
}

/*出口函数*/
static void __exit newchrled_exit(void)
{
	unsigned int val = 0;

	/*1、删除字符设备*/
	cdev_del(&newchrled.cdev);

	/*2、注销设备号*/
	unregister_chrdev_region(newchrled.devid, NEWCHRLED_COUNT);

	/*3、摧毁设备*/
	device_destroy(newchrled.class, newchrled.devid);
	
	/*4、摧毁类*/
	class_destroy(newchrled.class);
}

/*注册和卸载驱动*/
module_init(newchrled_init);
module_exit(newchrled_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("supersmart");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值