最近在学ARM9的裸板编程,中断对设备的控制特别重要,故了解其过程非常重要。
下图可以看到整个中断机制的硬件处理过程。
S3C2440的datasheet里面写着ARM芯片总共有60个中断源,网友也有讨论过不是60个之类的,但是我们以datasheet为准。中断源分内部中断源和外部中断源,I/O的属于外部中断源。
中断能否成功处理,有两部分,1是触发中断信号,2是ARM能否识别中断。
1触发中断信号,很简单,有高电平,低电平,上升沿,下降沿触发四种,至于用那种需要程序员来设置。可是一个设备能否具有触发中断信号的能力,还要看它是否是中断源,这个就要查datasheet了,看看那个引脚接的控制器是否有中断源标志。
2是CPU能否识别中断信号并处理,大家会说,这个简单啊,中断一发过来ARM就会自动处理的啊。实际上,在上面的图可以看出,一个中断信号传到给ARM前,还得经过中断控制器的处理。这个中断处理器的作用是用于集中处理中断信号的筛选和排序的功能。因为60个中断源,在中断控制器里会有对应的控制寄存器控制着,包括状态标志和中断开关。比如说一个二级中断传过来二级中控器,该寄存器相应状态标志的位会变为1,如果这是对应位的开关是0,那么这个中断也就无法往下传了,也就是说信号即使可以触发,但没有传到给ARM处理,那也是没有用的。如果开关是1,那么中断信号也是可以传到下一级的一级中控器的,当然,如果还要往ARM里面传中断信号,这个一级中控器的开关也是要设置为1才行。
综上所述,我们要写一个由中断信号来处理的程序。首先,把我们要控制的设备(前提它属于中断源之一)设置状态为中断信号,第二是把该设备的中断方式(刚才所说的四种之一)设置好。这样我们就完成了设置触发中断信号的工作。接下来就是要让ARM识别我们的中断,也就是要把相应的寄存器来设置好开关即可,这部分我们要查看设备的属于二级中断或外部中断,还是一级中断,然后把相关的开关打开就可以了。
下图是整个中断流程里的寄存器对应表,写代码参考十分有用。
下面给个二级中断设置的思路,我以IRQ中断方式来举例:
比如我们要触发的是INT_TC这个二级中断信号。好,那么我们要打开的开关是什么呢?在二级中断信号里,INTSUBMSK是二级中断信号的开关,我们要在里面找到INT_TC这个位并设置为1即可。二级中断还得传到一级中控器处理,那么我们先找出INT_TC是属于哪个一级中断信号的,看表里的紫色框起来的是二级属于同一个一级信号的,一级信号处理那个也有个紫色框,INT_ADC就是我们要找到的对应一级信号。而它也有对应的开关,那么就是INTMSK这个控制器。我们把INTMSK里的INT_ADC位设置为1就算成功了。
代码也就是
INTSUBMSK |= ( 0x1 << 9);//因为INT_TC在INTSUBMSK里的第9位,注意从0开始
INTMSK |= (0x1 << 31); //INT_ADC在INTMSK里的第31位。
其他的类似外部中断也是这样操作。只是一级中断的可以直接从一级中控器处理,那么就只设置一级中控器的相应开关即可。也就是说,我们要用到的设备接口,我们就把相应的开关打开就可以了,其他的让ARM来处理就可以了。
这里备注两个问题:
1 为什么要分一级中断和二级中断还有外部中断呢?
答:因为ARM有六十个中断源。一个寄存器有32位,用一个位来标志一个中断源,那肯定不够用。所以我们要用二级中断源还有外部中断源来作为一个二级的解析。我们又会问,为什么二级中断里会有好几个合在一起在一级中控器里?前面说了,不够用,还有一个就是,我们要清楚,在一个中断控制寄存器里,同一时间里只会有一位是为1的,放到IRQ里面,还会有个处理优先级的控制器,会根据优先级来处理哪个中断信号先处理。
2 INTMOD是什么?
答:中断的模式分为FIQ(快速中断)和IRQ(普通中断),前者设置标志寄存器INTMOD的相应位即表示该中断为快速中断,快速中断不用经过优先级的筛选,直接传给ARM处理。而后者就是我们上面的例子说的那种,还需要筛选和处理优先级才能传给优先级。
以上是ARM的中断机制的一些处理方式,但是要写出完整的中断处理代码,我们暂时只是踏出了第一步,请继续看下一篇文章,中断的清除。
http://blog.chinaunix.net/uid-24641004-id-3395857.html