您的位置:首页 > 其它

中断处理流程分析

2015-05-17 11:18 218 查看
当计算机正在当前指令时,此时发生了异常,那么在执行完当前指令后就要进行异常处理。跳转到相应的异常中断处理程序,同时保存当前执行现场,中断执行完成,返回执行现场的下条指令。

这里先了解异常相应的优先级,当多个异常发生时,由优先级的高低依次响应处理
异常中断处理过程(这里暂不考虑异常中断嵌套问题,默认为在ARM下处理异常):
     ----》当发生中断异常
     ----》(1)自动拷贝CPSR寄存器中数据到SPSR_<mode>
     ----》(2)修改CPSR寄存器中的[4:0]=mode,[T]=0设置为arm态,设置中断禁止[7:6];
     ----》(3)保存返回地址到(R14)lr_<mode>
     ----》(4)根基异常类型,跳转异常向量表
异常向量表在RAM启动代码中是这样写的:
Vectors    
 (  地址偏移量 )

                      LDR     PC, Reset_Addr        ; 0x00000000
               
      LDR     PC, Undef_Addr ;0x00000004
                   
      LDR     PC, SWI_Addr 
;0x00000008
                
      LDR     PC, PAbt_Addr ;0x0000000c
               
      LDR     PC, DAbt_Addr ;0x00000010
               
      NOP                            
        ;0x00000014
; Reserved Vector 
                
      LDR     PC, IRQ_Addr 
;0x00000018
               
      LDR     PC, FIQ_Addr 
;0x0000001c

     ----》(5)进入相应的处理程序后,处理先保护现场(压栈)
     ----》(6)进行相应的中断处理(中断处理操作)
     ----》(7)处理结束后,将SPSR加载到CPSR
     ----》(8)恢复现场(出栈)
     ----》(9)将lr_<mode>给pc(恢复pc地址继续执行)。

在中断异常处理过程中,在进行处理程序时,要进行现场保护,(不能原破坏指令流水线),即压栈操作,处理完后要恢复现场(出栈恢复)。

以模拟FIQ发生压栈为例: 

                MRS  R0,CPSR
;/* read CPSR value             */     
BIC  R0,R0,#0x1f
;/* clear low 5 bit             */     
ORR  R0,R0,#0x11
;/* set the mode as FIQ mode    */  
MSR  CPSR_cxfs,R0
LDR
 LR,=Ret

B
Vectors+0x1c                          ;/* 0x1c为相对异常向量表中基地址的偏移量跳转至 FIQ mode  */  

FIQ_Handler

        STMFD   SP!, {R0-R3, LR}
   ;保护现场,压栈保护公共寄存器,LR_fiq=返回地址 FIQ模式
        BL      FIQ_Handle                     ;调用中断处理程序ISR (进行相应的操作)   
LDMFD   SP!, {R0-R3, pc}^
   ;恢复现场,出栈恢复LR_fiq,R0-R3
        SUBS    PC,  LR,  #4  
   ;调整返回地址SPSR_fiq->CPSR, PC=LR_fiq-4

在不同的异常类型,LR链接寄存器的中的值与恢复流水线执行指令的偏移量不同。由于ARM的流水线特性(ARM7:三级流水线),pc在执行一条指令时,已经指向当前指令后的第二条指令,所以,当IRQ异常发生时,链接寄存器lr的值其实是最后执行的指令的地址+8.返回时应该跳到异常处理前最后一条指令的下一条指令。

下表给出了各种异常应使用的lr偏移:
异常                           地址                   用法
复位                           -                   没有定义
数据中止                    lr - 8               指向导致数据中止异常的那条指令(数据中断,处理方式一般是尝试着再次进行对数据存取操作,因此lr - 8)
 FIQ                           lr - 4               FIQ处理程序的返回地址
 IRQ                           lr - 4               IRQ处理程序的返回地址
 预取指中止                lr - 4              指向导致预取指中止异常的那条指令
 SWI                           lr                    指向SWI指令的下一条指令
 未定义指令                lr                    指向未定义指令的下一条指令
 
      另外,如果指令以pc为目标,且有后缀s,那么cpsr将自动从spsr中恢复,可以节省指令。用LDM的后缀^也有同样的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  arm 异常处理