新闻中心

EEPW首页>嵌入式系统>设计应用> ARM微处理器的编程模型之:异常中断处理

ARM微处理器的编程模型之:异常中断处理

作者: 时间:2013-09-13 来源:网络 收藏

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

3.4.5 从异常处理程序中返回

当一个异常处理返回时,一共有3件事情需要处理:通用寄存器的恢复、状态寄存器的恢复以及PC指针的恢复。通用寄存器的恢复采用一般的堆栈操作指令即可,下面重点介绍状态寄存器的恢复以及PC指针的恢复。

1.恢复被中断程序的处理器状态

PC和CPSR的恢复可以通过一条指令来实现,下面是3个例子。

· MOVS PC,LR

· SUBS PC,LR,#4

· LDMFD SP!,{PC}^

这几条指令是普通的数据处理指令,特殊之处在于它们把程序计数器寄存器PC作为目标寄存器,并且带了特殊的后缀“S”或“^”。其中“S”或“^”的作用就是使指令在执行时,同时完成从SPSR到CPSR的拷贝,达到恢复状态寄存器的目的。

2.异常的返回地址

异常返回时,另一个非常重要的问题就是返回地址的确定。前面提到过,处理器进入异常时会有一个保存LR的动作,但是该保持值并不一定是正确中断的返回地址。以一个简单的指令执行流水状态图来对此加以说明,如图3.7所示。

图3.7 3级流水线示例

架构里,PC值指向当前执行指令地址加8。也就是说,当执行指令A(地址0x8000)时,PC等于0x8000+8=0x8008,即等于指令C的地址。假设指令A是BL指令,则当执行时,会把PC值(0x8008)保存到LR寄存器。但是,接下来处理器会对LR进行一次自动调整,使LR=LR-0x4。所以,最终保存在LR里面的是图3.5中所示的B指令地址。所以当从BL返回时,LR里面正好是正确的返回地址。

同样的跳转机制在所有的LR自动保存操作中都存在。当进入中断响应时,处理器对保存的LR也进行一次自动调整,并且跳转动作也是LR=LR-0x04。由此,就可以对不同异常类型的返回地址依次比较。

假设在指令B处(地址0x8004)发生了异常,进入异常相应后,LR经过跳转保存的地址值应该是C的地址0x8008。

(1)软中断异常

如果发生软中断异常,即指令B为SWI指令,从SWI中断返回后下一条执行指令就是C,正好是LR寄存器保存的地址,所以只有直接把LR恢复给PC即可。

(2)IRQ或FIQ异常

如果发生的是IRQ或FIQ异常,因为外部中断请求中断了正在执行的指令B,当中断返回后,需要重新回到B指令执行,也就是说,返回地址应该是B(0x8004),需要把LR减4送PC。

(3)Data Abort数据中止异常

在指令B处进入的相应,但导致的原因却应该是上一条指令A。当中断处理程序恢复后,要回到A重新执行导致数据异常的指令,因此返回地址应该是LR加8。

为方便起见,表3.7总结了各异常和返回地址的关系

表3.7 异常和返回地址

异 常

地 址

用 途

复位

复位没有定义LR

数据中止

LR-8

指向导致数据中止异常的指令

FIQ

LR-4

指向发生异常时正在执行的指令

IRQ

LR-4

指向发生异常时正在执行的指令

预取指令中止

LR-4

指向导致预取指令异常的那条指令

SWI

LR

执行SWI指令的下一条指令

未定义指令

LR

指向未定义指令的下一条指令

3.4.6 在应用程序中安装异常处理程序

1.使用汇编语言安装异常处理程序

如果系统启动不依赖于Debug或Debug monitor软件,可以使用汇编语言在系统启动时直接安装异常处理程序。

下面的例子显示了系统从0x0地址启动,直接安装异常处理程序的方法。

Vector_Init_Block

LDR PC, Reset_Addr

LDR PC, Undefined_Addr

LDR PC, SWI_Addr

LDR PC, Prefetch_Addr

LDR PC, Abort_Addr

NOP ;保留向量

LDR PC, IRQ_Addr

LDR PC, FIQ_Addr

Reset_Addr DCD Start_Boot

Undefined_Addr DCD Undefined_Handler

SWI_Addr DCD SWI_Handler

Prefetch_Addr DCD Prefetch_Handler

Abort_Addr DCD Abort_Handler

DCD 0 ;保留向量

IRQ_Addr DCD IRQ_Handler

FIQ_Addr DCD FIQ_Handler



评论


相关推荐

技术专区

关闭