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

来源:互联网 发布:网络外汇理财诈骗信号 编辑:程序博客网 时间:2024/06/05 03:06

  

/*

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

 *原作者和原文链接 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
原创粉丝点击