zoukankan      html  css  js  c++  java
  • 【Linux开发】linux设备驱动归纳总结(十):1.udev&misc

    linux设备驱动归纳总结(十):1.udev&misc


    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    不知不觉我的总结已经写得七七八八了,这一章节只是补充一下两个知识点:动态创建设备节点和杂设备类的注册。

    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


    一、动态创建设备节点——udev


    之前加载字符型设备后是通过命令mknod来创建设备节点的。在2.6内核中,有一个名叫udev的后台程序,它通过读取/sys/class的信息,一旦添加的新的设备,该后台程序就会自动创建设备节点。


    一、要使用动态创建设备节点,首先要运行udev后台程序。


    在嵌入式下有两种方法:

    1、移植udev到嵌入式系统中。

    2、在编译busybox时加入mdev

    mdev可以理解是udev的精简版,在这里我就不介绍如何加入mdev,仅仅介绍udev的移植。

    首先:进入到udev的目录,我在附件中提供了udev的源文件:

    root@xiaobai-laptop:/nfsroot/review_driver/10th_udev_misc/udev/tools/udev-096# pwd

    /nfsroot/review_driver/10th_udev_misc/udev/tools/udev-096

    接着修改Makefile的两处:

    line 96 prefix = /nfsroot //指定udev安装路径,安装到我们的跟文件系统中

    linr 114 CROSS_COMPILE = arm-linux- //指定编译工具

    然后编译并安装:

    make

    make install

    最后在跟文件系统的/nfsroot/etc/init.d/rcS加上三句话,让系统启动后运行udev后台程序:

    mount -t tmpfs tmpfs /dev

    /sbin/udevd -d

    /sbin/udevstart

    移植udev后,系统启动是就会自己启动udev程序。


    二、接着就是在代码中使用动态创建函数了。


    udev的动态创建是通过读取/sys/class的信息来实现的。所以,首先是要创建一个类:

    struct class *class_create(struct module *owner, const char *name)

    owner用于指定该类的所属,一般填写THIS_MODULE

    name是指定该类该/sys/class/目录下的目录名字。

    同样的,该操作有可能出错,需要检验返回值。

    类创建成功后会在/sys/class创建一个以name命名的目录。


    类的注销使用以下函数:

    void class_destroy(struct class *cls)


    创建类后,就可以调用以下函数注册类设备,将设备加入到指定的类中,这样udev就可以才class目录下读取信息后动态创建设备节点了:

    /*drivers/base/core.c*/

    1386 struct device *device_create(struct class *class, struct device *parent,

    1387 dev_t devt, void *drvdata, const char *fmt, ...)

    class是用于指定所属的class

    parent用于指定设备的父设备,一般填NULL就可以了。

    Devt用于指定该设备的设备号。

    drvdata用于指定class下的数据,一般也不用传。

    fmt就是动态创建的设备文件的名字,一般格式:"%s", "test_led"

    设个函数成功调用会在/sys/devices/virtual的对应总线下创建一个test_led的目录,并且软连接到/sys/class对应的总线目录下。


    使用以下函数注销类设备:

    void device_destroy(struct class *class, dev_t devt)


    注意:上面的两步并没有真正创建设备文件,只有在udev读取/sys/class信息后发现tesl_led,才会真正创建设备文件。


    先来来个代码,这是我之前写的简洁版led驱动,添加了动态创建设备文件功能:

    /*10th_udev_misc/udev/1st_udev/test.c*/

    7 #include //需要包含该头文件

    10 struct class *my_class;

    。。。。。

    62 int test_init(void)

    63 {

    64      //devmodel class create

    65      my_class = class_create(THIS_MODULE, "test_class"); //创建class

    66      if(IS_ERR(my_class)){

    67           printk("create cleaa wrong! ");

    68           return -1;

    69      }

    70      device_create(my_class, NULL, MKDEV(253, 0), NULL, "%s", "test_led"); //根据class和设备号创建设备

    71

    72      register_chrdev(253, "udev led", &led_fops);

    73      led_init(); //ioremap的地址映射

    74      led_config(); //gpio_led的配置

    75

    76      return 0;

    77 }

    78 void test_exit(void)

    79 {

    80      iounmap((void *)virt); //注销虚拟地址的映射

    81      unregister_chrdev(253, "udev led"); //注销设备节点

    82      device_destroy(my_class, MKDEV(253, 0)); //注销类设备

    83      class_destroy(my_class); //注销类

    84      printk("bye ");

    85 }


    接下来验证一下:

    [root: 1st_udev]# insmod test.ko //加载驱动

    [root: 1st_udev]# ./app on //灯亮

    [root: 1st_udev]# ./app off //灯灭

    [root: 1st_udev]# cat /proc/devices //查看一下

    Character devices:

    1 mem

    。。。。。

    136 pts

    204 s3c2410_serial

    253 udev led //设备被注册了

    254 rtc

    [root: 1st_udev]# cd /

    [root: /]# find -name "*test_led*" //查找test_led相关文件

    ./sys/devices/virtual/test class/test_led ///device/virtule目录下有test_led目录

    ./sys/class/test class/test_led //并且有类test_class

    ./dev/test_led //动态创建了test_led设备文件

    [root: 1st_udev]# ls -l /sys/class/test class/test_led

    lrwxrwxrwx 1 root root 0 Jan 1 08:29 /sys/class/test class/test_led -> ../../devices/virtual/test class/test_led


    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


    二、杂设备——misc


    简单的说,杂设备就是内核自动帮你分配设备号并且自动创建设备文件。

    1、自动分配设备号,是指所有注册为杂设备的设备的主设备号为10,而次设备号内核自动分配。

    2、自动创建设备文件是指,内核会使用udev(前提是你已经移植udev),动态创建设备节点。


    方法很简单:需要包含头文件:linux/miscdevice.h
    1
    、定义杂设备结构体:

    36 struct miscdevice {

    37      int minor;

    38      const char *name; //设备文件的名字

    39      const struct file_operations *fops; //指定该设备的fops结构体

    40      struct list_head list;

    41      struct device *parent;

    42      struct device *this_device;

    43 };

    红色标记的内容是我们必须要自己填写的,其他部分可以由内核自己分配。


    2、定义结构体后使用使用一下函数注册和注销:

    int misc_register(struct miscdevice * misc); //注册

    int misc_deregister(struct miscdevice *misc); //注销

    注册操作会失败,建议检查返回值。


    看代码:

    /*10th_udev_misc/misc/1st_misc/test.c*/

    58 static struct file_operations led_fops = {

    59      .ioctl = led_ioctl,

    60 };

    61

    62 static struct miscdevice misc_led = { //杂设备

    63      .name = "test_led",

    64      .fops = &led_fops,

    65 };

    66

    67 int test_init(void)

    68 {

    69      misc_register(&misc_led); //注册杂设备

    70

    71      led_init(); //ioremap的地址映射

    72      led_config(); //gpio_led的配置

    73

    74      return 0;

    75 }

    76 void test_exit(void)

    77 {

    78      misc_deregister(&misc_led); //注销杂设备

    79      iounmap((void *)virt); //注销虚拟地址的映射

    80      printk("bye ");

    81 }

    再看效果

    [root: 1st_misc]# insmod test.ko

    [root: 1st_misc]# cat /proc/devices

    Character devices:

    1 mem

    4 /dev/vc/0

    4 tty

    5 /dev/tty

    5 /dev/console

    5 /dev/ptmx

    7 vcs

    10 misc //创建的设备在misc

    [root: 1st_misc]# lsmod

    test 2212 0 - Live 0xbf000000

    [root: 1st_misc]# ls -l /dev/test_led

    crw-rw---- 1 root root 10, 0 Jan 1 08:05 /dev/test_led //自动创建的设备节点主设备号为10

    [root: 1st_misc]# ./app on //亮灯

    [root: 1st_misc]# ./app off //灭灯

    [root: 1st_misc]# cd / //查看test_led相关文件

    [root: /]# find -name "*test_led*"

    ./sys/devices/virtual/misc/test_led

    ./sys/class/misc/test_led //发现注册到misc类中

    ./dev/test_led


    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


    三、总结


    这节介绍了如何动态创建设备文件和如果创建杂设备类驱动。


    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    源代码: 10th_udev_misc.rar   

  • 相关阅读:
    TCP源码—连接建立
    TCP系列02—连接管理—1、三次握手与四次挥手
    TCP系列01—概述及协议头格式
    ubuntu软件管理apt与dpkg
    318. Maximum Product of Word Lengths
    317. Shortest Distance from All Buildings
    316. Remove Duplicate Letters
    315. Count of Smaller Numbers After Self
    314. Binary Tree Vertical Order Traversal
    313. Super Ugly Number
  • 原文地址:https://www.cnblogs.com/huty/p/8518550.html
Copyright © 2011-2022 走看看