当前位置: 首页 > 图灵资讯 > 技术篇> Linux设备文件自动生成

Linux设备文件自动生成

来源:图灵教育
时间:2023-06-07 09:44:30

一是使用mknod手工创建:# mknod <devfilename> <devtype> <major> <minor>

二是自动创建设备节点:使用udev(mdev)要实现设备文件的自动创建,首先要保证支持udev(mdev),busybox配置。

这里不详细阐述udev的具体知识,可以移动Linux 文件系统和设备文件系统 —— udev 本文主要介绍设备文件系统的使用方法。

添加到驱动程序中的udev 支持的主要方法是在驱动初始化代码中调用class_create(...)为设备创建class,然后为每个设备调用device_create(...)创建相应的设备。

Struct定义在内核中 顾名思义,class结构体是struct class结构体类型变量对应一个类,内核还提供class_create(..)函数,可以用来创建一个类,存储在sysfs下面,一旦创建了这个类,再调用 device_create(..)函数在/dev目录下创建相应的设备节点。

这样,在加载模块时,用户空间中的UDEV会自动响应 device_create()函数,去/sysfs下寻找相应的类,从而创建设备节点。

以下是两个函数的分析:

支持自动生成linux/字符设备文件device.h

struct class *class_create(struct module *owner, const char *name);/*  功能:在/sys在class目录下创建一个目录,目录名是name指定的  参数:    struct module *owner - THIS_MODULE    const char *name - 设备名  返回值:    成功:class指针:class指针    失败: - bool IS_ERR(const void *ptr)  判断是否有错误         long PTR_ERR(const void *ptr)  转换错误码*//转换错误码
void class_destroy(struct class *cls);/*  功能:删除class指针指向的目录  参数:    struct class *cls - class指针*/
struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);/*   功能:    在class指针指向的目录下创建另一个目录,目录名称const char *fmt, ...指出并导出设备信息(dev_t)  参数:    struct class *cls - class指针    struct device *parent - 父对象,NULL    dev_t devt - 设备号    void *drvdata - 驱动私有数据    const char *fmt, ... - fmt是目录名字符串格式,...是不确定的参数  返回值:    成功 - device指针    失败 - bool IS_ERR(const void *ptr)  判断是否有错误       long PTR_ERR(const void *ptr)   转换错误码*//转换错误码
void device_destroy(struct class *cls, dev_t devt);/*  功能:删除device_create创建的目录  参数:    struct class *cls - class指针    dev_t devt - 设备号*/

structtt创建顺序 class *class_create(struct module *owner, const char *name);struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata,const char *fmt, ...);删除次序void device_destroy(struct class *cls, dev_t devt);void class_destroy(struct class *cls);

实例:

#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/cdev.h>#include <linux/fs.h>#include <linux/errno.h>#include <asm/current.h>#include <linux/sched.h>#include <linux/device.h>MODULE_LICENSE("GPL");static struct class *cls = NULL;static int major = 0;static int minor = 0;const  int count = 6;#define DEVNAME    "demo"static struct cdev *demop = NULL;///打开设备staticc打开设备 int demo_open(struct inode *inode, struct file *filp){    //get command and pid    printk(KERN_INFO "%s : %s : %d\n", __FILE__, __func__, __LINE__);return 0;}///关闭设备staticcc int demo_release(struct inode *inode, struct file *filp){    //get major and minor from inode    printk(KERN_INFO "%s : %s : %d\n", __FILE__, __func__, __LINE__);    return 0;}static struct file_operations fops = {    .owner    = THIS_MODULE,    .open    = demo_open,    .release= demo_release,};static int __init demo_init(void){    dev_t devnum;    int ret, i;    struct device *devp = NULL;    //1. alloc cdev obj    demop = cdev_alloc();    if(NULL == demop){        return -ENOMEM;    }    //2. init cdev obj    cdev_init(demop, &fops);    ret = alloc_chrdev_region(&devnum, minor, count, DEVNAME);    if(ret){        goto ERR_STEP;    }    major = MAJOR(devnum);    //3. register cdev obj    ret = cdev_add(demop, devnum, count);    if(ret){        goto ERR_STEP1;    }    cls = class_create(THIS_MODULE, DEVNAME);    if(IS_ERR(cls)){        ret = PTR_ERR(cls);        goto ERR_STEP1;    }    for(i = minor; i < (count+minor); i++){        devp = device_create(cls, NULL, MKDEV(major, i), NULL, "%s%d", DEVNAME, i);        if(IS_ERR(devp)){            ret = PTR_ERR(devp);            goto ERR_STEP2;        }    }    return 0;ERR_STEP2:    for(--i; i >= minor; i--){        device_destroy(cls, MKDEV(major, i));    }    class_destroy(cls);ERR_STEP1:    unregister_chrdev_region(devnum, count);ERR_STEP:    cdev_del(demop);    //get command and pid    printk(KERN_INFO "%s : %s : %d - fail.\n", __FILE__, __func__, __LINE__);    return ret;}static void __exit demo_exit(void){    int i;    //get command and pid    printk(KERN_INFO "%s : %s : %d - leave.\n", __FILE__, __func__, __LINE__);    for(i=minor; i < (count+minor); i++){        device_destroy(cls, MKDEV(major, i));    }    class_destroy(cls);    unregister_chrdev_region(MKDEV(major, minor), count);    cdev_del(demop);}module_init(demo_init);module_exit(demo_exit);