zoukankan      html  css  js  c++  java
  • Linux设备文件的创建

    /************************************************************************************

    *本文为个人学习记录,如有错误,欢迎指正。

    *本文参考资料: 

    *        http://www.cnblogs.com/chen-farsight/p/6154941.html

    *        https://blog.csdn.net/yueqian_scut/article/details/46771595

    ************************************************************************************/

    1. 创建设备文件的两种方式

    (1)手动创建:mknod命令

    在驱动程序insmod成功之后,通过mknod命令手动创建设备文件至/dev目录下:mknod /dev/xxx  c  主设备号 次设备号。("c"表示字符设备、"b"表示块设备、"p"表示网络设备)

    (2)自动创建设备文件:mdev

    在设备驱动注册到系统后,调用class_create为该设备在/sys/class目录下创建一个设备类,再调用device_create函数为每个设备创建对应的设备,并通过uevent机制调用mdev(嵌入式linux由busybox提供)来调用mknod创建设备文件至/dev目录下。

    2. 自动创建设备文件过程分析

    2.1 相关数据结构

    struct class和struct device则通过sysfs向用户层提供信息。

     class_private是class的私有结构,class通过class_private注册到系统中;device_private是device的私有结构,device通过device_private注册到系统中。注册到系统中也是将相应的数据结构加入到系统已经存在的链表中,但是这些链接的细节并不希望暴露给用户,也没有必要暴露出来,所以才有private的结构。

    //所在文件/kernel/include/linux/device.h
    //设备类
    struct class 
    {
      const char *name; //设备类名称
      struct module *owner;//创建设备类的module
      struct class_attribute *class_attrs;//设备类属性
      struct device_attribute *dev_attrs;//设备属性
      struct kobject *dev_kobj;//kobject再sysfs中代表一个目录
      .....................
      struct class_private *p;//设备类得以注册到系统的连接件
    };
    
    //drivers/base/base.h
    struct class_private
    {
      struct klist class_devices;//设备类包含的设备(kobject)
      ..................................
      struct class *class;//指向设备类数据结构,即要创建的本级目录信息
    };
    //所在文件/kernel/include/linux/device.h
    struct device 
    {
      struct device *parent;        //sysfs/devices/中的父设备
      struct device_private *p;     //设备得以注册到系统的连接件
      struct kobject kobj;          //设备目录
      const char *init_name;        //设备名称
      struct bus_type *bus;         //设备所属总线
      struct device_driver *driver; //设备使用的驱动
      struct klist_node knode_class;//连接到设备类的klist
      struct class *class;          //所属设备类
      .....................
    };
    //所在文件/kernel/drivers/base/base.h
    struct device_private 
    {
        struct klist klist_children;    //连接子设备
        struct klist_node knode_parent; //加入到父设备链表
        struct klist_node knode_driver; //加入到驱动的设备链表
        struct klist_node knode_bus;    //加入到总线的链表
        struct device *device;          //对应设备结构
    };

    2.2 创建过程

    step1:调用class_create函数在/sys/class目录下创建一个设备类。

    /*
      功能:在/sys/class目录下创建一个目录,目录名是name指定的
      参数:
        struct module *owner - THIS_MODULE
        const char *name - 设备名
      返回值:
        成功:class指针
        失败: - bool IS_ERR(const void *ptr)  判断是否出错
             long PTR_ERR(const void *ptr) 转换错误码
    */
    struct class *class_create(struct module *owner, const char *name);

    step2:调用device_create函数在step1创建的设备类目录下创建具体的设备目录和设备属性文件。

    /* 
      功能:
        在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)   转换错误码
    */
    struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);

    step3:在/dev创建设备文件(系统自动进行)

    step1、step2都是在sysfs文件系统中创建目录或者文件,而应用程序访问的设备文件则需要创建在/dev/目录下。该项工作由mdev完成(需保证根文件系统支持mdev,由busybox配置)。

    2.2 注销过程

    step1:删除设备类目录下的设备

    /*
      功能:删除device_create创建的目录
      参数:
        struct class *cls - class指针
        dev_t devt - 设备号
    */
    void device_destroy(struct class *cls, dev_t devt);

    step2:删除/sys/class目录下的设备类

    /*
      功能:删除class指针指向的目录
      参数:
        struct class *cls - class指针
    */
    void class_destroy(struct class *cls);
  • 相关阅读:
    Range对象
    WorkSheet属性和方法
    Workbooks对象集
    常用对象之Application
    过程(Sub和Function)
    VBA基本语言结构
    Python网络编程-UDP(基于socket)
    Python网络编程-TCP(基于socket)
    二叉树的创建与遍历算法-C语言
    级数收敛的判定步骤
  • 原文地址:https://www.cnblogs.com/linfeng-learning/p/9316224.html
Copyright © 2011-2022 走看看