Linux中8259A到底是用level触发还是edge触发?
本帖最后由 rocklinux 于 2012-01-10 15:18 编辑以3.2代码为准
在init_IRQ()初始化过程中
init_8259A()中将ICW1初始化为0x11,这说明是设置成edge触发。
但又为什么在init_ISA_irqs()中将irq_desc->handle_irq设置成handle_level_irq?这不矛盾么?还是我遗漏了什么地方?
求教~ 另外,在哪个管理页面可以看到所有与自己有关的帖?像自己发的主帖,回复,被回复等等? 回复 2# rocklinux
右上角有个搜索按钮,可以按你的要求搜索的。
回复 1# rocklinux
8259A的触发方式貌似可以设置的吧,既可以是edge触发,也可以是level触发
回复 4# 瀚海书香
我知道是可以设置的,但我看Linux代码,是在将8259A设置为edge触发后,但却用的是level模式处理函数handle_level_irq()。所以我觉得有矛盾。不知道是不是什么地方我遗漏了。 回复 5# rocklinux
哦,只看标题了。。。
我看一下源码去
回复 1# rocklinux
到底是level方式还是edge方式,你首先要看一下数据手册的说明,一般这两种方式都会支持,但是具体使用哪种就看你的需求,只不过触发方式不一样而已。。。。 本帖最后由 rocklinux 于 2012-01-10 18:40 编辑
回复 7# chenrvmldd
我明白你的意思,我不是说“我”的需求。我是说在“linux内核”中。
内核会通过init_IRQ()初始化8259A,其中在调用init_8259A()时,会将8259A设置为edge触发。可是它又将irq_desc->handle_irq设置为handle_level_irq(),这个函数是处理level触发的中断的。所以我不清楚linux这么做是什么意思,有点矛盾。当然可能是我什么地方看漏了,所以请教。 回复 8# rocklinux
兄弟,对这块的源码我还没有深入研究过,但是我曾经做过一个实验,发现:硬件上设置的level还是edge方式,其实操作系统是不管的,操作系统只负责最终执行到你的自己注册的中断处理函数,然后你在中断处理函数中去处理到底是edge,还是level,对于edge和level的方式处理还是不一样的。。。我的实现过程如下:
第一段注册中断处理函数:注意我在硬件上设置的edge方式
/*
* 设置外部中断IRQ1为上升沿触发htm
*/
ptr = (volatile u32 *) (mbar_base + 0x50000+0x0020); (*ptr) |= BIT8; (*ptr) &= ~BIT9;
/*
* 设置外部中断IRQ2优先级为15,最高优先级
*/
(*ptr) |= (BIT12|BIT13|BIT14|BIT15);
virq=irq_create_mapping(NULL,1);
printk("virq is %d.\n", virq);
if (request_irq(virq, Htm_Int2_irq, 0, "HTM INT2 IRQ", NULL)) {
printk(KERN_ERR "htm: HTM INT2 irq allocation failed\n");
}
第二段注册中断处理函数:注意我在硬件上设置的edge方式
/*
/*
* 设置外部中断IRQ2(对应/INT_UART)为上升沿触发
*/
ptr = (volatile u32 *) (mbar_base + 0x50000+0x0040); (*ptr) |= BIT8; (*ptr) &= ~BIT9;
/*
* 设置外部中断IRQ2优先级为14,低于IRQ1管脚对应的优先级设置
*/
(*ptr) |= (BIT12|BIT13|BIT14);
virq=irq_create_mapping(NULL,2);
printk("virq is %d.\n", virq);
if (request_irq(virq, Uart_int_irq, 0, "Serial_com_irq", NULL)) {
printk(KERN_ERR "Serial_com: Serial_com_irq allocation failed\n");
}
下面是我加载驱动后通过:
/home # cat /proc/interrupts
CPU0 CPU1
17: 0 0 OpenPIC Level eth0_g1_tx
18: 0 0 OpenPIC Level eth0_g1_rx
19: 0 0 OpenPIC Level fsl-lbc
20: 0 0 OpenPIC Level HTM DMA IRQ
21: 0 0 OpenPIC Level fsldma-channel
22: 0 0 OpenPIC Level fsldma-channel
23: 0 0 OpenPIC Level fsldma-channel
24: 0 0 OpenPIC Level eth0_g1_er
29: 0 6 OpenPIC Level eth0_g0_tx
30: 115 0 OpenPIC Level eth0_g0_rx
34: 0 0 OpenPIC Level eth0_g0_er
37: 0 0 OpenPIC Level Serial_com_irq
38: 0 0 OpenPIC Edge HTM INT2 IRQ
42: 108 22 OpenPIC Level serial
43: 0 0 OpenPIC Level i2c-mpc, i2c-mpc
59: 2 0 OpenPIC Level fsl-espi
72: 162 0 OpenPIC Level mmc0
247: 0 0 OpenPIC Edge mpic timer 0
251: 0 0 OpenPIC Edge ipi call function
252: 1328 1806 OpenPIC Edge ipi reschedule
253: 417 383 OpenPIC Edge ipi call function single
可以看到:37和38号中断号的对应的处理方式不一样,一个是edge一个是level,所以我个人认为:这个有可能和操作系统方面是edge还是level没有多大的关系,理解不到此处还往指出 本帖最后由 rocklinux 于 2012-01-10 19:43 编辑
回复 9# chenrvmldd
其实我也是刚开始学。。。
你确定你是用的8259A么,8259A在Linux中的名字不是"XT-PIC"么。
我还不知道8259A芯片可以对每个管脚单独设置触发方式。我知道8259A的ICW1的bit3位是控制触发方式,0为边沿触发。但它是影响整个芯片8个管脚的。
另外你有个概念可能有误(当然可能是我有误)。Linux操作系统是要关系到底是level触发还是edge触发,不同的触发有不同的处理流程,比如handle_level_irq()和handle_edge_irq()。这两个流程函数会调用我们注册的ISR。也就是说,我们通过request_irq()或setup_irq()注册的的ISR是不用关系触发模式的。
页:
[1]
2