• 【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   

  • 相关阅读:
    三种方法处理文字中的空格
    text——文本属性大全
    font——文字属性大全
    padding和margin——内边距和外边距
    background——背景属性
    C# 解析excel时,字段内有内容,却读取不到的解决方法
    jqprint 打印分页
    pre标签 首行会自动换行解决方案
    正则表达式 清除所有标签的属性
    针对安卓微信浏览器网页 置顶悬浮框浮动固定 的问题
  • 原文地址:https://www.cnblogs.com/huty/p/8518551.html
Copyright © 2020-2023  润新知