字符设备注册/注销

字符设备注册步骤:

1.分配cdev结构体

2.分配设备号,register_chrdev_region()/alloc_chrdev_region();

3.添加设备到系统,cdev_add();

字符设备注销步骤:

1. 从系统中删除设备,cdev_del();

2. 释放设备号,unregister_chrdev_region();

除了以上按步骤注册/注销字符设备外,系统也提供了函数直接完成设备的注册与注销。

 1 /**
 2  * __register_chrdev() - create and register a cdev occupying a range of minors
 3  * @major: major device number or 0 for dynamic allocation
 4  * @baseminor: first of the requested range of minor numbers
 5  * @count: the number of minor numbers required
 6  * @name: name of this range of devices
 7  * @fops: file operations associated with this devices
 8  *
 9  * If @major == 0 this functions will dynamically allocate a major and return
10  * its number.
11  *
12  * If @major > 0 this function will attempt to reserve a device with the given
13  * major number and will return zero on success.
14  *
15  * Returns a -ve errno on failure.
16  *
17  * The name of this device has nothing to do with the name of the device in
18  * /dev. It only helps to keep track of the different owners of devices. If
19  * your module name has only one type of devices it's ok to use e.g. the name
20  * of the module here.
21  */
22 int __register_chrdev(unsigned int major, unsigned int baseminor,
23               unsigned int count, const char *name,
24               const struct file_operations *fops)
25 {
26     struct char_device_struct *cd;
27     struct cdev *cdev;
28     int err = -ENOMEM;
29 
30     cd = __register_chrdev_region(major, baseminor, count, name);
31     if (IS_ERR(cd))
32         return PTR_ERR(cd);
33     
34     cdev = cdev_alloc();
35     if (!cdev)
36         goto out2;
37 
38     cdev->owner = fops->owner;
39     cdev->ops = fops;
40     kobject_set_name(&cdev->kobj, "%s", name);
41         
42     err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);
43     if (err)
44         goto out;
45 
46     cd->cdev = cdev;
47 
48     return major ? 0 : cd->major;
49 out:
50     kobject_put(&cdev->kobj);
51 out2:
52     kfree(__unregister_chrdev_region(cd->major, baseminor, count));
53     return err;
54 }
55 static inline int register_chrdev(unsigned int major, const char *name,
56                   const struct file_operations *fops)
57 {
58     return __register_chrdev(major, 0, 256, name, fops);
59 }
register_chrdev()
 1 /**
 2  * __unregister_chrdev - unregister and destroy a cdev
 3  * @major: major device number
 4  * @baseminor: first of the range of minor numbers
 5  * @count: the number of minor numbers this cdev is occupying
 6  * @name: name of this range of devices
 7  *
 8  * Unregister and destroy the cdev occupying the region described by
 9  * @major, @baseminor and @count.  This function undoes what
10  * __register_chrdev() did.
11  */
12 void __unregister_chrdev(unsigned int major, unsigned int baseminor,
13              unsigned int count, const char *name)
14 {
15     struct char_device_struct *cd;
16 
17     cd = __unregister_chrdev_region(major, baseminor, count);
18     if (cd && cd->cdev)
19         cdev_del(cd->cdev);
20     kfree(cd);
21 }
22 static inline void unregister_chrdev(unsigned int major, const char *name)
23 {
24     __unregister_chrdev(major, 0, 256, name);
25 }
unregister_chrdev()
原文地址:https://www.cnblogs.com/yangjiguang/p/6034851.html