linux驱动:那容易遗忘的角落--return 0 by明智

  

/*

 *本文版权归于凌阳教育和本作者所有。如转载请注明

 *原作者和原文链接 http://blog.csdn.net/edudriver/article/details/20554927*

 *特此说明并保留对其追究法律责任的权利*

 */ 

     来,我们来看一段代码.

     这段代码是用于linux驱动初始化,很熟悉吧,功能就是申请中断,注册驱动和生成设备节点.来,慢慢看,仔细看,睁大眼睛看.

retval = request_irq(IRQ_EINT(20), buttons_interrupt, IRQF_SHARED,
            "KEY1", (void *)EINT_DEVICE_ID);
    if(retval){
        err("request eint20 failed");
        goto error;
    }

    
    /* Driver register */
    major = register_chrdev(major, DRIVER_NAME, &key_fops);
    if(major < 0){
        retval = major;
        goto error_register;
    }
    key_class=class_create(THIS_MODULE,DRIVER_NAME);
    if(IS_ERR(key_class)){
        retval =  PTR_ERR(key_class);
        goto error_class;
    }
    key_device=device_create(key_class,NULL, MKDEV(major, minor), NULL,DRIVER_NAME);
    if(IS_ERR(key_device)){
        retval = PTR_ERR(key_device);
        goto error_device;
    }
    __debug("register myDriver OK! Major = %d\n", major);

error_device:
    class_destroy(key_class);
error_class:
    unregister_chrdev(major, DRIVER_NAME);
error_register:
    free_irq(IRQ_EINT(20), (void *)EINT_DEVICE_ID);
error:
    return retval;
}

     看出问题了吗?

     那位同学,请把你的砖头和鸡蛋放下,我知道你想说什么,"没有.ko 没有调试 没有完全代码你丫让我找BUG!!".其实是可以看出来的,公布答案了!


     说好炸鸡和啤酒呢! 不对,是说好的return 0呢!!


     看到了吗,在error_device之前是不是要有一个return 0呢.别小看了这个问题,在我为学员上嵌入式驱动培训过程中,就有不少的学员出现这样的问题.他们辛辛苦苦调试了半天,明明没有打印错误信息,那应该就是成功了呀,为嘛就是进入不了中断服务函数呢!一些成绩好一点的学员,可能想到一个命令cat /proc/interrupts来查看中断有没有注册进内核,"咦,今天见鬼啦!居然也没有看到自己编写的中断..."万般无奈之下,只好屁颠屁颠(请注意,不含贬义,纯粹是为了增加画面感)来找老师帮忙.


    看到这里,有些同学可能还不是很明白,为嘛这个return 0这么重要.我们来分析一下.假如一切顺利的话,我们的申请中断,注册驱动和生成设备节点都成功,这时候代码跋山涉水运行到了

    __debug("register myDriver OK! Major = %d\n", major);这时候屏幕也提示你说,注册OK啦,开香槟啦!且慢,思考一个问题,思考一个问题

error_device:

    class_destroy(key_class);

    这段代码会执行吗?按照C语言的语法规则,必定会!因为还没有看到return.

    不仅class_destroy(key_class)会执行,剩下这些代码都会被执行



error_device:
    class_destroy(key_class);
error_class:
    unregister_chrdev(major, DRIVER_NAME);
error_register:
    free_irq(IRQ_EINT(20), (void *)EINT_DEVICE_ID);
error:
    return retval;


    这会造成一个什么结果呢:注册成功了所有都被注销了,并且还return的retval=0.这就使得调试起来很郁闷,明明屏幕显示成功,内核也没有打印出什么错误信息,但实际不成功,如果没有相关调试经验的话可能就无法下手了.
    所以下次再遇到这样的问题时,第一时间,看return 0!


    当然啦,我肯定是不会告诉你,我也犯过这样的错误并且被同事嘲笑过的啦偷笑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值