微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm处理器异常处理swi

arm处理器异常处理swi

时间:11-09 来源:互联网 点击:
ARM处理器共有7中运行模式:

用户模式(usr) -- 正常程序执行模式

|-- |-- 快速中断模式(fiq) -- 用于高速数据传输和通道处理

特 | 异 | 外部中断模式(irq) -- 用于通常的中断处理
权 --| 常 --| 管理员模式(svc) -- 供操作系统使用的一种保护模式
模 | 模 | 数据访问中止模式(abt) -- 用于虚拟存储及存储保护
式 | 式 |-- 未定义指令中止模式(und) -- 用于支持通过软件仿真硬件的协处理器
|-- 系统模式(sys) -- 用于运行特权级的操作系统任务

特权模式:fiq、irq、svc、abt、und、sys -- 程序可以访问所有的系统资源,也可以任意切换处理器模式
异常模式:fiq、irq、svc、abt、und

ARM异常中断种类及优先级:
优先级 异常中断名称
高 复位(reset)
|| 数据访问中止(data abort)
|| 快速中断请求(FIQ)
|| 外部中断请求(IRQ)
/||/ 指令预取中止(prefetch abort)
// 软中断(SWI)
低 未定义指令(undefined instruction)

异常向量表:
地址 异常中断名称 优先级
. .
. .
. .
0x1c FIQ 3
0x18 IRQ 4
0x14 Reserved X
0x10 Data Abort 2
0x0c Prefetch Abort 4
0x08 SWI 5
0x04 Undefined Instruction 6
0x00 Reset 1
Vector Table可以位于0x0或者0xFFFF0000处(ARM720T、ARM9、ARM10..)
优先级为3的FIQ为什么放在地址0x1c处呢?当初这么设计应该是为了更加快速地响应FIQ中断,也就是说不在0x1c地
址放跳转指令,而是直接存放最关键的FIQ处理代码在0x1c开始一段地址区域内。

异常进入及返回:
当异常产生时:
1. 拷贝当前模式的CPSR值到相应异常模式的SPSR_,如:CPSR(usr) --> SPSR_svc(svc)。
2. 设置适当的CPSR位:
改变处理器状态进入ARM状态
改变处理器模式进入相应的异常模式
如果需要可以设置中断禁止位禁止相应中断
3. 保存返回地址(pc-4)到LR_
4. 设置pc为相应的异常向量。
异常返回时,需要:
1. 从SPSR_恢复CPSR。
2. 从LR_恢复pc
(只能在ARM状态下实现该返回操作)
异常返回的指令分析:
* 使用一数据处理指令实现,该指令带“S”后缀,同时pc作为目的寄存器
* 在特权模式下不仅仅要更新pc,而且还要拷贝SPSR到CPSR
1. 从SWI和Undef异常返回:
movs pc , lr
这两种异常都会在导致异常的指令执行周期中就进入异常,没有等到下个时钟周期才进入异常,另外这两种异常都是返回到产生异常指令的下一条指令去继续执行。我从前面可以知道lr中保存的就是pc-4(该pc值是产生异常指令的下下一条指令的地址),所以可以直接将lr的值送入pc。
2. 从FIQ、IRQ和Prefect Abort返回:
subs pc , lr , #4
这三种异常都会等待产生异常的指令执行完才会进入异常,所以此刻的pc已经更新,比如:
...
subs r3, r3, #1 < 26 @ 0x100
bcs 2b @ 0x104
subs r1, r1, #1 < 5 @ 0x108
bcs 1b @ 0x10b
...
如果在执行第1行地址为0x100指令时,发生了上面三种异常,此刻的pc值为0x108,等第1行执行完之后,pc更新为0x10b。同时进入异常处理,在异常进入时将lr值保存为pc-4,即0x108。那么在异常返回后,需要接着执行发生异常指令的下一条指令的话就必须将lr的值减去4才能得到正确的地址,lr-4 = 0x108 - 4 = 0x104。
3. 从数据异常(Data Abort)异常返回:
该异常也是会等待产生异常的那条指令执行完才会进入异常,情况类似于第2类的三种异常,但是有一点不同的是:数据异常返回地址不是产生异常的下一条指令,而是产生异常的那条指令,所以,它的返回指令应该是:
subs pc , lr , #8
按照上面的例子就应该返回到地址0x100处继续执行。为什么会这样,因为数据异常返回后会继续去取数据,想想缺页异常。
4. 如果lr在进入异常后被压栈的话,就需要使用下面的指令来弹出。
LDMFD sp! , {pc}^
(^同时拷贝SPSR到CPSR中,这里的lr在压栈之前已经做了前面3中情况对应的处理了)

SWI异常:
执行SWI软中断指令即可产生软中断异常,进入SWI异常时会做如下动作:
CSPR保存到SPSR_svc。
改变处理器状态进入ARM状态
改变处理器模式进入相应的管理员模式(svc)
看需要禁止中断
保存返回地址(pc-4)到LR_svc
设置pc为0x08或者0xFFFF0008
需要注意一点的是:如果在执行SWI指令时系统正处于svc模式时,那么将会覆盖掉原来LR_svc的值。所以
在SWI指令之前应该对LR_svc压栈保存。
SWI异常返回时,做如下动作:
从SPSR_svc恢复CPSR
从LR_svc恢复pc,不需要修正

在c语言中使用关键字“__

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

网站地图

Top