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

第十二章 中断控制器与外部中断

本章代码,查看我的github网站:https://github.com/weiqi7777/…

1、异常处理的2个阶段

1) 异常向量表跳转

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

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

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

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

2、210的中断控制器

210包括4个VIC(vectored 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,这个是中断的物理号,每个中断对应一个。应用层使用的是中断的物理号,所以底层代码需要处理,将中断的物理号转换为对应寄存器的对应位。

以下是中断相关的寄存器

2.1、VICIRQSTATUS

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

2.2、VICFIQSTATUS

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

2.3、VICRAWINTR

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

2.4、VINCINTSELECT

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

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

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

2.5、VICINTENABLE

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

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

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

2.6、VICINTENCLEAR

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

2.7、VICSOFTINT

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

2.8、VICSOFTINTCLEAR

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

2.9、VICPROTECTION

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

2.10、VICADDRESS

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

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

2.11、VICSWPRIORITYMASK

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

2.12、VICVECTADDR[0-31]

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

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

2.13、VICVECTPRIORITY[0-31]

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

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

3、中断设置流程
3.1、流程

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

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

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

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

3.2、中断2部分工作

中断的工作分为2部分:

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

1) 初始化中断控制器

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

3) 相应中断的使能

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

1) 经过异常向量表跳转入IRQ/FIQ的入口

2) 做中断现场保护(在start.S)中,然后跳入isr_handler

3) 在isr_handler中先找到哪个VIC中断了,然后直接去这个VIC的VICADDR寄存器中取出isr地址执行

4) Isr执行完,中断现场恢复,直接返回继续做常规任务。

4、外部中断

外部中断属于VIC0。

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

关键寄存器, CON,PEND, MASK

4.1、GPxnCON

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

4.2、EXT_CON

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

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

4.3、EXT_PEND

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

4.4、EXT_MASK

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

4.5、EXT_FILTER

中断滤波寄存器

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

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

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

5、外部中断编程实践
5.1、外部中断对应的GPIO模式设置

5.2、中断触发模式设置

5.3、中断允许、清挂起

5.4、中断处理程序isr编写

系列其他篇

  • CORTEX-A8裸机系列:第十章 时钟
  • CORTEX-A8裸机系列:第十一章 串口

原文首发于骏的世界博客
作者:卢骏.
更多Arm技术相关的文章请关注Arm技术博客极术专栏,每日更新。

发表评论

邮箱地址不会被公开。 必填项已用*标注