ARM异常
---------------------------------------------------------
Author :tiger-john
WebSite :blog.csdn.net/tigerjb
Email :[email protected]
Update-Time : 2011年2月17日星期四
Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人联系或留言给我。3Q
---------------------------------------------------------
一前言:
异常?
1. 只要正常的程序流被暂时中止,处理器就进入异常模式
2.如果同时发生两个或更多异常,那么将按照固定的顺序来处理异常。
异常有那些?
异常有:复位,数据中止,未定义中止,预取值中止,软件中断。
如果有两个以上的不同类型的异常同时发生,那么谁先谁后呢?à(优先级的问题?)
异常优先级:
当多个异常同时发生时,一个固定的优先级决定系统处理它们的顺序:
1 复位
2 数据中止
3 FIQ
4 IRQ
5 预取指中止
6 未定义指令中止
7 软件中断异常
优先级从上往下依次递减
注:
1.未定义的指令和SWI指令互斥。因为同一条指令不能即是未定义的,又能产生有效的软件中断。
2.当FIQ使能,并且FIQ和数据中止异常同时发生时,内核首先进入数据中止处处理程序,然后立即跳转到FIQ向量。
在FIQ处理结束后返回到数据中止处理程序。数据中止的优先级高于FIQ以确保数据转移错误不会被漏过。
二.异常的进入和退出
那么当系统进入异常时,内核会做那些事呢?反之,当退出异常时,内核又会做那些事呢?
何时进入异常?
从何处进?
从何时退?
1. 何时进入异常:
A. 处理器复位后进入管理模式,操作系统通常处于管理模式
B. 当处理器访问存储器失败时,进入数据访问中止模式
C. 对处理器遇到没有定义或不支持的指令时,进入未定义指令模式
D. 中断模式与快速中断模式分别对应ARM的2中不同级别的中断作出响应。
2. 异常的进入
当一个异常导致模式切换时,内核自动的做如下处理:
1> 将异常处理程序的返回地址(加固定的偏移量)保存到相应异常模式下的LR(为以后能返回做准备)
2> 将CPSR的当前值保存到相应异常模式下的SPSR(为以后能复原CPSR中的值做准备)
3> 设置CPSR为相应的异常模式。
4> 设置PC为相应异常处理程序的中断入口向量地址,跳转到相应的异常中断处理程序执行。
注:在第四步中提到了异常中断入口向量地址,每个异常的地址都是固定的。现在我们就来看一个图来体验下异常向量表
注:
1>异常总是在ARM状态中进行处理。当处理器处于Thumb状态时发生了异常,在异常向量地址装入PC时,会自动切换到ARM状态。
2>在进入异常时,系统会强制将I为置1来禁止中断,这样可防止不受控制的异常嵌套。
3.异常的退出
当异常处理程序结束时,异常处理程序必须:
1> 返回到发生异常中断的指令的下一条指令处执行,即将LR中的值减去偏移量后移入PC
2> 将SPSR的值复制回CPSR中。
3> 清零在入口处置位的中断禁止标志。
4. 异常入口/出口汇总
三.具体的各个异常处理
1.IRQ异常模式
1>.进入IRQ异常模式的前提条件
A. 只有当CPSR中相应的中断屏蔽位被清除时,才可能发生IRQ异常。
B. 中断请求(IRQ)异常通常由一个nIRQ输入断的低电平所产生的正常中断
C. 中断异常产生时,中断异常模式下的R14保存的是PC的值。
2>进入IRQ中断模式下的工作流程:
程序运行在用户模式下,当一个IRQ异常模式发生时,内核切换到中断模式。并自动做如下处理:
A. 将异常处理程序的返回地址保存到异常模式下的R14中(R14_irq)
注:由于ARM处理器的三级流水线结构,当异常发生时,程序计数器PC总是指向返回位置的下一条指令即第三条指令。即异常处理程序的正确返回地址为PC-4,且在PC-8的地址处发生异常中断程序跳转,由此可见,R14保存的是指向第三条指令的程序计数器PC(地址),即“中断返回地址+4”。
B. 用户模式下的CPSR被保存到新的IRQ中断异常模式下的SPSR_irq中。
C. 修改CPSR,禁止新的IRQ中断产生,进入ARM状态,设置为IRQ模式。
D. 设置IRQ模式下的PC值为异常处理程序的中断入口 向量地址0x00000018.
E. 将IRQ中断异常模式的栈顶指针保存到R13_irq中,之后软件处理程序调用中断服务程序为中断源服务。
注:如果用户要嵌套IRQ中断,那么必须在中断服务程序中重新使能IRQ中断,并将R14压入堆栈R13之中以预先保留返回地址。通过异常IRQ中断向量,程序将跳到异常中断服务程序ISR。程序应当首先通过压入IRQ堆栈来预先保留ISR将会使用的R0~R12的值,这时就可以对异常进行处理了。
3.>退出IRQ异常模式
A.从R13_irq中获取IRQ中断异常模式的栈顶指针
B.将SPSR_irq中内容复制回CPSR
C.由于流水线的特性,将R14_irq指向的地址减去一个偏移量后存入R15(PC)中。
SUBS PC,R14_irq,#4
2.FIQ异常模式:
由于在ARM状态中,快中断模式有8个专用的寄存器可用来满足寄存器保护的需要。因此也就加速了上下文的切换速度。因此,也就导致了快速中断适用于对一个突发时间的快速响应。
1> 在特权模式下,可以通过置位CPSR中的F位来禁止FIQ异常。
2> FIQ通过执行下面的指令从中断返回:
SUBS PC,R14,#4
3> 指令1在指令过程中产生了FIQ中断。完成指令1的执行后才响应中断。
FIQ中断响应过程中,硬件自动执行如下动作:
A. 将CPSR寄存器内容存入IRQ模式的CPSR寄存器中
B. 置位F和I(禁止FIQ和IRQ中断)
C. 清零T位(进入ARM状态);
D. 设置MOD位,切换处理器模式为FIQ模式。
E. 将下一条命令的地址存入FIQ模式的LR寄存器(即指令3的地址)
F. 将跳转地址存入PC,即FIQ中断服务函数的入口地址,实现跳转
G. FIQ中断服务程序在ARM状态下执行现场保护等等操作。
4> FIQ中断异常处理结束后,异常处理程序完成以下动作
A将SPSR寄存器的值复制回CPSR寄存器
B.将LR寄存器的值减去一个常量(FIQ异常为4)后复制到PC寄存器,跳转到被中断的用户程序(指令2的地址)
注:在中断入口地址的安排上,FIQ处于所有异常入口的最后,这样安排可以让直接从FIQ(0X001C)就开始安排服务程序,而不需要再次跳转。
3.未定义的指令异常
1>未定义指令异常异常是内部异常中断。
2>当ARM处理器遇到一条自己和系统内部任何协处理器都无法执行的指令时,就会发生未定义指令异常,从而进入中断处理程序。
3>软件可以使用这一机制通过仿真未定义的协处理器指令来扩张ARM指令集合。
1> 在仿真失败的指令后,捕获处理器执行下面的指令:
MOVS PC,R14
5> 通过程序来模拟未定指令的执行过程
4. 数据中止
1> 当发生数据中止异常时,异常会在“导致异常的指令”执行后的下一条指令处发生。因此在处理完异常后,再重新执行导致异常的指令。于是就将返回2条指令。
2> 处理器必须通过执行下面的指令返回:
SUBS PC,R14,#8
5. 预取指中止
1> 当发生预取指中止时,ARM内核将预取的指令标记为无效,但只有当指令到达流水线的执行阶段时才进入异常。如果指令在流水线中因为发生分支而没有被执行,中止将不会发生。
2> 处理器会通过下面的指令返回:
SUBS PC,R14,#4
6. SWI软件中断异常
所有的任务都是在用户模式下运行的,因此任务只能读CPSR而不能写CPSR。任务切换到特权模式的唯一途径,就是使用一个SWI指令调用。SWI指令强迫处理器从用户模式切换到SVC管理模式,并使IRQ中断自动关闭。所以软件中断方式常被用于系统调用。
1> 软件中断异常(SWI)用于进入管理模式,通常用于请求一个特定的管理函数。
2> SWI处理程序通过执行下面的指令返回
MOVS PC,R14
补充一个概念:
l 中断延迟:从外部中断请求信号发出到执行对应的中断服务程序ISR的第一条指令所需要的时间。
通过软件程序设计来缩短中断延迟的方法有:中断优先级和中断嵌套。