驱动开发(万金油创建字符设备my_cdev并初始化)

主要函数为my_cdev_init(),驱动启动部分可能不全

struct cdev {
	struct kobject kobj;					// 内嵌的内核对象.
	struct module *owner;				    //该字符设备所在的内核模块的对象指针.
	const struct file_operations *ops;	    //该结构描述了字符设备所能实现的方法,即file_operations.
	struct list_head list;                 //用来将已经向内核注册的所有字符设备形成链表.
	dev_t dev;					            //字符设备的设备号,由主设备号和次设备号构成.
	unsigned int count;                     //隶属于同一主设备号的次设备号的个数.
} __randomize_layout;
=
struct my_cdev
{
	int major;
	dev_t cdevno;
	struct cdev cdev;
	struct device* sys_device;
	struct class *class;
	
};
struct my_cdev g_my_cdev;

static const struct file_operations my_cdev_fops = {
	.owner = THIS_MODULE,
	.open  = my_open,
	.release = my_close,
	.read = my_read,
	.write = my_write,
};


int my_cdev_init()
{
	struct my_cdev* cdev = &g_my_cdev;
	dev_t dev;
	
	if(cdev->sys_device)
	{
		return 0;
	}
	if(!cdev->major)
	{
		/*动态分配设备号*/
		if(alloc_chrdev_region(&dev, 0, 255, "my_dev"))
		{
			printk("alloc_chrdev_region failed\n");
		}	
		cdev->major = MAJOR(dev); /*dev:   0e f0 00 00*/
							/*cdev->major: 00 00 00 ef*/
	}
	
	cdev->cdev.owner = THIS_MODULE;
		
	if(kobject_set_name(&cdev->cdev.kobj, "cdev") < 0)
	{
		printk("cdev_add failed\n");
		goto unregister_region;
	}
	cdev->cdevno = MKDEV(cdev->major,1);/*cdev->cdevno : 0e f0 00 01*/
	

	cdev_init(&cdev->cdev, &my_cdev_fops);
	
	/*加入到内核结构体cdev_map设备列表中*/
	if(cdev_add(&cdev->cdev, cdev->cdevno, 1) < 0)
	{
		printk("cdev_add failed\n");
		goto unregister_region;
	}
	
	/*在/sys/class下创建一个新的文件夹,名字叫my_dev,也可以说创建一个逻辑类*/
	cdev->class = class_create(THIS_MODULE, "my_dev");
	if(IS_ERR(cdev->class))
	{
		return -1;
	}
	if(cdev->class)
	{
		/*类生成之后,在/dev创建一个新的设备节点*/
		cdev->sys_device = device_create(cdev->class, NULL, cdev->cdevno, NULL ,"cdev");
	}	
	return 0;
unregister_region:
	unregister_chrdev_region(dev, 255);
	return -1;
}
int my_cdev_exit(void)
{
	struct my_cdev *dev = &g_my_cdev;
	if(NULL == cdev->sys_device)
	{
		return 0;
	}
	if(cdev->sys_device)
	{
		device_destory(cdev->class, cdev->cdevno);
		cdev->sys_device = NULL;
	}
	if(cdev->class)
	{
		class_destroy(cdev->class);
	}
	
	cdev_del(&cdev->cdev);

	if(cdev->major)
	{
		unregister_chrdev_region(MKDEV(cdev->major,0), 255);
	}
	return 0;
}


static int __init mod_init(void)
{
	int ret = 0;
	/*初始化控制部分*/
	my_cdev_init();
	
	return pci_register_driver(&pci_driver);/*struct pci_driver pci_driver*/
}

static void __exit mod_exit(void)
{
	pci_unregister_driver(&pci_driver);
	my_cdev_exit();
}


module_init(mod_init);
module_exit(mod_exit);

注意alloc_chrdev_region()中的名字要和class_create()中名字一致,否则rmmod时候会kill掉,device_destory()会报错

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值