Linux字符设备驱动基础(四)
7 Linux字符设备驱动注册示例
static int __init chardev_driver_test_init(void)
{
int ret;
int major = 126;
int minor = 0;
struct cdev chardev_test;
struct class *test_class;
dev_t devno = MKDEV(major, minor);
//第一步:申请字符设备号
//注册的字符设备:在/proc/devices中查看到设备号
if (major) {
//静态申请字符设备号,文件操作集后有描述
ret = register_chrdev(major, "chardev_test", &chardev_test_fops);
if (IS_ERR(ret)) {
printk(KERN_ERR "static register chardev-%d err:%d\n", major, ret);
return ret;
}
} else {
//动态申请字符设备号
ret = alloc_chrdev_region(&devno, 0, 1, "chardev_test");
if (IS_ERR(ret)) {
printk(KERN_ERR "alloc register chardev err:%d\n", ret);
return ret;
}
major = MAJOR(devno);
minor = MINOR(devno);
//初始化字符设备及添加字符设备的文件操作集(后有描述)
cdev_init(&chardev_test, &chardev_test_ops);
ret = cdev_add(&chardev_test, MKDEV(major, minor), 1);
if (IS_ERR(ret)) {
printk(KERN_ERR "add chardev-%d test failed:%d\n", devno, ret);
goto unregister_chrdev;
}
}
//第二步:创建设备类,在sys/class/创建“chardev_test”目录
test_class = class_create(THIS_MODULE, "chardev_test");
if (IS_ERR(test_class)) {
ret = PTR_ERR(test_class);
goto cdev_del;
}
//第三步:在/dev下自动创建设备节点"chardev_test"
struct device *dev = device_create(test_class, &pdev->dev,
MKDEV(major, minor), NULL,
"chardev_test");
if (IS_ERR(dev)) {
ret = PTR_ERR(dev);
goto class_destroy;
}
printk(KERN_INFO "chardev_add success\n");
return 0;
class_destroy:
class_destroy(test_class);
cdev_del:
cdev_del(&chardev_test);
unregister_chrdev:
unregister_chrdev(major, "chardev_test");
return ret;
}
static void __exit chardev_driver_test_exit(void)
{
//先删除设备,再删除类
device_destroy(test_class, devno);
class_destroy(test_class);
unregister_chrdev(major, "chardev_test"); //注销设备号
printk(KERN_ALERT "chardev_test_exit\r\n")
}