新闻中心

ARM的中断原理

作者: 时间:2016-11-11 来源:网络 收藏
1.中断概述

CPU与外设的数据传输方式通常有以下3种方式:查询方式、中断方式、DMA方式。

本文引用地址://m.amcfsurvey.com/article/201611/316975.htm

所谓查询方式是指,CPU不到查询外设的状态,如果外设准备就绪则开始进行数据传输;如果外设还没有准备好,CPU将进入循环等待状态。很显然这样浪费了大量的CPU时间,降低了CPU的利用率。

所谓中断方式是指,当外设准备好与CPU进行数据传输时,外设首先向CPU发出中断请求,CPU接收到中断请求并在一定条件下,暂时停止原来的程序并执行中断服务处理程序,执行完毕以后再返回原来的程序继续执行。由此可见,采用中断方式避免了CPU把大量的时间花费在查询外设状态的操作上,从而大大提高了CPU的执行效率。
ARM系统 包括两类中断:一类是IRQ中断,另一类是FIQ中断。IRQ是普通中断,FIQ是快速中断,在进行大批量的复制、数据传输等工作时,常使用FIQ中断。FIQ的优先级高于IRQ。
在ARM系统中,支持7类异常,包括:复位、未定义指令、软中断、预取中止、数据中止、IRQ和FIQ,每种异常对应于不同的处理器模式。一旦发生异常,首先要进行模式切换,然后程序将转到该异常对应的固定存储地址执行。这个固定的地址称为异常向量。异常向量中保存的通常为异常处理程序的地址。ARM的异常向量如下:
异常 模式 正常地址 高向量地址
复位管理 0x00000000 0xFFFF0000
未定义指令 未定义0x00000004 0xFFFF 0004
软中断 管理 0x00000008 0xFFFF 0008

预取指中止 中止 0x0000000C 0xFFFF 000C
数据中止 中止 0x00000010 0xFFFF0010
IRQ IRQ 0x000000180xFFFF0018
FIQ FIQ 0x0000001C 0xFFFF 001C

由此可见,IRQ中断和FIQ中断都属于ARM的异常模式。在ARM系统中,一旦有中断发生,不管是外部中断,还是内部中断,正在执行的程序都会停下来。接下来通常会按照如下步骤处理中断:

(1)保存现场。保存当前的PC值到R14,保存当前的程序运行状态到SPSR。
(2)模式切换。根据发生的中断类型,进入IRQ模式或FIQ模式。
(3)获取中断源。以异常向量表保存在低地址处为例,若是IRQ中断,则PC指针跳动0x18处;若是FIQ中断,则跳到0x1C处。IRQ和FIQ的异常向量地址处一般保存的是中断服务子程序的地址,所以接下来PC指针跳入中断服务子程序处理中断。
(4)中断处理。
(5)中断返回,恢复现场。当完成中断服务子程序后,将SPSR中保存的程序运行状态恢复到CPSR中,R14中保存的被中断程序的地址恢复到PC中,继续执行被中断的程序。
2.S3C2410A的中断控制器
ARM920T CPU的中断可分为FIQ和IRQ。为了使CPU能够响应中断,必须首先对程序状态寄存器(PSR)中的F位和I位进行正确设置。如果PSR的F位为1,则CPU不会响应来自中断控制器的FIQ中断;如果PSR的I位为1,则CPU不会响应来自中断控制器的IRQ中断。因此,为了使中断控制器能够接收中断请求,必须在启动代码中将PSR中的F位和I位设置为0,同时还需要将中断屏蔽寄存器(INTMSK)中的相应位设置为0。
中断屏蔽寄存器用于指示中断是否禁止。设置为1表示相应中断禁止,为0则发生中断时正常执行中断服务。如果发生中断时相应的屏蔽位正好为1,则中断挂起寄存器中的相应中断源挂起位将置1。
S3C2410A有2个中断挂起寄存器:中断源挂起寄存器(SPCPND)和中断挂起寄存器(INTPND)。这两个挂起寄存器用于指示某个中断请求是否处于挂起状态。当多个中断源请求中断服务时,SRCPND寄存器中的相应位置1,仲裁过程结束后INTPND寄存器中只有1位被自动置1。
S3C2410A中的中断控制器能够接收来自56个中断源的请求。见芯片手册,由于引脚有限,因此采用了共享中断技术。由芯片手册可知S3C2410A共有32个中断请求信号。中断请求的优先级逻辑是由7个仲裁器组成的,其中包括6个一级仲裁器和1个二级仲裁器。每个仲裁器是否使能由寄存器PRIORITY[6:0]决定。每个仲裁器可以处理4~6个中断源,从中选出优先级最高的。优先级顺序由寄存器PRIORITY[20:7]的相应位决定。
要想使用S3C2410A的中断控制器,必须对以下列出的寄存器进行正确配置。以下寄存器中的每一位含义参阅芯片手册。
寄存器地址 描述 复位值
SRCPND0x4A000000 中断源挂起寄存器,当中断产生后,相应位置1 0x0
INTMOD0x4A000004 中断模式寄存器0=IRQ模式,1=FIQ模式 0x0
INTMSK0x4A00 0008 中断屏蔽寄存器 0=中断允许,1=中断蔽0xFFFFFFF

