微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM1176JZF-S/S3C6410处理器的异常处理过程

ARM1176JZF-S/S3C6410处理器的异常处理过程

时间:11-09 来源:互联网 点击:
本来准备总结一下ARM1176JZF-S/S3C6410处理器异常处理过程,但是发现《嵌入式系统Linux内核开发实战指南》一书中的这一部分讲解得非常简明和清楚。所以就不再重复发明轮子,不过我会在以下的引用中做一些补充。

进入异常中断处理

ARM处理器发生异常中断,则ARM处理器进入如下异常中断自动处理过程(假设发生的异常中断对应的模式为mode):

  1. 将当前程序状态寄存器CPSR的值保存到SPSR_mode中;
  2. 将CPSR中的模式位设置成mode模式,将CPSR中的bit7(I)设置为1,禁止IRQ中断,如果是FIQ中断,则再将CPSR中的bit6(F)设置为1,禁止FIQ中断;
  3. 将返回地址传给lr_mode;
  4. 将该异常中断的向量地址传给程序计数器pc,从而进入异常中断处理程序。

退出异常中断处理

当要从异常中断处理程序中返回时,要做以下两步操作(假设发生的异常中断对应的模式为mode):

  1. 将保存在SPSR_mode中的值恢复到当前程序状态寄存器CPSR中;
  2. 返回到发生异常中断的指令的下一条指令处执行,也就是将lr_mode寄存器的值适当地返回到程序计数器pc中。

但程序员只需做好上述第二步即可,第一步在完成第二步的同时由处理器自动完成,所以我们下面讲解从各种异常中断处理返回的编程接口。

退出复位异常中断处理(Reset)

复位异常中断处理程序不需要返回,所以不需要这个接口。

退出未定义指令异常中断处理(Undefined Instruction)

未定义指令异常中断由当前执行的指令自身产生,当未定义指令异常中断产生时,程序计数器pc的值还未更新,它指向当前指令后面第2条指令(对于ARM指令,它指向当前指令地址加8字节的位置;对于Thumb指令,它指向当前指令地址加4字节的位置),当未定义指令异常中断发生时,处理器将值(pc-4)保存到lr_und中,此时(pc-4)指向当前指令的下一条指令,所以从未定义指令异常中断返回可以通过如下指令来实现:

mov pc, lr

该指令将寄存器lr_mode中的值到程序计数器pc中,实现程序返回,同时将SPSR_mode寄存器中的值到当前程序状态寄存器CPSR中。

如果要在异常中断处理中使用数据栈,那么可以在进入异常中断处理程序时保存被中断程序的执行现场,在退出异常中断处理程序时恢复被中断程序的执行现场,编程如下:

stmfd sp!, {register_list, lr} ;保存被中断程序的执行现场
; . . .
ldmfd sp!, {register_list, pc}^ ;恢复被中断程序的执行现场

上面的register_list,是异常中断处理程序中使用的寄存器列表,标识符^表示要将SPSR_mode寄存器中的值到当前程序状态寄存器CPSR中。

退出软中断指令(SWI)异常中断处理(Undefined Instruction)

SWI异常中断和未定义异常中断指令一样,也是由当前执行的指令自身产生,当SWI指令执行时,pc的值还未更新,它指向当前指令后面第2条指令(对于ARM指令,它指向当前指令地址加8字节的位置;对于Thumb指令,它指向当前指令地址加4字节的位置),当未定义指令异常中断发生时,处理器将值(pc-4)保存到lr_svc中,此时(pc-4)指向当前指令的下一条指令,所以从SWI异常中断处理返回的实现方法与从未定义指令异常中断处理返回一样:

mov pc, lr

使用数据栈的方法与未定义指令异常中断处理中的方法也一样:

stmfd sp!, {register_list, lr} ;保存被中断程序的执行现场
; . . .
ldmfd sp!, {register_list, pc}^ ;恢复被中断程序的执行现场

退出指令预取中止异常中断处理(Prefetch Abort)

在指令预取时,如果目标地址是非法的,该指令被标记成有问题的指令,这时,流水线上该指令之前的指令继续执行,当执行到该被标记成有问题的指令时,处理器产生指令预取中止异常中断。发生指令预取异常中断时,程序要返回到该有问题的指令处,重新读取并执行该指令,因此指令预取中止异常中断应该返回到产生该指令预取中止异常中断的指令处,而不是当前指令的下一条指令。

指令预取中止异常中断由当前执行的指令自身产生,当指令预取中止异常中断发生时,程序计数器pc的值还未更新,它指向当前指令后面第2条指令(对于ARM指令,它指向当前指令地址加8字节的位置;对于Thumb指令,它指向当前指令地址加4字节的位置)。此时处理器将值(pc-4)保存到lr_abt中,它指向当前指令的下一条指令,所以返回操作可以通过下面指令实现:

subs pc, lr, #4

该指令将lr中的值减4后传给程序计数器pc中,实现程序返回,同时将SPSR_abt寄存器的内容到当前程序状态寄存器CPSR中。

如果要在指令预取中止异常中断处理中使用数据栈,可以用以下方法保护、恢复被中断程序的执行现场:

subs lr, lr, #4
stmfd sp!, {register_list, lr} ;保存被中断程序的执行现场
; . . .
ldmfd sp!, {register_list, pc}^ ;恢复被中断程序的执行现场

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top