BF518的interrupt

来源:互联网 发布:淘宝价格趋势图 编辑:程序博客网 时间:2024/05/11 01:51

BF518有32个外设可以产生中断信号。这些中断信号,要经过很多道关卡才能到达中断服务程序。

1. SIC_ISR(System Interrupt Status Register)。由两个16bit寄存器SIC_ISR0SIC_ISR1组成,它们是只读的。中断信号首先到达这里,SIC_ISR会记录下信号。如果中断在SIC_IMASK被挡住了,信号就会停留在SIC_ISR中,当SIC_IMASK打开时,再继续通过,中断服务程序被启动之后,我们需要手动清除中断源的中断信号,SIC_ISR相应bit也会被自动清零。

2. SIC_IWR(System Interrupt Wakeup-Enable Register)。由两个16bit寄存器SIC_IWR0SIC_IWR1组成。信号到达这里时,可以将Core从Idle状态中唤醒。0表示不唤醒,1表示唤醒。

3. SIC_IMASK(System Interrupt Mask Register)。由两个16bit寄存器SIC_IMASK0SIC_IMASK1组成。中断信号到达这里,如果该位为0则禁止通过,如果为1则允许通过。

4. SIC_IAR(System Interrupt Assignment Register)。由8个16位寄存器SIC_IAR1-7组成,共128bit。其中4bit为一组,分为32组,每组管理一个系统中断源。可以把系统中断源映射到IVG7-IVG159个内核中断源上。如果有多个中断源映射到了一个内核中断上时,这些中断信号时逻辑与的关系。而IVG0-IVG6这几个高优先级的中断,是留给内核中断源的,外设的中断源是没有资格来触发的(Core Timer除外,它占用了IVG6)。这前四个寄存器都是以SIC(System Interrupt Control)为前缀,说明都是在system的范围,它们都使用系统时钟,通过了这一关,中断信号就进入了core的范围,使用内核时钟了。

5. ILATInterrupt Latch)。16bit的寄存器。ILAT会记录进入内核并且没有被服务过的中断信号。

6. IMASKInterrupt Mask)。16bit的寄存器。这里又是一层阻挡。

7. IPENDInterrupt Pending)。16bit的寄存器。中断信号通过IPEND时,会被记录下来。IPEND相应bit被置位,而同时ILAT相应bit被清零。

8. EVTEvent Vector Table)。EVT不是一个寄存器,而是一个查找表。我们可以用register_handler(ik_xxxx, function_name);这种方式修改其中的项。ik_xxxx是内核中断源的代码,比如ik_ivg7(这些玩意的定义在exception.h中)。function_name是中断服务程序名。通过EVT找出中断服务程序并运行。

9. 中断服务程序执行完毕,RTI指令会清除IPEND相应的位。所以ILATIPEND都不用我们操心清除,而SIC_ISR则需要我们自己去清除。

如果我们想初始化一个外设的中断,至少要做以下步骤:

1. EX_INTERRUPT_HANDLER(function_name)的形式写一个中断服务程序。

2. 打开SIC_IMASK相应位

3. 看这个中断源默认对应哪个内核中断源

4. register_handler(ik_xxxx, function_name)的形式把内核中断源和中断服务程序关联起来。这一步骤会自动打开IMASK相应位。

5. 打开外设的中断使能


1 0