Linux设备文件自动生成

第一种是使用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指针
    失败: - 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 - 设备号
*/

创建次序
struct 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;

//打开设备
static 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;
}

//关闭设备
static 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);

下面可以看几个class几个名字的对应关系:

时间: 2024-10-10 13:13:03

Linux设备文件自动生成的相关文章

[Linux: vim]vim自动生成html代码

如果直接将vim编辑的文字复制粘贴到一些blog的编辑器中,这些代码将会是死板的白纸黑字.如果能加入关键字高亮功能就好了,这样代码阅读起来会很方便.一些blog的编辑器提供了这项功能,一些没有,一些支持的语言不够全面.好在vim的syntax支持的语言够多,绝大部分流行的语言都可以直接找到支持.如果能将vim显示的代码直接转换成为html就好多了,这样很多支持HTML编辑的blog就可以直接使用格式化好的代码. 使用vim将代码转换为html有两种方式,TOhtml和syntax/2html.v

Linux下PHP自动生成文章预览图,html转换成各种格式图片、PDF-----转自phpboy的文章

原文地址:http://www.phpboy.net/linux/575.html 用WordPress建立博客站点,选择了一套可以显示文章缩略图的模板,几经折腾将原有模板改得面目全非,最后还是直接上线吧,不想折腾了. 站点上线没几天,在公司做项目时,对图片做了一个放大的JS,自己博客也加上点击缩略图查看原图的功能,然后迅速的加了. 过了几天,突发奇想,想做文章预览图,即点击缩略图查看文章预览图,也就是你们现在首页和文章列表页看到的那个功能. 不费话了,不知道什么时候又要折腾... Linux下

CCS 6新建文件自动生成注释

对于CCS6,可以通过配置,达到新建源文件或者头文件时,自动生成适当的注释: 一.新建源文件自动生成配置. 在某个文件夹下右击选择 New - Source File. 点击 Configure,再选择对应的语言,然后点击Edit. 此时就出现了一个可编辑的模版.适当的配置模版,保存.可以参考下列程序: 1 /**************************************************************** 2 @版权 : 个人开发,禁止用于商业用途 3 @文件名

【Android】Android Layout Binder——根据layout布局文件自动生成findViewById的java代码的神器

Android Layout Binder是一个网站,能够在线的根据layout布局文件自动生成findViewById的java代码. 网址是http://android.lineten.net/layout.php 如图:

使用 udev 管理 Linux 设备文件

本文以通俗的方法阐述 udev 及相关术语的概念.udev 的配置文件和规则文件,然后以 Red Hat Enterprise Server 为平台演示一些管理设备文件和查询设备信息的实例.本文会使那些需要高效地.方便地管理 Linux 设备的用户受益匪浅,这些用户包括 Linux 最终用户.设备驱动开发人员.设备测试人员和系统管理员等等. 概述: Linux 用户常常会很难鉴别同一类型的设备名,比如 eth0, eth1, sda, sdb 等等.通过观察这些设备的内核设备名称,用户通常能知道

【Java】Eclipse新建的Java文件自动生成主函数、控制台输出行数不再受限制

一.新建的Java文件自动生成主函数 虽然只是一个很简单的事情,但应该还是有人不知道了,每次新建Java文件都要手动输入public static void main(String args[]){},非常麻烦,其实Eclipse可以自动生成这行,只是大多数的Java文件都是没有主函数的,所以这行默认关闭, 右击Java项目下的src可以选择New->Class也就可以新建类 然后在弹出的对话框上勾上自动产生主函数,点击确认,在生产的Java文件中就有主函数了 二.Eclipse控制台输出行数不

【Latex】Latex小白入门(2)——如何用.bib文件自动生成论文Reference

写在前面: 在研究生阶段搞学术的童鞋们很有可能会接触到Latex这种论文格式编辑工具,一般在论文投稿的时候,大多数期刊和会议会给一个Latex模板,要求将你的论文用Latex编辑成.pdf版本.这里的Latex小白可不是指各位读者,而是我自己.才开始用Latex的时候,team里面唯一会Latex的师姐已经毕业say goodbye了,而我连怎么编译运行都不会.无奈论文要投,只好"赶鸭子上架",秉承"哪里不会查哪里"的精神,完成了几次论文从word到Latex的移植

Linux设备文件简介(转载)

Linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取).块设备(有缓冲且可以随机存取).每个字符设备和块设备都必须有主.次设备号,主设备号相同的设 备是同类设备(使用同一个驱动程序).这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的物理硬件, 又称为"虚拟设备").每个设备在 /dev 目录下都有一个对应的文件(节点).可以通过 cat /proc/devices 命令查看当前已经加载的设备驱动程序的主设备号.内核能够识别的所

Linux 设备文件简介

概述 设备管理是 Linux 中比较基础的知识,与内核的关系也比较密切.随着 Udev 的广泛使用,Linux 发行版的智能程度越来越高,许多 Linux 新用户对 /dev 目录下的东西变得不再熟悉,有时候遇见问题就会抓狂. Linux 中的设备按照存取方式的不同,可以分为两种: 字符设备 无缓冲且只能顺序存取 块设备 有缓冲且可以随机(乱序)存取 而按照是否对应物理实体,也可以分为两种: 物理设备 对实际存在的物理硬件的抽象 虚拟设备 不依赖于特定的物理硬件,仅是内核自身提供的某种功能 无论