关于驱动模块自动创建设备节点

驱动模块设备节点的自动创建,不再需要 mknod.


背景.

Linux 2.6 引入了动态设备管理, 用 udev 作为设备管理器(应用在x86), 相比之前的静态设备管理,在使用上更加方便灵活。
udev 根据 sysfs 系统提供的设备信息实现对/dev目录下设备节点的动态管理,包括设备节点的创建、删除等

引入 udev 自动创建设备节点后,比如在我们使用的 insmod led_drv.ko 时候,udev 自动帮我们在 /dev 目录下创建设备节点;
使用 rmmod led_drv 时候,udev 自动帮我们在 /dev 目录下删除设备节点;
这里并不需要我们再人为的mknod /dev/led_dev c 239 0 来生成为该设备在/dev目录下创建设备文件了。

如要编写一个能够使用 udev 管理的设备驱动,需要在驱动代码中调用 class_create() 为设备创建一个 class 类 ,再调用 device_create() 为每个设备创建对应的设备即可,从此告别需要繁琐的 mknod ....

根据源码解析.

设备类的申请等都在初始化函数中完成,故取前面的led_dev.c代码中的初始化函数来解析


static struct class  *led_class;
static struct device *led_dev_device;

    ...
    ...
    ...

//入口函数
static int __init gec6818_led_init(void)
{
    int ret = 0;
	ret=alloc_chrdev_region(&led_dev_num,0,1,"myled");    //动态申请设备号,这里的“myled”相当于代号,并不重要
    if (ret < 0)
    {
        printk("<3>""register chrdev region error\n");
        return -1;
    }
    
    //字符设备的初始化 void cdev_init(struct cdev *cdev, const struct file_operations *fops)
    cdev_init(&led_cdev, &led_fops);
    //将设备加入到内核 int cdev_add(struct cdev *p, dev_t dev, unsigned count)
    ret = cdev_add(&led_cdev, led_dev_num, 1);
    if(ret < 0)
    {
        printk("<3>""cdev_add error\n");
        goto err_cdev_add;

    }

    led_class=class_create(THIS_MODULE, "myled");   //这里的“myled”会显示在/sys/class目录当中

	if (IS_ERR(led_class))                  //判断当前指针是否为错误码指针,大于0为错误码指针
	{
		ret = PTR_ERR(led_class);           //将指针转为错误码
		
		printk("class_create led device fail\n");
		
		goto err_class_create;
		
	}

    led_dev_device = device_create(led_class, NULL, led_dev_num, NULL, "myled");//这里的“myled”是设备的名字,如果创建成功,就可以在/dev目录看到该设备的名字
    if (IS_ERR(led_dev_device))                 //创建设备失败
    {
        ret = PTR_ERR(led_dev_device);

        printk("device_create led fail\n");
        goto err_device_create;
    }

    printk("<3>""device num: %d\n", MAJOR(led_dev_num));
    printk("<3>""device last num: %d\n", MINOR(led_dev_num));

	return 0;


err_device_create:
    class_destroy(led_class);                   //创建led类失败,释放内存资源

err_class_create:
    cdev_del(&led_cdev);                        //从系统删除字符设备

err_cdev_add:
    unregister_chrdev_region(led_dev_num, 1);   //注销设备号

    return ret;
}


类的创建 class_create() 头文件: #include <linux/device.h>函数解析.

代码原型:
class_create()

参数作用
ownerclass的所有者,默认写THIS_MODULE
name自定义class的名字,会显示在/sys/class目录当中
返回值成功:就返回创建好的class指针,失败:就返回错误码指针

设备的创建 device_create() 头文件: #include <linux/device.h>

代码原型:
device_create()

参数作用
class创建device是属于哪个类
parent默认为NULL
devt设备号,设备号必须正确,因为这个函数会在/dev目录下帮我们自动创建设备文件
drvdata默认为NULL
fmt设备的名字,如果创建成功,就可以在/dev目录看到该设备的名字
返回值成功:就返回创建好的设备指针,失败:就返回错误码指针

类的销毁 class_destroy() 头文件: #include <linux/device.h>

代码原型:
class_destroy()

参数作用
class创建device是属于哪个类

设备的销毁 device_destroy() 头文件: #include <linux/device.h>

代码原型:
device_destroy()

参数作用
class创建device是属于哪个类
devt设备号

错误码.

错误码指针的判断

static inline long __must_check IS_ERR(const void *ptr)
{
	return IS_ERR_VALUE((unsigned long)ptr);
}


将错误码指针转换为数值(即错误码)

static inline long __must_check PTR_ERR(const void *ptr)
{
	return (long) ptr; 
}

 


我的GITHUB

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大棋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值