我在s3c44b0上基于uclinux写自己设备的驱动,内核2.4
在驱动文件里头申请了一个中断
ret=request_irq(21,&key_interrupt,SA_INTERRUPT,"my_key",NULL);
其中21是外部中断源号,key_interrupt是我的中断服务程序,SA_INTERRUPT是指快速中断,“my_key”是我的设备名称,NULL代表中断不共享(不知道对不对)
中断服务程序:
key_interrupt()
{
count_temp++;
printk("key interrupt occur %d times!", count_temp++);
}
调试的时候就出现问题了:
一旦我按一下按钮,调试中断就显示
key interrupt occur 1 times!
key interrupt occur 2 times!
key interrupt occur 3 times!
key interrupt occur 4 times!
key interrupt occur 5 times!
........
就是不断地运行中断程序??十分费解!
出现此问题后,我首先想的是,当我申请了一个中断的时候,就是最上面request_irq里头没有哪个参数代表是高电平、低电平、上升沿、下降沿还是双边沿触发,感觉linux应该有设置中断方式的函数,可是我没找到。于是我自己在申请中断之前,手动设置了21号中断源的方式为下降沿触发。
(*(volatile unsigned *)S3C44B0_EXTINT) &= 0x5555ffff
再次调试,
key interrupt occur 1 times!
key interrupt occur 2 times!
key interrupt occur 3 times!
........
结果,依然是不断地运行中断程序??更费解?!
再思考,是不是因为我的中断程序没有清楚标志位呢?导致系统不断误认为有中断产生呢?我参考一些资料,在中断程序里头都没有说要清楚标志位的做法,linux下应该有自动清除中断标志位的吧?(也不太了解)。在毫无头绪的情况下,我在中断服务程序里头加了一个清楚中断标志位的语句。
(*(volatile unsigned *)S3C44B0_EXTINPND) &= 0xfffffff0
(*(volatile unsigned *)S3C44B0_INTPND) &= 0xffdfffff
上面涉及到两个寄存器,一个是外部中断寄存器EXTINPND和总的中断寄存器INTPND,当有外部中断产生时,EXTINPND的低四位某一位置1,INTPND的21位也会置1,我把他们都清0了
继续运行
key interrupt occur 1 times!
key interrupt occur 2 times!
key interrupt occur 3 times!
。。。
结果还是悲剧的。。无限费解?!?!
这是何解呢??
请大家指教 |