linux – 内核函数asm_do_IRQ()中的irq与我在模块中请求的不同

linux – 内核函数asm_do_IRQ()中的irq与我在模块中请求的不同,第1张

概述我做了一些皮质-A9开发板的实验.我使用gpio_to_irq()获取irq num并且我请求了irq并用它写了一个小驱动程序,它在syslog中是196.我在asm_do_IRQ中添加了一些printks.当我触发gpio中断时,驱动程序工作正常,但asm_do_IRQ中的irq num为62.我无法理解.为什么irq号码与我要求的号码不同?司机如下: #include <linux/modul 我做了一些皮质-A9开发板的实验.我使用gpio_to_irq()获取irq num并且我请求了irq并用它写了一个小驱动程序,它在syslog中是196.我在asm_do_IRQ中添加了一些printks.当我触发gpio中断时,驱动程序工作正常,但asm_do_IRQ中的irq num为62.我无法理解.为什么irq号码与我要求的号码不同?司机如下:

#include <linux/module.h>    #include <linux/interrupt.h>    #include <linux/irq.h>    #include <linux/gpio.h>    #define GPIO_N 36     //gpio number    int flag = 0;    static irqreturn_t handler(int irq,voID *dev_ID)    {            printk("hello world hahahahahhahahah \n\n");            return 0;    }    static int __init gpio_test_init(voID)    {            if(gpio_request_one(GPIO_N,GPIOF_DIR_IN,"some test")<0)            {                    printk(KERN_ERR "Oops! BAD! BAD! BAD!\n\n");                    return 0;            }            int irq,irq2;            irq = OMAP_GPIO_IRQ(TEST_GPIO);            printk("irq : %d \n",irq,irq2);            // ..................            // irq : 196 in dmesg             //......................            set_irq_type(irq,IRQ_TYPE_EDGE_FALliNG);            enable_irq(gpio_to_irq(GPIO_N));            int err;            // request the irq ...            if((err = request_irq(irq,&handler,NulL,NulL))<0)            {                    printk("err : %d\n",err);                    return 0;            }            printk("gpio test init success!\n");            flag = 1;            return 0;    }    static voID __exit gpio_test_exit(voID)    {            int irq = gpio_to_irq(TEST_GPIO);            if(flag == 1)free_irq(irq,NulL);            gpio_free(TEST_GPIO);            printk("gpio test exit byebye!\n");    }    module_init(gpio_test_init);    module_exit(gpio_test_exit);    MODulE_liCENSE("GPL");

arch / arm / kernel / irq.c中的asm_do_IRQ

asmlinkage voID __exception_irq_entry    asm_do_IRQ(unsigned int irq,struct pt_regs *regs)    {            struct pt_regs *old_regs = set_irq_regs(regs);            printk("the irq : %d\n",irq);              //...............             // I get 62 here            //...............            irq_enter();            /*             * Some harDWare gives randomly wrong interrupts.  Rather             * than crashing,do something sensible.             */            if (unlikely(irq >= nr_irqs)) {                    if (printk_ratelimit())                            printk(KERN_WARNING "Bad IRQ%u\n",irq);                    ack_bad_irq(irq);            } else {                    generic_handle_irq(irq);            }            /* AT91 specific workaround */            irq_finish(irq);            irq_exit();            set_irq_regs(old_regs);    }
解决方法 这种观察可能是由于物理和虚拟IRQ号之间的映射.驱动程序中显示的数字是虚拟IRQ编号,仅在使用通用linux中断处理子系统时才有效. asm_do_IRQ中的中断号将是核心的中断结构提供的物理中断号.

我相信OMAP处理器支持GPIO引脚上的中断.通常实现的方法是为一组GPIO输入分配单个IRQ线,比如32位.当任何GPIO发生中断时,IRQ线将激活.这可能是处理器上的数字62.如果查看处理器的手册,您应该看到IRQ 62对应于GPIO bank上的中断.

现在,linux GPIO子系统将允许您为任何GPIO分配中断处理程序,为您提供从linux irq号到物理irq号的映射.您的情况下的linux irq编号为196. GPIO子系统配置为处理所有GPIO中断(例如中断62),读取GPIO寄存器以确定存储区中的哪个GPIO位可能产生中断,然后调出您使用request_irq分配的中断处理程序.

这是GPIO中断的基本控制流程:

> GPIO bank中的中断发生变化. IRQ 62被提出.
> asm_do_IRQ在IRQ 62上运行.已注册GPIO子系统以通过平台初始化代码处理IRQ 62.
> GPIO子系统读取GPIO寄存器并确定GPIO位X是否已导致中断.它计算从位X到linux虚拟IRQ号的映射,在本例中为196.
>然后GPIO中断处理程序用196调用generic_handle_irq函数,该函数调用中断处理程序.

通常在虚拟IRQ号和物理IRQ号之间由平台定义静态映射.要查看此映射,

>在早于linux-3.4的内核上启用CONfig_VIRQ_DEBUG,或
>在较新的内核上启用CONfig_IRQ_DOMAIN_DEBUG.

然后看看irq_domain_mapPing deBUGfs文件.例如.在PowerPC上:

# mount -t deBUGfs none /sys/kernel/deBUG# cat /sys/kernel/deBUG/irq_domain_mapPing irq    hwirq    chip name        chip data   domain name   16  0x00009  IPIC             0xcf801c80  /soc8347@e0000000/pic@700   18  0x00012  IPIC             0xcf801c80  /soc8347@e0000000/pic@700   19  0x0000e  IPIC             0xcf801c80  /soc8347@e0000000/pic@700   20  0x0000f  IPIC             0xcf801c80  /soc8347@e0000000/pic@700   21  0x00010  IPIC             0xcf801c80  /soc8347@e0000000/pic@700   77  0x0004d  IPIC             0xcf801c80  /soc8347@e0000000/pic@700
总结

以上是内存溢出为你收集整理的linux – 内核函数asm_do_IRQ()中的irq与我在模块中请求的不同全部内容,希望文章能够帮你解决linux – 内核函数asm_do_IRQ()中的irq与我在模块中请求的不同所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1018614.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存