PRIORITY0x4A00000C 中断优先级控制寄存器,设置中断优先级 0x7F
INTPND0x4A000010 中断挂起寄存器,只是中断请求的状态。 0x0
0=该中断没有请求 1=该中断源发出中断请求

INTOFFSET0x4A000014 中断偏移寄存器,只是IRQ中断源 0x0
SUBSRCPND0x4A000018子中断源挂起寄存器,指示中断请求的状态0x0
0=该中断没有请求 1=该中断源发出中断请求

INTSUBMSK0x4A00 001C定义哪个中断源屏蔽 0=中断服务允许,1=中断服务屏 0x7FF
所有来自中断源的中断请求首先被登记到中断源挂起寄存器中。在中断模式寄存器,中断请求分成两类:FIQ和IRQ。多个IRQ中断的仲裁过程在优先级寄存器进行。
中断源挂起寄存器可以看作各种中断有无请求的状态标志寄存器。相应位置1,说明存在该中断请求;相应位为0,说明该中断请求产生。
中断模式寄存器主要用于配置该中断是IRQ型中断,还是FIQ型中断。


3.中断编程实例
介绍一个通过定时器1中断控制CPU板上的LED1和LED2实现轮流闪烁的实例,需要完成的主要工作如下:
(1)对定时器1初始化,并设定定时器的中断时间为1s,据代码参见Timer1_init()函数。
void Timer1_init(void){

rGPCON=rGPGCON&0xfff0ffff|0x00050000; //配置GPG口为输出口

rGPGDAT=rGPGDAT|0x300;
rTCFG0=255;

rTCFG1=0
rTCNTB1=48828; //在pclk=50MHz下,1s的记数值rTCNTB1=50000000/4/256=48828
rTCMPB1=0x00;
rTCON=(1
rTCON=(1
}
(2)为了使CPU响应中断,在中断服务子程序执行之前,必须打开ARM920T的CPSR中的I位,以及相应的中断屏蔽寄存器中的位。打开相应的中断屏蔽寄存器的位,是在Timer1INT_Init()函数中实现,具体代码如下。
void Timer1INT_Init(void){
//定时器接口使能
if((rINTPND&BIT_TIMER1)){
rSRCPND|=BIT_TIMER1;
}
pISR_TIMER1=(int)Timer1_ISR;
//写入定时器1中断服务子程序的入口地址
rINTMSK&=~(BIT_TIMER1);
//开中断
}
(3)等待定时器中断,通过一个死循环如“while(1);”实现等待过程。
(4)根据设置的定时时间,产生定时器中断。中断发生后,首先进行现场保护,然后转入中断的入口代码处执行。该部分代码通常使用汇编语言编写。在执行中断服务程序之前,要确保HandleIRQ地址处保存中断分发程序IsrIRQ的入口地址,代码如下:
ldrr0,=HandleIRQ
ldrr1,=IsrIRQ
strr1,[r0]


接下来将执行IsrIRQ中断分发程序,具体代码如下。
IsrIRQ
subsp,sp,#4 ;为保存PC预留堆栈空间
stmfdsp!,{r8-r9}
ldrr9,=INTOFFSET
ldrr9,[r9] ;加载INTOFFSET寄存器值到r9
ldrr8,=HandleEINT0;加载中断向量表的基地址到r8
addr8,r8,r9,lsl#2;获得中断向量
ldrr8,[r8] ;加载中断服务程序的入口地址到r8
strr8,[sp,#8] ;保存sp,将其作为新的pc值
ldmfd sp!,{r8-r9,pc};跳转到新的pc处执行,即跳转到中断服务子程序执行


(5)执行中断服务子程序,该子程序实现将LED1和LED2灯熄灭或点亮。从现象中看到LED1和LED2灯闪烁一次,就说明定时器发生了一次中断。具体实现见函数Timer1_ISR().
int flag;
void_ _irq Timer1_ISR(void){
if(flag==0){
rGPGDAT=rGPGDAT&0xeff|0x200;
flag=1;
}else{
rGPGDAT=rGPGDAT&0xdff|0x100;
flag=0;
}
rSRCPND|=BIT_TIMER1;
rINTPND|=BIT_TIMER1;
}
(6)从中断中返回,恢复现场,跳转到被中断的主程序继续执行,等待下一次中断的到来。



关键词:ARM中断原

评论


技术专区

关闭