源代码
alloc_chrdev_region与register_chrdev_region的区别在于,
前者不知道主设备号,由操作系统自动分配
后者由人工设置主设备号!!
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h> // kfree,kmalloc
#include <linux/cdev.h> // cdev_xxx
#include <linux/device.h> // device_xxx
static dev_t g_simple_cdev_dev_no;
static struct cdev *g_simple_cdev;
static struct class *g_simple_cdev_class;
static struct device *g_simple_cdev_device;
static int simple_cdev_open(struct inode *inode, struct file *file)
{
return 0;
}
static int simple_cdev_release(struct inode *inode, struct file *file)
{
return 0;
}
/* File operations struct for character device */
static const struct file_operations g_simple_cdev_fops = {
.owner = THIS_MODULE,
.open = simple_cdev_open,
.release = simple_cdev_release,
};
static int __init simple_cdev_init(void)
{
int ret;
ret = alloc_chrdev_region(&g_simple_cdev_dev_no, 0, 1, "simple_cdev");
if (ret < 0) {
return ret;
}
g_simple_cdev = cdev_alloc();
if (g_simple_cdev == NULL) {
return -1;
}
g_simple_cdev->owner = THIS_MODULE;
g_simple_cdev->ops = &g_simple_cdev_fops;
ret = cdev_add(g_simple_cdev, g_simple_cdev_dev_no, 1);
if (ret < 0) {
return ret;
}
g_simple_cdev_class = class_create(THIS_MODULE, "simple_cdev");
g_simple_cdev_device = device_create(g_simple_cdev_class, NULL, g_simple_cdev_dev_no, NULL, "simple_cdev");
return 0;
}
static void __exit simple_cdev_exit(void)
{
device_destroy(g_simple_cdev_class, g_simple_cdev_dev_no);
class_destroy(g_simple_cdev_class);
cdev_del(g_simple_cdev);
unregister_chrdev_region(g_simple_cdev_dev_no, 1);
}
MODULE_LICENSE("GPL");
module_init(simple_cdev_init);
module_exit(simple_cdev_exit);