zoukankan      html  css  js  c++  java
  • 字符设备驱动2:易错点【注册 、 注销】

    概要:

    1. cdev_add时分配设备号不足的错误示范
    2. unregister_chrdev_region没有完全注销设备

      相关错误现象:

        error, can't open /dev/led1

        insmod: cannot insert '/module/myleds_new.ko': File exists (-1): File exists

       

     1.cdev_add时分配设备号不足的错误示范

    正确代码及现象:

     1 static int __init s3c24xx_leds_init()
     2 {
     3     int ret ;
     4     int minor = 0 ;
     5     dev_t devno = MKDEV(leds_major , 0);
     6 /*申请设备号,当xxx_major不为0时,表示静态指定;当为0时,表示动态申请*/
     7     if(leds_major){
     8         ret = register_chrdev_region(devno , LEDS_DEV_COUNT , LEDS_DEV_NAME);
     9     }else{
    10         ret = alloc_chrdev_region(devno, LEDS_BASE_MINOR, LEDS_DEV_COUNT, LEDS_DEV_NAME);
    11         leds_major = MAJOR(devno);
    12     }
    13     if(ret<0){
    14         return ret ;
    15     }
    16 
    17 //初始化并添加cdev结构体
    18     cdev_init(&leds_cdev , &s3c24xx_leds_fops );
    19     leds_cdev.owner = THIS_MODULE ;
    20     leds_cdev.ops = &s3c24xx_leds_fops;
    21     ret = cdev_add(&leds_cdev , devno , LEDS_DEV_COUNT); 
    22  printk("cdev_add(&leds_cdev , devno , 4);
    ");
    23 //这里因为下面要建立四个子设备,因此必须至少 4个(LEDS_DEV_COUNT)。否则,使用该设备是,子设备0后面的设备是无法使用的
    24 //现象见下面的:“cdev_add时分配设备号不足的错误示范”。
    25   
    26     if(ret){
    27         printk(LEDS_DEV_NAME"Error %d adding leds_cdev",ret);
    28     }
    29 
    30 //oo00 :begin : 分配了四个子设备号  minor == 0 1 2 3
    31 //class_create动态创建设备的逻辑类,并完成部分字段的初始化,然后将其添加到内核中。创建的逻辑类位于/sys/class/。
    32     leds_class = class_create(THIS_MODULE, "leds");
    33     if (IS_ERR(leds_class))
    34         return PTR_ERR(leds_class);
    35 
    36     leds_class_devs[0] = class_device_create(leds_class, NULL, MKDEV(leds_major, 0), NULL, "leds");
    37 
    38     for (minor = 1; minor < 4; minor++){
    39         leds_class_devs[minor] = class_device_create(leds_class, NULL, MKDEV(leds_major, minor), NULL, "led%d", minor);
    40         if (unlikely(IS_ERR(leds_class_devs[minor])))
    41             return PTR_ERR(leds_class_devs[minor]);
    42     }
    43 //oo00 :end
    44 
    45 //prow: device_create  ?  or   class_device_create?
    46 
    47     printk(LEDS_DEV_NAME" initialized
    ");
    48 
    49     return 0;
    50 }
    51 
    52 现象:
    53 # insmod myleds_new.ko 
    54 cdev_add(&leds_cdev , devno , 4);
    55 leds initialized
    56 # ./ledtest /dev/leds on
    57 info new: in s3c24xx_leds_ioctl!
    58 # ./ledtest /dev/led1 off
    59 info new: in s3c24xx_leds_ioctl!

    错误代码及现象:

    ret = cdev_add(&leds_cdev , devno , 1);
    printk("cdev_add(&leds_cdev , devno , 1);
    ");
    
    现象:
    insmod正常,cat /proc/devices 能看见 leds 231;在app里面使用子设备号为0的设备ok,使用0以上的打不开。
    # insmod myleds_new.ko 
    cdev_add(&leds_cdev , devno , 1);//printk , 分配数量不够
    leds initialized                //printk
    
    # ./ledtest /dev/leds on
    info new: in s3c24xx_leds_ioctl!
    # ./ledtest /dev/led1 off
    error, can't open /dev/led1

    2.unregister_chrdev_region没有完全注销设备

    void unregister_chrdev_region(dev_t from, unsigned count); //count: the number of device numbers to unregister

    正确代码及现象:

    static void __exit s3c24xx_leds_exit()
    {
        dev_t devno = MKDEV(leds_major , 0);
        int minor;
        for(  minor = 0;minor<4;minor++){
            class_device_unregister(leds_class_devs[minor]);
        }
        class_destroy(leds_class);
        cdev_del(&leds_cdev);//删除结构体
        unregister_chrdev_region(devno, LEDS_DEV_COUNT);//注销设备区域,正确的,将4个子设备域都注销了
    }
    //执行rmmod之后,cat /proc/devices 没有leds 231

    错误代码及现象: 

    unregister_chrdev_region(devno, 1);//注销设备区域, 4个子设备域没有完全注销
    //执行rmmod之后,cat /proc/devices 仍有leds 231,并导致下次insmod失败。并且此时leds设备实体已经被注销了。
  • 相关阅读:
    C#总结(四)调用C++动态库
    Golang 入门系列(十二)ORM框架gorm
    《关键对话》如何高效沟通,营造无往不利的事业和人生?
    Golang 入门系列(十一)Go语言实现webapi
    Golang 入门系列(十) mysql数据库的使用
    Golang 入门系列(九) 如何读取YAML,JSON,INI等配置文件
    Golang 入门系列(八) cron定时任务
    Golang 入门系列(七) Redis的使用
    福利 | 互联网产品经理学习资料免费下载(可下载)
    福利 | 2018各大技术大会资料汇总(可下载)
  • 原文地址:https://www.cnblogs.com/mylinux/p/4010881.html
Copyright © 2011-2022 走看看