ARM单片机三种中断返回情况的分析与解决
ARM单片机是大多数新手选择的入门切入点,但由于知识的不足,在设计过程中新手们经常会遇到这样或那样的问题,ARM异常中断返回就是这样一种令人头疼的问题。在ARM的使用问题中异常中断返回是新手们较为苦恼的问题,本文就将对ARM异常中断的集中情况进行总结,并给出了一些解决方法。
在正式介绍之前,要为大家补充一些较为重要的基础知识。首先R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三条指令。当ARM状态时,每条指令为4字节长,所以PC始终指向该指令地址加8字节的地址,即:PC值=当前程序执行位置+8;而ADS中的pc,是为了调试看着方便而修改过的,它指向的是正在执行的指令,即“真正pc-8”!
SWI和未定义指令异常中断的返回
指令地址:
A PC-8当前指令为SWI或未定义指令,此时发生中断.PC的值还没有更新。
A+4 PC-4中断时处理器将PC-4保存到LR。;r!
A+8 PC
返回时,从发生中断的指令A(PC-8)的下一条指令A+4(PC-4)处开始执行,所以直接把LR的值赋给PC就行了,具体指令为MOV PC,LR(PC=A+4=LR)。
白话解释:对于SWI和未定义指令发生异常时pc没有更新,根据ARM的三级流水线原理,pc没有更新,仍然等于(A+8);lr = pc – 4(这时处理器决定的,无法更改!)即A+4。
由于这类异常返回后应执行下一条指令(A+4),所以返回时,pc=lr即可。
IRQ 和FIQ异常中断处理的返回指令地址对应于PC A,PC-8执行此指令完成后(!)查询IRQ及FIQ,如果有中断请求则产生中断。
A+4 PC-4
A+8 PC ;lr!
(此时PC的值已经更新,指向A+12.将当前PC-4,即A+8)。
保存到LR.返回时,要接着执行A+4(LR-4)处的指令,所以返回指令为:
SUBS PC,LR,#4(PC=A+4=LR-4)
白话解释:对于普中断和快中断异常,中断必须在一条指令执行完以后被检测到,如正在执行指令甲时发生了中断,不等指令甲执行完是不会处理该中断的,发生异常时pc已经更新(A+12); lr=pc– 4(这时处理器决定的,无法更改!)即A+8返回后,应执行被中断而没有执行的指令(上面的A+4),所以返回时,pc= lr-4。
指令预取中止异常中断处理的返回
指令地址:
A PC-8 执行本指令时发生中断,A+4 PC-4处理器将A+4(PC-4)保存到:
LR. ;lr!A+8 PC
返回时,发生指令预取中止的指令A(PC-8)处重新执行,所以返回指令为SUBS PC,LR,#4(PC=A=LR-4)。
白话解释:对于预取指令中止异常发生预取指令异常时,是在执行时发生的异常,pc未更新,即pc=A+8;lr=pc – 4(这时处理器决定的,无法更改!)即A+4。
由于这类异常返回后应重新执行异常的那个指令(A),所以返回时,pc = lr-4。
数据访问中止异常中断处理的返回
指令地址:
A PC-8 本指令访问有问题的数据,产生中断时,PC的值已经更新。
A+4 PC-4 中断发生时PC=A+12,处理器将A+8(PC-4)保存到LR.。
A+8 PC ;lr!
返回时,要返回到A处继续执行,所以指令为SUBS PC,LR,#8.(PC=A=LR-8)
白话解释:对于数据访问中止异常时,是在执行时访问数据错误。
导致的异常,pc已经更新,即pc=A+12。
lr=pc–4(这时处理器决定的,无法更改!)即A+8。
由于这类异常返回后应重新执行异常的那个指令(A),所以返回时,pc=lr-8。
总结
引起PC更新的原因一种是数据中止,还有就是中断了。
中断必须是在一条指令执行完毕后才能被检测到,所以它中断的只是还未执行的那条。指令(pc-8),所以pc=lr – 4;
与中断相同,SWI和未定义指令异常也是返回到下一条指令(pc-4),只是他们在执行时,PC的值并没有更新,所以pc= lr。
预取指令中止异常,也没有发生pc更新,但它还得重新执行发生异常的那条指令,所以pc=lr–4。
数据访问中止异常,发生了pc更新,并且它也需要重新执行发生异常的那条指令,所以pc=lr–8。
通过以上的介绍,可以看到造成单片机中断返回的原因非常多,每种方法的应对方案都不尽相同。在ARM芯片调试过程中遇到中断返回问题的朋友不妨仔细阅读本文,相信会从中找到问题的解决方法。也可收藏本文以备不时之需,在遇到错误的时候进行查阅。
干货|一文读懂单片机里面的“中断”优先级
中断优先级的内容,有一般紧急的中断,有特别紧急的中断,这取决于具体的系统设计,这就涉及到中断优先级和中断嵌套的概念,今天先简单介绍一下相关寄存器,不做例程说明。
中断的产生背景,实际生活当中还有更复杂的,比如我正在看电视,这个时候来电话了,我要进入接电话的“中断”程序当中去,就在接电话的同时,听到了水开的声音,水开的“中断”也发生了,我们就必须要放下手上的电话,先把煤气关掉,然后再回来听电话,最后听完了电话再看电视,这里就产生了一个优先级的问题。
还有一种情况,我们在看电视的时候,这个时候听到水开的声音,水开的“中断”发生了,我们要进入关煤气的“中断”程序当中,而在关煤气的同时,电话声音响了,而这个时候,我们的处理方式是先把煤气关闭,再去接听电话,最后再看电视。
从这两个过程中,我们可以得到一个结论,就是最最紧急的事情,一旦发生后,我们不管当时处在哪个“程序”当中,我们必须先去处理最最紧急的事情,处理完毕后再去解决其它事情。
在我们的单片机程序当中有时候也是这样的,有一般紧急的中断,有特别紧急的中断,这取决于具体的系统设计,这就涉及到中断优先级和中断嵌套的概念,今天先简单介绍一下相关寄存器,不做例程说明。
中断优先级有两种,一种是抢占优先级,一种是固有优先级,先介绍抢占优先级。来看表1和表2。
表1: IP——中断优先级寄存器的位分配(地址0xB8、可位寻址)
表2: IP——中断优先级寄存器的位描述
IP 这个寄存器的每一位,表示对应中断的抢占优先级,每一位的复位值都是 0,当我们把某一位设置为 1 的时候,这一位的优先级就比其它位的优先级高了。
比如我们设置了 PT0位为 1 后,当单片机在主循环或者任何其它中断程序中执行时,一旦定时器 T0 发生中断,作为更高的优先级,程序马上就会跑到 T0 的中断程序中来执行。
反过来,当单片机正在 T0中断程序中执行时,如果有其它中断发生了,还是会继续执行 T0 中断程序,直到把 T0 中的中断程序执行完毕以后,才会去执行其它中断程序。
当进入低优先级中断中执行时,如又发生了高优先级的中断,则立刻进入高优先级中断执行,处理完高优先级级中断后,再返回处理低优先级中断,这个过程就叫做中断嵌套,也称为抢占。
所以抢占优先级的概念就是,优先级高的中断可以打断优先级低的中断的执行,从而形成嵌套。当然反过来,优先级低的中断是不能打断优先级高的中断的。
表3: 中断查询序列
那么既然有抢占优先级,自然就也有非抢占优先级了,也称为固有优先级。在表3中的最后一列给出的就是固有优先级,请注意,在中断优先级的编号中,一般都是数字越小优先级越高。
从表3中可以看到一共有 1~6 共 6 级的优先级,这里的优先级与抢占优先级的一个不同点就是,它不具有抢占的特性,也就是说即使在低优先级中断执行过程中又发生了高优先级的中断,那么这个高优先级的中断也只能等到低优先级中断执行完后才能得到响应。既然不能抢占,那么这个优先级有什么用呢?
答案是多个中断同时存在时的仲裁。比如说有多个中断同时发生了,当然实际上发生这种情况的概率很低,但另外一种情况就常见的多了,那就是出于某种原因我们暂时关闭了总中断,即 EA=0,执行完一段代码后又重新使能了总中断,即 EA=1,那么在这段时间里就很可能有多个中断都发生了,但因为总中断是关闭的,所以它们当时都得不到响应,而当总中断再次使能后,它们就会在同时请求响应了,很明显,这时也必需有个先后顺序才行,这就是非抢占优先级的作用了——如表3中,谁优先级最高先响应谁,然后按编号排队,依次得到响应。
抢占优先级和非抢占优先级的协同,可以使单片机中断系统有条不紊的工作,既不会无休止的嵌套,又可以保证必要时紧急任务得到优先处理。在后续的学习过程中,中断系统会与我们如影随形,处处都有它的身影,随着学习的深入,相信你对它的理解也会更加的深入。
相关问答
单片机 C编程中的return?一个函数可以定义为无返回值的,例如voidds1820_reset(void);在函数之前加入void,那么就不会有return,但是有的时候函数是需要计算出一个结果的,在调用这个函...
在 单片机 中,RET和RETI分别是什么 返回 指令?RETI是中断返回指令;RET是子程序返回指令;RETI比RET多一步清除中断优先级状态位,让同级别的中断有机会得到响应。中断指令“RETI”做为中断...RETI是中...
51 单片机 中ret是什么意思?RETI是中断返回指令;RET是子程序返回指令;RETI比RET多一步清除中断优先级状态位,让同级别的中断有机会得到响应。中断指令“RETI”做为中断...RETI是中...
执行 中断返回 指令后,从堆栈区弹出的地址送给什么寄存器?以51系列单片机为例,RETI中断返回:从堆栈栈顶弹出的两个字节内容(即断点地址)送至程序指针寄存器PC以51系列单片机为例,RETI中断返回:从堆栈栈顶弹出的两...
51 单片机中断 处理分为几部分?51单片机中断处理分为三部分,分别是中断响应、中断处理和中断返回。中断响应是由中断系统自动执行的,包括接收中断源发出的中断请求信号、执行相应的中断服务...
单片机中断 在什么情况下有着不可替代的作用?我天天玩单片机呢!😁单片机中断是在系统应用中非常独特的、实时的。中断的目的就是实时处理突发事件。比如主程是正在计算1+1=2,当一个外中断响应时,程序会立...
单片机中断 汇编开头几行怎么写,地址是什么?51单片机5个中断源的中断程序入口地址分别是:INT0:0003HT0:000BHINT1:0013HT1:001BH串口:0023H一般在相应的中断入口位置写一跳转指令LJMP,在中断服务程序....
51 单片机中断 函数的定义形式?例如定时器0中断:voidtimer0_sev(void)interrupt1timer0_sev是中断程序名称,可自己定interrupt1指的是中断号,不能随意写0123...
单片机 interrupt后面加什么?voidfunctionName()interrupt1//using2类型固定为void即无返回值中断函数名functionName只要是合法标识,不与已有的函数重名即可,且函数固定无...
51 单片机 的 中断 函数何时执行?中断的执行:当CPU正在执行某一程序时,若有中断响应,则CPU转而执行中断服务程序,当中断服务程序执行完毕后,CPU自动返回原来的程序继续执行。中断:当计算机...