首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内核函数asm_do_IRQ()中的irq与我在模块中请求的irq不同

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

Stack Overflow用户
提问于 2013-04-08 12:03:05
回答 1查看 2K关注 0票数 4

我用cortex A9开发板做了一些实验。我使用gpio_to_irq()获得一个irq num,我请求irq并用它编写了一个小驱动程序,它在syslog中是196。我在asm_do_IRQ中添加了一些打印。当我触发gpio中断时,驱动程序工作正常,但asm_do_IRQ中的irq数是62,.I无法理解。为什么irq号和我要求的不一样?驱动程序如下:

代码语言:javascript
复制
    #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,0,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/ asm_do_IRQ /irq.c中的内核

代码语言:javascript
复制
    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);

    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-08 15:48:42

这种观察可能是由于物理和虚拟IRQ编号之间的映射造成的。在您的驱动程序中看到的数字是虚拟IRQ数字,仅在使用通用linux中断处理子系统时有效。asm_do_IRQ中的中断号将是由内核的中断结构提供的物理中断号。

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

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

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

  1. 更改发生在GPIO库中的中断上。IRQ 62是在IRQ 62上运行的raised.
  2. asm_do_IRQ
  3. GPIO子系统读取GPIO子系统的寄存器并确定GPIO位X引起了中断。它计算从第X位到linux虚拟IRQ号的映射,在本例中为196。
  4. GPIO中断处理程序然后使用196调用generic_handle_irq函数,该函数调用您的中断处理程序。

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

  • 在低于linux-3.4的内核上启用CONFIG_VIRQ_DEBUG,或
  • 在较新的内核上启用CONFIG_IRQ_DOMAIN_DEBUG

然后查看irq_domain_mapping调试文件。例如,在PowerPC上:

代码语言:javascript
复制
# 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
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15871048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档