weiqi7777

cortex-a8裸机系列:第十二章 中断控制器与外部中断

0
阅读(2179)

一、            异常处理的2个阶段

1、  异常向量表跳转

依赖于CPU设计时自动提供的异常向量表的机制,也就是当异常发生时,硬件能自动的跳转到异常向量表执行。

该阶段主要任务是产生异常前后的现场保存/恢复现场,跳转到真正的异常处理程序。

2、  进入了真正的异常处理程序

通过判断寄存器,得知是哪一类的中断产生,然后再检查子类中断寄存器,查看具体是哪一个中断产生,然后跳转到对应的程序执行。

二、            210的中断控制器

         210包括4VICvectored interrupt controller)。

 

当要清除中断挂起,需要往VICADDRESS寄存器(VIC0ADDRESS,VIC1ADDRESS,VIC2ADDRESS,VIC3ADDRESS)写入0

 

210支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源,(理论上210最多支持128个中断源,但是实际上只有93个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在中断处理程序中依次查询4个中断源寄存器,看哪一个的哪一位置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。

于是计算中断编号就比较麻烦了,很耗费时间,就影响了实时性。(实时性就是中断发生到响应的时间,这个时间越短越好)。

所以210开拓了一种全新的寻找isr的机制。210提供了很多寄存器来解决每个中断源对应isr的寻找问题。这些都是硬件来实现的。

 

210的中断号有两种,一个是VIC port no,表示的是在寄存器中的偏移,另外一个是No,这个是中断的物理号,每个中断对应一个。应用层使用的是中断的物理号,所以底层代码需要处理,将中断的物理号转换为对应寄存器的对应位。

clip_image002

 

寄存器

1.    VICIRQSTATUS

中断源在屏蔽之后的状态。为1,说明中断有效。

clip_image004

2.    VICFIQSTATUS

快速中断源在屏蔽之后的状态

clip_image006

3.    VICRAWINTR

中断源未屏蔽之前的状态,这个寄存器,表明中断源的原始状态,但是CPU是否响应该中断,还需要后续的一些设置(需要看VINCINTENABLEVICINESELECT寄存器)才行。

clip_image008

4.    VINCINTSELECT

中断的选择,是选择普通中断还是快中断。

210支持两种中断,irqfiqIrq是普通中断,fiq是快速中断。快速中断提供了一种更快响应处理的中断通道,用于对实时性要求很高的中断源。FiqCPU设计时预先提供了一些机制保证fiq可以被快速处理,从而保证实时性。Fiq的限制就是只能有一个中断源被设置为fiq,其他都是irq

CPU是如何保证fiqirq快?一、fiq模式有专用的r8-r12寄存器,因此在fiqisr中可以直接使用r8-r12而不用保存,这就能节省时间。二、异常向量表中fiq是最后一个异常向量入口,因此fiqisr不需要跳转,这样就比其他异常少跳转了一次,省了函数跳转的时间。

clip_image010

 

5.    VICINTENABLE

中断使能寄存器,负责相应的中断的使能,也就是当中断产生时,CPU是否要响应该中断。只要在这个中断编号对应的VICINTENABLE响应位写1即可。

     这个寄存器写1才有效果,写0没有效果。

          该寄存器可读可写,读的话,是得到中断是否使能的状态,1是使能,0是不使能。

clip_image012

 

6.    VICINTENCLEAR   

中断除能寄存器,负责相应的中断的除能,往相应寄存器相应的位写入1,就对该中断禁止了。

clip_image014

 

7.    VICSOFTINT

软中断寄存器,产生软中断,也就是软件往这个寄存器的某些位写1,那么就会触发软件中断,CPU会执行该位对应的中断处理函数。

clip_image016

8.    VICSOFTINTCLEAR    

软中断除能寄存器。将对应的软中断给除能。使用软中断,CPU执行完中断后,因为软中断没有被清除,所以又会执行中断。所以要在中断处理程序中,将软中断给清除掉,避免再次进入中断。

clip_image018

9.    VICPROTECTION

  中断保护模式寄存器。开启保护模式后,中断中只有特权模式才能访问中断控制器寄存器,用户模式下是不能访问中断控制器寄存器的。如果没有开启的话,用户模式和特权模式都是可以访问中断控制器寄存器的。

clip_image020

10.         VICADDRESS

  中断地址寄存器,当对应中断产生的时候,硬件会将中断处理函数地址赋值给这个寄存器。

     在中断处理函数结束后,要往中断地址寄存器写入任意值,以清除中断挂起。

clip_image022

11.         VICSWPRIORITYMASK

    屏蔽优先级中断寄存器。设置这个寄存器,可以屏蔽某些优先级的中断,使CPU不响应这些优先级的中断。

clip_image024

12.         VICVECTADDR[0-31]

   中断异常程序地址寄存器,这个是一个寄存器组,共有32个,每一个对应一个中断的中断处理函数的地址。当对应中断产生的时候,硬件会从该中断号对应的中断地址寄存器,取出该执行的中断处理函数的地址,然后赋值给PC,就执行中断处理函数了。

      VICVECTADD0-3132个寄存器分别用来存放真正的各个中断对应的isr的函数地址。相当于每一个中断源都有一个VECTADDR寄存器,设置中断的时候,把这个中断的isr地址直接放入到这个中断对应的VECTADDR寄存器即可。

clip_image026

 

13.         VICVECTPRIORITY[0-31]

中断优先级寄存器,设置中断的优先级,有效值是0-15

设置多个中断同时发生时先处理谁后处理谁的问题。一般来说高优先级的中断可以打断低优先级的中断,从而嵌套处理中断。

clip_image028

三、            中断设置流程

1.         绑定异常向量表到异常处理程序,禁止所有中断源,选择所有中断类型为IRQ,清除VICADDR寄存器为0

2.         中断的使能和禁止:根据终端号判断这个中断属于VIC几,然后再中断源减去这个VIC的偏移量,得到这个中断号在本VIC中的偏移量,然后1<<x位,写入相应的VICINTENABLE/INTENCLEAR寄存器即可

3.         绑定实现的ISEVICnVECTADDRVICVECTADDR寄存器共有4*32个,每个中断源都有一个VECTADDR寄存器,我们应该将为这个中断源写的isr地址写入到这个中断源对应的VECTADDR寄存器中即可

4.         发生中断时,硬件会自动把相应中断源的isr地址从VICnVECTADDR寄存器中保存在VICnADDR寄存器中,所以第二阶段的中断处理程序中,判断是哪一个VIC发生中断,只需要判断哪一个VICVICnIRQSTATUS不为0,就说明该VIC发生了中断。然后将该VICVICADDR赋值给函数指针,然后去执行该函数。

clip_image030

 

         中断的工作分为2部分:

         第一部分是我们为中断响应而做的预备工作:

                   初始化中断控制器

                   绑定写好的isr到中断控制器

                   相应中断的使能

第二部分是硬件产生中断后自动执行isr

         第一步:经过异常向量表跳转入IRQ/FIQ的入口

    第二步:做中断现场保护(在start.S)中,然后跳入isr_handler

第三步:在isr_handler中先找到哪个VIC中断了,然后直接去这个VICVICADDR寄存器中取出isr地址执行

         第四步:Isr执行完,中断现场恢复,直接返回继续做常规任务。

四、         外部中断

         外部中断属于VIC0

clip_image032

         外部中断0-15是各自单独占有一个中断源,中断16-31是公用一个中断源,EINT 16_31

         关键寄存器, CONPEND MASK

1.    GPxnCON

配置GPIO管脚为外部中断,GPHn为外部中断源。

clip_image034

2.    EXT_CON

配置外部中断的触发方式。触发方式就是外部中断产生的条件。

触发方式有两种:电平触发和边沿触发。

clip_image036

 

               

3.    EXT_PEND

中断挂起寄存器,每一位对应一个外部中断,没有中断产生值为0。发生中断后,硬件会自动将这个寄存器该中断对应的位置为1

clip_image038

4.    EXT_MASK

中断屏蔽寄存器。用来屏蔽中断的,如果对应位设置为1,那么该位对应的中断是被屏蔽的。

clip_image040

 

5.    EXT_FILTER

  中断滤波寄存器

clip_image042

    有两种滤波方式,一种是Delay filter,一种是Digital filter

   

clip_image044

Delay filter是固定延时(和时钟没有关系),35ns,也就是当中断第一次检测到后,35ns后会再次检测一下,如果第二次检测中断确实产生,就认为中断产生,然后CPU执行中断。这个可以用在电平中断中,滤除电平毛刺。

Digital filter,数字滤波,和时钟是有关系的。滤波时间是时钟的周期*滤波周期数,每隔滤波周期数时间去检测一个中断,这里的时钟应该用的是PCLK,也就是GPIOCLK。这个可以用在边沿触发的中断中,滤除抖动。

五、            外部中断编程实践

1.    外部中断对应的GPIO模式设置

clip_image046

2.    中断触发模式设置

clip_image047

3.    中断允许、清挂起

clip_image048

4.    中断处理程序isr编写

clip_image049