zoukankan      html  css  js  c++  java
  • Linux驱动学习(四)

             在前三篇里学习了Linux平台设备和驱动的一些知识后,这篇就说一下驱动程序是怎么自动生成设备文件。

             写过Linux驱动的可能都知道,Linux里有一类设备叫做混杂设备,而且还可以发现注册这一类设备后是不用手动去生成设备文件的。好吧,由这类设备的注册函数入手,从而去了解是怎样自动生成设备文件的。看看混杂设备注册函数在/drivers/char/misc.c里的定义:

     1 int misc_register(struct miscdevice * misc)
     2 {
     3         struct miscdevice *c;
     4         dev_t dev;
     5         int err = 0;
     6 
     7         INIT_LIST_HEAD(&misc->list);
     8 
     9         mutex_lock(&misc_mtx);
    10         list_for_each_entry(c, &misc_list, list) {
    11                 if (c->minor == misc->minor) {
    12                         mutex_unlock(&misc_mtx);
    13                         return -EBUSY;
    14                 }
    15         }
    16 
    17         if (misc->minor == MISC_DYNAMIC_MINOR) {
    18                 int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
    19                 if (i >= DYNAMIC_MINORS) {
    20                         mutex_unlock(&misc_mtx);
    21                         return -EBUSY;
    22                 }
    23                 misc->minor = DYNAMIC_MINORS - i - 1;
    24                 set_bit(i, misc_minors);
    25         }
    26         // MISC_MAJOR = 10
    27         dev = MKDEV(MISC_MAJOR, misc->minor);
    28 
    29         misc->this_device = device_create(misc_class, misc->parent, dev,
    30                                           misc, "%s", misc->name);
    31         if (IS_ERR(misc->this_device)) {
    32                 int i = DYNAMIC_MINORS - misc->minor - 1;
    33                 if (i < DYNAMIC_MINORS && i >= 0)
    34                         clear_bit(i, misc_minors);
    35                 err = PTR_ERR(misc->this_device);
    36                 goto out;
    37         }
    38 
    39         /*
    40          * Add it to the front, so that later devices can "override"
    41          * earlier defaults
    42          */
    43         list_add(&misc->list, &misc_list);
    44  out:
    45         mutex_unlock(&misc_mtx);
    46         return err;
    47 }

    第17~25行的作用是分配一个还没用过的次设备号(混杂设备的主设备号都是一样的);第27行,生成一个设备号(由主设备号和次设备号组成)。第29行,自动生成设备文件的“玄机”就在里面,看它在drivers/base/core.c里的定义:

     1 struct device *device_create(struct class *class, struct device *parent,
     2                              dev_t devt, void *drvdata, const char *fmt, ...)
     3 {       
     4         va_list vargs;
     5         struct device *dev;
     6 
     7         va_start(vargs, fmt);
     8         dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
     9         va_end(vargs);
    10         return dev;
    11 }

    关键看第8行device_create_vargs()的定义:

     1 struct device *device_create_vargs(struct class *class, struct device *parent,
     2                                    dev_t devt, void *drvdata, const char *fmt,
     3                                    va_list args)
     4 {
     5         struct device *dev = NULL;
     6         int retval = -ENODEV;
     7 
     8         if (class == NULL || IS_ERR(class))
     9                 goto error;
    10 
    11         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    12         if (!dev) {
    13                 retval = -ENOMEM;
    14                 goto error;
    15         }
    16 
    17         dev->devt = devt;
    18         dev->class = class;
    19         dev->parent = parent;
    20         dev->release = device_create_release;
    21         dev_set_drvdata(dev, drvdata);
    22 
    23         retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
    24         if (retval)
    25                 goto error;
    26 
    27         retval = device_register(dev);
    28         if (retval)
    29                 goto error;
    30 
    31         return dev;
    32 
    33 error:
    34         put_device(dev);
    35         return ERR_PTR(retval);
    36 }

    第17~21行,很明显,就是设置device变量的一些成员的值;第27行,怎么样,很眼熟是吧,前面已经分析过了,这里就不再累述。

    下面总结一下在编写驱动程序时怎么让内核帮我们自动生成设备文件,其实也就是多调用2个函数:

    1. class_create()

    该函数在include/linux/device.h里定义。

    2. 上面所说的device_create()

    关键在于把class_create()函数的返回值作为device_create()函数第一个参数的值,其他参数的含义都很好明白。

  • 相关阅读:
    小程序 图片和文字放在一行对齐的方法
    Linux下Redis安装使用教程
    关系型数据库和非关系型数据库的区别
    微信小程序scroll-view 横向和纵向scroll-view组件
    ThinkPHP5.0手把手实现手机阿里云短信验证
    极验(Geetest) Laravel 5 集成开发包,让验证更安全
    (进阶篇)PHP(thinkphp5框架)实现用户注册后邮箱验证,激活帐号
    详解PhpSpreadsheet设置单元格
    使用PhpSpreadsheet将Excel导入到MySQL数据库
    【JZOJ4783】【NOIP2016提高A组模拟9.15】Osu
  • 原文地址:https://www.cnblogs.com/lknlfy/p/2504684.html
Copyright © 2011-2022 走看看