中断。。

来源:互联网 发布:java并发实战 epub 编辑:程序博客网 时间:2024/06/16 23:22
#include <linu/init.h>
#include <linux/module.h>

irqreturn_t test_irq_handler(int irq, void *dev_id)
{
    printk("test test\n");
    return IRQ_HANDLED;
}
/*
IRQ_HANDLED 操作中断成功
IRQ_NONE    意味着操作不成功
*/
int test_mode_init(void)
{
    int ret;
    re = request_irq(IRQ_EINT(0), test_irq_heandler, IRQF_TRIGGER_FALLING | IRQF_SHARED, "test_irq", NULL);
    if(ret)
    {
        printf("request_irq failed!\n");
        reuturn -1;
    }
    return 0;
}
/*
    IRQF_TRIGGER_NONE    不会触发
    IRQF_TRIGGER_FALLING 下降沿触发
    IRQF_TRIGGER_RISING    上升沿触发
    IRQF_TRIGGER_HIGH        高电平触发
    IRQF_TRIGGER_LOW        低电平触发
*/
void test_mod_exit(void)
{
    free_irq(IRQ_EINT(0), "test_irq");
}

module_init(test_mode_init);
module_exit(test_mode_exit);

将这个模块编译进内核作为测试用,测试当一个按键中断被用了后,再次使用是什么情况?

编译进内核后,将内核重新烧写到开发板上去。
之后再把一个按键中断模块加入到内核中去

这个时候中断注册不成功,把模块卸载后,再加载模块时又可以注册中断成功了?
为什么了????
    因为第一次加载的时候,因为已经有人注册了当前的中断号,所以注册中断失败,卸载掉模块后,会调用free_irq函数,把之前那个人注册的中断注销掉,下次再注册中断的时候注册可以成功了。这么做是相当危险,所以注册中断的时候一定要判断中断注册返回值。其实也不止这个,任何有返回值的代码都要小心处理。

1、判断返回值
2、cat proc/interrupts 查看中断注册情况。
3、grep -Rn "test-irq" drivers/ *  查看到注册中断的代码
4、找到后如果代码不重要就make menuconfig把那一块代码处理掉。

但是如果不能去掉这一块代码,那该如何处理了?
那当然就是采用共享中断了。
要想共享中断成功就一定要两边都设置成中断共享标志(IRQ_SHARED)


调试内核代码:
    一个函数测试有没有出问题,一般去打印信息。
    一般是在if return的地方加printk打印信息。

    printk("[%s][%d]\n", __FUNCTION__, __LINE__);
    if(ret < 0)
        return -1;
    printk("[%s][%d]\n", __FUNCTION__, __LINE__);

    在request_irq()代码中有一句:
    if((irqflags & IRQF_SHARED) && !dev_id)
        return -EINVAL;

    所以在设置了IRQF_SHARED后,如果第四个参数是NULL的时候,注册就会失败
    
    这么处理主要是为了好处理当共享中断的时候,好让内核知道是哪一个要free_irq();
    
    
    共享中断后,触发中断后,两个共享代码同时处理。
    内核里面的先处理,后面加载的后处理。
原创粉丝点击