精华内容
下载资源
问答
  • linux驱动:自动创建设备节点

    千次阅读 2018-11-03 09:05:28
    在加载驱动模块后,就要自己使用mknod创建设备节点,这样虽然是可行的,但是比较麻烦。我们可以在__init()函数里面添加一些函数,自动创建设备节点创建设备节点使用了两个函数 class_create()和device_create(),...

    在加载驱动模块后,就要自己使用mknod创建设备节点,这样虽然是可行的,但是比较麻烦。我们可以在__init()函数里面添加一些函数,自动创建设备节点。创建设备节点使用了两个函数 class_create()和device_create(),当然在__exit()函数里,要使用class_destory()和device_desotry()注销创建的设备节点。

     

    1. 函数说明

    struct device *device_create(struct class *class, struct device *parent,
    dev_t devt, const char *fmt, ...)
    
    struct device *device_create(struct class *class, struct device *parent,
    dev_t devt, void *drvdata, const char *fmt, ...)

    在驱动用加入对udev的支持主要做的就是:在驱动初始化的代码里调用class_create(...)为该设备创建一个class,再为每个设备调用device_create(...)( 在2.6较早的内核中用class_device_create)创建对应的设备。

    内核中定义的struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。

     

    2. 具体用法

    需要包含头文件 #include <linux/device.h>    

    static int led_init()
    {
    
        major = register_chrdev(0, "led_drv", &led_fops);
        led_drv_class = class_create("THIS_MODULE", "led_drv");
        device_create(led_drv_class, NULL, MKDEV(major, 0), NULL, "myled");
    
        return 0;
    
    }
    
    
    
    static void led_exit()
    {
    
        unregister_chrdev(major, "led_drv");
        device_destroy(led_drv_class, MKDEV(major, 0));
        class_destroy(led_drv_class);
    
    }

     

    在驱动初始化的代码里调用class_create为该设备创建一个class,再为每个设备调用 device_create创建对应的设备。

    加载模块后,会自动在/dev/下创建myled设备文件。

     

    展开全文
  • 2.自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置。在驱动用加入对udev 的支持主要做的就是:在驱动初始化的代码里调用class_create

    利用cat /proc/devices查看申请到的设备名,设备号。
    创建设备节点
    1.使用mknod手工创建:mknod filename type major minor
    2.自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置。

    在驱动用加入对udev 的支持主要做的就是:在驱动初始化的代码里调用class_create(…)为该设备创建一个class,再为每个设备调用device_create(…)创建对应的设备。
    内核中定义的struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。
    这样,加载模块的时候,用户空间中的udev会自动响应 device_create()函数,去/sysfs下寻找对应的类从而创建设备节点。

    下面是两个函数的解析:
    1、class_create(…) 函数
    功能:创建一个类;
    内核源码:

    #define class_create(owner, name)       \
    ({                      \
        static struct lock_class_key __key; \
        __class_create(owner, name, &__key);    \
    })

    owner:THIS_MODULE
    name : 类名字
    2.设备类的销毁函数

    void class_destroy(struct class *cls)
    {
        if ((cls == NULL) || (IS_ERR(cls)))
            return;
    
        class_unregister(cls);
    }

    2.device_create(…) 函数
    struct device *device_create(struct class *class, struct device *parent,
    dev_t devt, void *drvdata, const char *fmt, …)
    {
    va_list vargs;
    struct device *dev;

    va_start(vargs, fmt);
    dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
    va_end(vargs);
    return dev;
    }
    功能:创建一个字符设备文件
    参数:
    struct class *class :类
    struct device *parent:NULL
    dev_t devt :设备号
    void *drvdata :null、
    const char *fmt :名字
    返回:
    struct device *

    代码示例

    #include <linux/module.h>  
    #include <linux/fs.h>  
    #include <linux/cdev.h>  
    #include <linux/device.h>  
    
    static int major = 250;  
    static int minor=0;  
    static dev_t devno;  
    static struct class *cls;  
    static struct device *test_device;  
    
    static int hello_open (struct inode *inode, struct file *filep)  
    {  
        printk("hello_open \n");  
        return 0;  
    }  
    static struct file_operations hello_ops=  
    {  
        .open = hello_open,  
    };  
    
    static int hello_init(void)  
    {  
        int ret;      
        printk("hello_init \n");  
    
    
        devno = MKDEV(major,minor);  
        ret = register_chrdev(major,"hello",&hello_ops);  
    
        cls = class_create(THIS_MODULE, "myclass");  
        if(IS_ERR(cls))  
        {  
            unregister_chrdev(major,"hello");  
            return -EBUSY;  
        }  
        test_device = device_create(cls,NULL,devno,NULL,"hello");//mknod /dev/hello  
        if(IS_ERR(test_device))  
        {  
            class_destroy(cls);  
            unregister_chrdev(major,"hello");  
            return -EBUSY;  
        }     
        return 0;  
    }  
    static void hello_exit(void)  
    {  
        device_destroy(cls,devno);  
        class_destroy(cls);   
        unregister_chrdev(major,"hello");  
        printk("hello_exit \n");  
    }  
    MODULE_LICENSE("GPL");  
    module_init(hello_init);  
    module_exit(hello_exit);  
    展开全文
  • 在写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点, 实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点, 并在卸载模块时删除该节点,当然...
    设备节点的自动创建
    
    在写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,
    实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,
    并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。
    内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,
    内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,
    一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。
    这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
    通过device_destroy();class_destroy();来注销类和节点
    展开全文
  • Linux 驱动创建设备节点的方式

    千次阅读 2019-02-03 20:04:37
    在编写新需求时,要求底层提供节点给上层调用,这里我总结的三种Linux下如何创建设备节点的方法,而创建设备节点调用的函数都是Linux内核里面提供的函数接口,我们只需要调用这些函数接口去创建节点即可。...

      最近在学习Android下的LCD模块,在编写新需求时,要求底层提供节点给上层调用,这里我总结的三种Linux下如何创建设备节点的方法,而创建设备节点调用的函数都是Linux内核里面提供的函数接口,我们只需要调用这些函数接口去创建节点即可。

    1. /sys/class/下面某个目录下创建hello这个节点,可以通过调用以下函数:
    示例:static DEVICE_ATTR(hello, S_IRUGO | S_IWUSR, hello_read, hello_wirte);

    第一个参数:要创建的节点名字;
    第二个参数:创建节点的权限;
    第三个参数:向/sys/class/xxx/hello节点读取数据的时候,调用这个函数指针参数(读函数名称);
    第四个参数:向/sys/class/xxx/hello节点写入数据的时候,调用这个函数指针参数(写函数名称);

    具体说明在在documentation/driver-model/Device.txt中;

    #define DEVICE_ATTR(_name, _mode, _show, _store) \
    struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
    dev_attr_##_name!!!!!
    
    #define __ATTR(_name,_mode,_show,_store) { \
     .attr = {.name = __stringify(_name), .mode = _mode }, \
     .show = _show,     \
     .store = _store,     \
    }
    
    device_attribute定义:
    struct device_attribute {
     struct attribute attr;
     ssize_t (*show)(struct device *dev, struct device_attribute *attr,
       char *buf);
     ssize_t (*store)(struct device *dev, struct device_attribute *attr,
        const char *buf, size_t count);
    };
    
    ​

    2. /proc目录下创建文件节点,可调用内核中的创建函数:
    示例:struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops)
    name: 表示要创建的节点名字;
    mode: 表示创建节点的权限;
    parent: 父entry,为NULL的话,默认父entry是/proc;
    proc_fops:表示对这个文件节点进行读写操作的函数的结构体;

    踩过的坑经验:

    (1). 在对proc_fops结构体里面的读写函数,进行实现的时候,写函数的返回值必须是写入的字节数,否者内核一直循环的去写这个值;

    (2). 同时在编写驱动文件对应的文件操作函数时,在添加打印信息时,一定不能把用户空间的字符串用在内核空间打印,否则会导致Linux系统在加载这个函数时,系统崩溃;

    (3). 在这里额文件操作函数要注意传参,buf数据都是用户空间的,要加__user去修饰变量,这个和编写一个简单的字符设备驱动对应的读写函数传的参是一样的,要使用copy_to_user()和copy_from_user()宏进行内核空间和用户空间数据的交互;

    static inline struct proc_dir_entry *proc_create(
        const char *name, umode_t mode, struct proc_dir_entry *parent,
        const struct file_operations *proc_fops)
    {
        return proc_create_data(name, mode, parent, proc_fops, NULL);
    }
    ​
    struct file_operations {
    	struct module *owner;
    	loff_t (*llseek) (struct file *, loff_t, int);
    	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    	int (*open) (struct inode *, struct file *);
    	int (*release) (struct inode *, struct file *);
            ...
            ...
    };
    
    ​

    3. 调用内核函数sysfs_create_file(struct kobject *hellowold_kobj, struct kobj_attribute hello_value_attribute); 去创建文件节点,节点对应的读写函数,分别为show(),store()函数;

    而show()函数和store()函数的注册实在 struct kobj_attribute hello_value_attribute结构体中;

    struct kobj_attribute {
    	struct attribute attr;
    	ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
    			char *buf);
    	ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
    			 const char *buf, size_t count);
    };

    大家可以看到show()函数和store()函数中的参数buf前面没有__user的修饰符,证明buf存放的数据是用户空间的数据,所以我们这个时候不能调用copy_to_user()和copy_from_user()宏了,可以使用snprintf()函数和sscanf()函数,来进行操作数据,把要读取的数据和写入的数据传递给新的变量,然后去操作这个新的内核变量,而buf这个变量数据内核会对它进行操作改变,我们不需要关心这个,因为我们只是在调用内核函数接口,剩下的内核会帮助我们去处理。如果你想弄懂内核的机制,你可以追内核源代码。

    在show函数中,要调用snprintf()函数,把内核空间的数据放到用户空间去;
    在store函数中,要调用sscanf()函数,把用户空间的数据放到内核空间去;
     sprintf和sscanf类似与对copy_from_user和copy_to_user函数的封装。

     

    最后,如果大家对每一种创建节点的方式要了解的更清楚一下,可以猛戳一下链接:

    1、https://blog.csdn.net/njuitjf/article/details/16849333

    2、https://www.cnblogs.com/ck1020/p/7475729.html

    3、https://blog.csdn.net/yj4231/article/details/7799245

    展开全文
  • Linux驱动】自动创建设备节点

    千次阅读 2014-06-29 00:54:02
    开始学习驱动的时候,是将驱动程序编译成...这时就不能再手动的建立设备节点了,而必须自动的创建设备节点(不需要人为的操作)。 ★注册类 注册类的目的是为了使mdev可以在/dev/目录下建立设备节点。 首先要定义一个类
  • 字符设备是一种以字节流来存取的设备,查看正在使用的设备驱动可用命令:cat /proc/devices;字符设备文件第一个为c开头,可使用命令:ls –l /dev/* 如下图示: 在老版的Linux内核中,注册一个Linux字符设备需要...
  • Linux驱动模块自动创建设备节点

    千次阅读 2013-07-09 11:24:06
    在宋宝华《Linux设备驱动开发详解》中我们能找到如下描述: devfs与udev的另一个显著区别在于:采用devfs,当一个并不存在的/dev节点被打开的时候,devfs能自动加载对应的驱动,而udev则不能。这是因为 udev的设计者...
  • Linux内核驱动自动创建设备节点文件 (2012-06-16 10:06) 标签: 转载  原文地址:Linux内核驱动自动创建设备节点文件 作者:xgqsa Linux下生成驱动设备节点文件的方法有3个:1、手动mknod;2、...
  • 在做linux混杂设备驱动的时候想要通过class_creat,device_creat来自动创建设备节点,但是在加载驱动的时候报错了。 后来仔细检查发现在misc_register注册混杂设备驱动的时候里面调用了device_creat来自动创建设备...
  • 本文简述在linux字符设备驱动编程中自动创建设备节点。至于手动创建设备节点的编程
  • 创建设备节点/sys/class/drm/card0-DSI-1/disp_param static ssize_t disp_param_store(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct drm_...
  • linux驱动设备号与创建设备节点

    千次阅读 2014-12-18 21:50:18
    设备号: 1、自动分配 major = register_chrdev(0,"first_drv",&first_sdv_fops);... 注册设备时给设备号写0,则内核会自动分配一个主设备号返回。...应用程序设备节点: 我们会使用open这个函数带开一个设备,那么o
  • Linux字符设备驱动自动创建设备节点

    千次阅读 2016-11-29 14:38:46
    Linux可使用udev、mdev的机制来自动创建设备节点。在驱动层面,我们需要首先调用class_create创建一个class类,然后在class类下,调用device_create来创建一个class_device,即类下面创建类的设备。(此方法仅适用于...
  • Linux设备驱动实现自动创建设备节点

    千次阅读 2014-08-24 13:45:54
    /*创建设备节点/sys/class/xxx和/dev/xxx*/ xxx_class = class_create(THIS_MODULE, DRIVERNAME); if (IS_ERR(xxx_class)) { ret = PTR_ERR(xxx_class); goto class_err; } device_create(xxx_class, ...
  • Linux字符设备驱动(三)自动创建设备节点 在前面的字符设备中需要手动运行mknod创建设备节点,但其实linux中可以通过udev自动创建设备节点,通过下面两步即可实现。 class_createdevice_create struct class *class...
  • 上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。...答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。问:文件系统里,
  • linux 自动创建设备节点

    千次阅读 2014-01-24 11:12:02
    最近在看一个MISC的设备驱动,看到这样一句: misc->this_device = device_create(misc_class, misc->parent, dev, misc, "%s", misc->name); 其中: struct miscdevice * misc; struct device *this_device...
  • 上一篇我们介绍到创建设备文件的方法,...第二种是自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置。在驱动初始化代码里调用class_create为该设备创建一个
  • 区分上节内容,手动创建设备节点: mknod 文件名 类型 主设备号 次设备号 怎样查看系统设备节点,在project window中查找major.h就行 自动创建设备节点的方法 #define MINORBITS20 #define MINORMASK((1U ...
  • 详细教程参考文章https://blog.csdn.net/szm1234/article/details/113615535
  • extern struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *... 函数device_create()用于动态的建立逻辑设备,并对新的逻辑设备类进行相应初始化,将其与函数的第一个参
  • Linux设备节点设备设备驱动

    千次阅读 2017-09-15 14:44:38
    Linux设备分成三种基本类型: ...在Linux中,所有设备都以文件的形式存放在/dev目录下,都是通过文件的方式进行访问,设备节点Linux内核对设备的抽象,一个设备节点就是一个文件。应用程序通过一组

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,142
精华内容 28,456
关键字:

linux驱动建立设备节点

linux 订阅