|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、中断概念:
6 ~, D. x8 q: V- t0 i4 TCPU 在执行当前程序的过程中因硬件或软件的原因插入了另一段程序运行的过程5 G% s8 `* K* N1 @1 d& |3 \) O) z
硬件引起的中断不可预测,随机性
" i3 H, ~( d$ I( U A$ O, M软中断:事先在程序中安排特殊指令,CPU 执行到该类指令时,转去执行相应的一段预先安排好的程序,然后再返回来执行原来的程序
! Y* K" E- s' d
: \6 r- ~; L+ ^5 {+ N1 j 二、ARM 体系异常分类:
; V% E9 |' F3 i复位异常(Reset)5 O) P( l w. [. j/ j2 B) U! B6 {
数据异常(Data Abort)
/ }- U# K. `/ x; v& {快速中断异常(FIQ)% f5 N s( Z |+ b- c( n
外部中断异常(IRQ)
* c2 ]: g+ M _+ O% v/ J, J* z9 {8 E6 y预取异常(Prefetch Abort)
4 D7 w+ Z% l& F: g/ S( P软中断异常(SWI)& b9 s) g; G/ M3 K& Y" M' p
未定义异常(Undefined interrupt)
/ n4 k, l' {" X& I8 ~- i3 C) |! J( K. ?8 A" r, e, D
三、异常处理伪代码及 7 种异常( L9 E0 s3 ^4 ` r
异常处理伪代码:
- Y! C1 y) R- d5 s5 i8 Y: \+ |) C T8 Q' F7 W( Q# }
R14_<exception_mode> = return link! ?7 [4 B! C' @+ v
* L# e2 D# z& L
SPSR_<exception_mode> = CPSR7 h. {% d/ [' o6 Z% u0 o0 y
3 [! t# U; ^9 e& x: E3 X' W+ `
CPSR[4:0] = exception mode number2 X! `2 Q0 J2 P, [. c4 \( a
) B; _/ |2 o0 e: L. x2 d CPSR[5] = 0 /*进入 ARM 状态*/& E/ `3 c) _% g5 N1 X
( Y Z0 D! e6 \
If <enception_mode> == reset or FIQ then
: @5 D; S) U0 I4 I% S% l0 w! j
, [5 p2 [, u! c/ Z3 v W4 x CPSR[6] = 1 /*屏蔽快速中断 FIQ*/
4 X N: j- Z* e" ^* q2 j1 p: R3 r; i) }
% g( u% z' k5 b! H# S5 Z CPSR[7] = 1 /*屏蔽外部中断 IRQ*/
# X% G2 Z1 V9 _* V( b8 U5 ?! `; ~
6 n ~4 j& O0 k% d) k: q PC = exception vector address
4 F- D: t6 Y1 w( R7 J2 Q复位异常
, y) I: \9 h. E; ~概念2 a; i0 Y+ {8 n ]% l" ?( X
; d2 e) M1 `1 ? g& i
当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行,复位异常中断通常用于系统上电和系统复位两种情况。
' U& K' T+ _! T: s7 J- n8 g步骤:' x+ j6 t: v! s1 `/ a- K/ a
: x( W+ F( n) _* I8 x$ }
设置异常中断向量表
?: N& b1 `( J' d4 @% l" [9 [( m7 k
初始化数据栈和寄存器
2 a$ b4 E+ q/ C: Z0 @9 I# Q& V4 W, K h
初始化存储系统,如系统中的 MMU" `/ g& H6 p8 S, _% K" i
( {# C* K$ b4 X6 r: H 初始化关键的 I/O 设备- S4 R+ c& D! ]: U$ T
+ B; l9 ~8 S8 p' G0 }, Q( ^' h: k
使能中断' r2 I0 Z( B* |6 R
8 n0 o3 T$ s5 G( _4 \ 处理器切换到合适的模式0 B& S6 P- E# L
) A2 K+ t1 {1 e& M) V 初始化C变量,跳转到应用程序执行
1 I9 U2 j0 F' z伪代码
1 B& u0 i0 v+ { N) l/ W8 h; R! m; f( h4 Q% }7 r5 X
R14_svc = UNPREDICTABLE value: h1 k: b" f6 ?4 O& i+ @; @6 E) r9 ?
4 q! v! \8 a8 T F9 S+ I b: E# p
SPSR_svc = UNPREDICTABLE value
Z8 s) T$ O% e0 N/ i+ c9 n# }5 t ~% z5 G! E" H l9 w
CPSR[4:0] = 0B10011 /*进入特权模式*/
3 O9 l/ X) f- n( l, V! X9 t' \7 p: D( [1 d# E
CPSR[5] = 0 /*处理器进入 ARM 态*/, U% c) R* P8 Q8 {2 M
4 D3 m. j s8 ]! G7 ^" A$ t
CPSR[6] = 1 /*禁止快速中断*/$ M+ [/ i( A" x4 x9 b# p
# e+ X6 w ^* S* @1 ~
CPSR[7] = 1 /*禁止外设中断*/
; I, `) W) g* w; j7 A
3 V3 w; U0 ?. Q1 x( N5 B& N1 n If high vectors configured then% e% T6 ^& G5 u; |3 \( j) y
: ]. ~% x$ A4 ]: a PC = 0xffff0000% t8 Y' a! M7 _* v0 D/ t
" A, h3 a6 c/ n1 [! s" { Else; P! x: A2 n* F$ N, p
% N$ }! `/ r9 C
PC = 0x00000000
4 a. _1 q! R- V1 ~+ X未定义指令异常
: m" ]4 `) F2 `' ]) z$ f概念+ n6 ?4 ?/ f# V+ q! ?" P4 B+ {$ ?
1 a0 [3 |& I* `4 e0 Q; m 当 ARM 处理器执行协处理器指令时,它必须等待一个外部协处理器答应后,才能真正执行这条指令。若协处理器没有响应,则发生未定义指令异常。未定义指令异常可用于在没有物理协处理器的系统上,对协处理器进行软件仿真,或通过软件仿真实现指令集扩展。; w8 n9 ~9 K" Y( p: s
步骤
, Z% C" {2 h0 F& Y* y2 l将仿真程序入口地址链接到向量表中未定义指令异常中断入口处(0x00000004 或 0xffff0004),并保存原来的中断处理程序, L1 Q( H- U+ b6 l6 ]6 b' B$ P7 R! f
读取该未定义指令的 bits[27:24],判断其是否是一条协处理器指令。如果 bits[27:24]值为 0b1110 或 0b110x,则该指令是一条协处理器指令;否则由软件仿真实现协处理器功能,可以通过 bits[11:8] 来判断要仿真的协处理器功能(类似于 SWI 异常实现机制): ~: f0 @. P! B% b/ D& A1 s
如果不仿真该未定义指令,则程序跳转到原来的未定义指令异常中断的中断处理程序行
* ?1 I- @5 _. b! c- m4 ^伪代码
! O( C# H s! e9 v6 C( |' F4 K$ {) G: V3 U( @7 Q3 }4 z( P
r14_und = address of next instruction after the undefined instruction+ | c/ R+ p% M5 C6 ~
, P- o% o( J8 ~/ e4 O SPSR_und = CPSR
* Q; y q* b/ r5 l- N$ i! R+ p, T% P; U& }
CPSR[4:0] = 0b11011 /*进入未定义指令模式*/
; @! V; B: K. N* w
l! n; T0 ]6 L1 K CPSR[5] = 0 /*处理器进入 ARM 状态*/
+ d9 X- t0 ~$ R; }% W* l
}9 c6 v. Z+ A. Y /*CPSR[6] 保持不变*/8 i0 t3 C) V& T2 M/ o/ ^
7 J2 @8 k3 d' n! U& y3 T
CPSR[7] = 1 /*禁止外设中断*/5 X% `7 Y$ r; ? l& j
+ C4 r& G j& [6 z/ @' J6 X$ } If high vectors configured then! q+ }* k; ^& f
+ ]0 y ~/ M/ E4 h# E5 [ PC = 0xffff00004
) }" p+ g4 |1 d6 K5 {! @: `- Y1 j. X) Q, I9 N9 E' g V" Y" u
Else
" [+ P& k) q- N
. k( p7 V% V) F/ V" C, g+ u PC = 0x00000004
' [. h8 M. U4 ^- z/ G) c+ m软中断异常
5 q5 d& T, ?; h$ Q( [- J, h概念
h8 |) b7 Z6 c. u3 G& ~' I' @' P1 I' V, n- E, ]
这是一个由用户定义的中断指令(SWI)。该异常由执行 SWI 指令产生,可用于用户模式下的程序调用特权操作指令。在实时操作系统中可以通过该机制实现系统功能调用。6 w: `" e* u7 {/ C/ f/ b
伪代码
( U7 J7 p: I2 M( g: q2 C; d" x
z1 F0 @( I5 } r14_svc = address of next instruction after the SWI instruction
; V, x$ t9 y; t2 k1 I) ~5 R0 ?# o% u x0 {! k' s, p7 {# l
SPSR_und = CPSR$ d$ z2 Q* ~; u- B, X; p
) q4 _! {# J1 V: \9 P9 K0 T CPSR[4:0] = 0b10011 /*进入特权模式*/
% K5 p7 R. }2 s+ |9 V/ F8 w3 |
+ m3 e, k0 s$ k: y9 a, j* Y5 ^ CPSR[5] = 0 /*处理器进入 ARM 态*/
: S4 s. |- c! a2 S8 M! [
6 y$ j% n# B" d1 V /*CPSR[6] 保持不变*/
/ ^" S# U# L3 T$ T0 J$ u
& ], w+ o! t. ~ CPSR[7] = 1 /*禁止外设中断*/. t9 `% K& {1 e( ~. a( {/ {
3 i# h: r; X1 N1 O0 e! a4 {, r If high vectors configured then
, p ], @$ u# Q0 ^, I j
& r7 k# S: C. ?3 E9 a+ g$ s* M PC = 0xffff000C& Z3 K3 o6 u# ^' G0 U0 s9 ]+ v
5 H! v( f) n$ F" u$ |) M$ k8 B# F Else
9 x a: u, k. W( r' }' O1 \4 b% q1 x$ J1 c" {& d' o
PC = 0x0000000C6 g1 _2 c2 c1 {1 ]" B( Q2 m4 k
预取异常
' l6 I* r9 ~: Q概念& R1 u& P7 u+ G# Z8 d6 m& Y
# N, S8 x' [* Y/ J R
预取异常是由系统存储器报告的。当处理器预取的指令的地址不存在,或者该地址不允许当前指令访问(权限不够)时,将产生预取异常。 {2 ?0 n: C$ A6 u9 u
( e1 ]& Q, S8 L$ U! `8 q5 z+ R" U
如果系统中不包含 MMU,指令预取异常中断处理程序只是简单地报告错误并退出;若包含 MMU,引起异常的指令的物理地址被存储到内存中。
( y* a+ ^, ], m. N+ k( C; M伪代码
, P- z8 B6 i2 y1 s3 N/ l8 D) G
|1 R7 [ E& f, \ r14_svc = address of the aborted instruction + 4" J6 x4 [# d8 G8 o' H
8 \ e8 q# f( f5 G, b. I/ p
SPSR_und = CPSR% ^$ ^) L# r" r; }% c- [" n3 p
: h. s3 O% v* r& \# \6 M
CPSR[4:0] = 0b10111" R. l7 `- f* U5 b& F$ R- ~3 P6 {
1 @* A- s5 z# r, W4 H
CPSR[5] = 0) \: W$ v6 T- |2 U" A# t! Z) U$ Y
: K0 H8 ]/ I( M* w* w; ]
/*CPSR[6] 保持不变*/
" v2 X b% e; _' E6 s1 a7 o
6 }; G! A7 q0 ?+ m$ N; x3 G CPSR[7] = 1 /*禁止外设中断*/
3 H8 a" ^. |$ d/ m& n9 z: ]% ?& X! R F% E1 J
If high vectors configured then5 K* S1 V* m) H. ~5 I
' F8 ?% `/ O* U9 u' J# ^! Q
PC = 0xffff000c( r% R# y& S: ]# w3 s! q- r0 r/ x
! ]- W z9 f2 i8 W; w5 V# j3 D1 l) [
Else0 r: [+ L2 n& R; g: m
- V* ~: n" K5 D7 D
PC = 0x0000000c
# U# m6 P# p2 q) p0 q) C% a数据异常
- j7 C2 x- c9 \" M概念
1 b$ Y ]0 K" Z& z, `- c
! F7 |2 ^# C. q D- y( { 数据异常是由存储器发生数据中止信号,它由存储器访问指令 Load/Store 产生。 & T* c6 j3 f$ M0 a8 v3 S* `
. S K# O% l/ q 当数据访问指令的目标地址不存在,或者该地址不允许当前指令访问(权限不够)时,将产生数据访问中止异常。
+ c3 f6 P( w4 o% |产生数据访问中止异常时,寄存器的值修改规则
" I T, f% l8 }8 e1 pr14 的值只与发生数据异常的指令地址有关,与 PC 值无关
% l$ X& a0 E; v. D9 ]如果指令中没有指定基址寄存器回写,则基址寄存器的值不变, N8 |* ?1 S! B. r: y u! K
如果指令中指定了基址寄存器回写,则寄存器的值和具体芯片的 Abort Models 有关,由芯片的生成商指定
: C/ \0 f- ?" F3 M6 q' _如果指令只加载一个通用寄存器的值,则通用寄存器的值不变
6 _2 e% K$ H" t如果是批量加载指令,则寄存器中的值不可预知
/ H/ ?5 Z( g; n. {. X N如果指令加载协处理器寄存器的值,则被加载寄存器的值不可预知, Z) \ p6 g: Q8 @& Z+ ]7 `
伪代码
C1 }" Q3 I. A8 D. W+ C4 i" G! r4 f7 G$ p* G
r14_abt = address of the aborted instruction + 8+ n# k# r, [# @) k" q) a
5 U s9 D& S2 k: ]% [$ s SPSR_abt = CPSR0 d6 N' P5 h2 ?4 F" u8 J
# T' @8 Z0 N$ D7 K2 [
CPSR[4:0] = 0b10111* J8 o" K% u6 n2 d+ D# ~8 a
' d0 {- N# A8 J4 p CPSR[5] = 0' W, t: I g2 f9 T7 F/ E
5 i% O" Y: X$ L& s
/*CPSR[6] 保持不变*/
" G% g3 t' Y/ d( Q! p
4 f9 `' o# L, K; B CPSR[7] = 1 /*禁止外设中断*/ m9 f% V3 R: R5 _0 [) J; q. u
6 H4 T; h1 t# W, Y5 C If high vectors configured then
& d, D. e, n% n+ Q7 u3 u, l9 ]; E3 c. d; | Q3 y
PC = 0xffff0010& i$ _3 K4 @; `$ n& N. H
2 j9 I3 C$ G9 V8 a' U2 q
Else2 b0 b5 Z" t2 z0 P% Z6 P# j- V
8 `, i0 L" x3 m$ ~* s PC = 0x000000109 x8 |. s0 b4 F% `
外部中断异常% ?. ~+ V( Z# T2 U8 F1 @9 t
概念! [$ C7 [' {: g, ?9 c, f
/ }2 [% g) Z3 @* `" x& h) {
当处理器的外部中断请求引脚有效,而且 CPSR 的寄存器的 I 控制位被清除时,处理器产生外部中断请求异常中断。系统中各外设通过该异常中断请求处理服务。
, P) q* j2 @5 `2 O5 k伪代码
% {3 R0 U; t- M8 l
! F3 w6 s9 E7 x+ K r14_abt = address of the next instruction to be executed + 4
9 x5 }( Q$ u7 t9 {6 M; b
; ] }, x/ Z( O9 Y5 {' K SPSR_irq = CPSR
0 e+ i3 c z8 |# ^5 R; Y6 [ p9 b9 ~' M$ C( V. Z& v# y$ L
CPSR[4:0] = 0b10010 /*进入特权模式*/( \* p- h8 M. t6 l Q9 J6 V
b+ b9 c$ X3 \: V2 I
CPSR[5] = 0 /*处理器进入 ARM 状态*/6 G0 \) O) j, Z, A( d, r
* i7 F t! b8 V8 p7 H /*CPSR[6] 保持不变*/+ i L: q( J+ U' G( g
9 D) p: E1 z1 q8 g1 _ CPSR[7] = 1 /*禁止外设中断*/
( r( }8 J, b5 T. m
) l5 g" ^2 t' j6 X7 j+ V$ l m If high vectors configured then) y3 }* K( X3 }8 i3 m, v! [, }
?9 n: u: ]7 ?, T& L% O* k) n, X* G
PC = 0xffff00181 A c& r+ g! z* ^# v
O7 c7 g j0 a P8 j, G
Else6 y" E B; O) Z( H4 u; F X! Q2 a4 d
! f: D+ K) B& p PC = 0x00000018! G6 T* T8 \/ D" V/ i/ ~
快速中断异常
. |7 _3 R7 C2 b" t; p概念
/ K# m/ l/ d& S; _3 _
q: m5 l$ H0 e3 k5 Z9 n9 M% e6 c 当处理器的外部快速中断请求引脚有效,而且 CPSR 的 F 控制位被清除时,处理器产生外部快速中断请求异常中断。
1 Q2 [; G, w9 ^+ l+ L伪代码# u% w8 F; u6 W4 R
. Z2 r3 Z) N$ L& C4 q5 @! V r14_abt = address of the next instruction to be executed + 8
5 R2 u6 A' m; l2 x+ }# m
4 F' I( u( x! y" G; V/ W. M SPSR_fiq= CPSR. f& j& j" }) C" |& I/ n' D
, u+ Y1 W2 U! J8 r5 ]# B CPSR[4:0] = 0b10001 /*进入FIQ模式*/; k {+ f" O% K. ^0 i9 G) U
& Q- }) K7 R! K/ ?( a& }6 m
CPSR[5] = 0
$ G0 S! W! u; I9 [/ O
, F+ H$ [! o; x4 Q+ R. ? CPSR[6] = 1
+ d6 e4 H) F3 k7 C7 K: `6 R! T$ R/ Z7 `0 T; Z) D
CPSR[7] = 1 /*禁止外设中断*/
% q5 K6 I! C6 Z8 Y
! h3 p9 ?6 i, K+ x1 Q# u If high vectors configured then
]: I* P/ Y# P
. O7 C2 D, M0 v) m# J PC = 0xffff001c
4 E! ?+ O" A7 G2 W# A7 J7 E4 o9 l- g( T9 M3 \: e$ f0 v
Else2 J! r" N- @' J/ a
! A: n3 S: ^* r6 x J0 \
PC = 0x0000001c
- c Q+ q3 j* V% w) s2 }# H/ W8 | Z M9 {' a! W: @7 ]( s
5 U+ I, M7 ]5 S, B7 x. ~4 ^7 I- z# i7 @! R4 F$ V+ i
7 M1 F6 n( U( k0 s . I, x- Z! @$ Q8 J2 v
4 Z0 }2 q$ B+ A5 ~" p3 \. L, R2 m7 l) y! e4 @! f
四、FIQ 与 IRQ 比较( m! c- ~& ~% _" u) |& T$ D
相同点
( P- ~; i$ W X都只是普通中断:
. @+ h9 b- a x; A* f$ {: C4 {: B2 h/ W3 O6 P# `
当我们程序定义了该中断,并且在程序运行的时候产生了 IRQ/FIQ 中断,则此时的芯片运行过程:①中断处理器利用IRQ请求线来告诉ARM,②ARM切换到 IRQ/FIQ 模式运行' \9 j; e% |2 o
不同点
- c- m' c: t+ l" |' j- _FIQ 速度快,IRQ 速度慢,原因:
3 A$ x/ K. s* vFIQ模式提供了更多的寄存器,r8-r14 和 SPSR,而 IRQ 模式只有 r13-r14 和 SPSR,这就意味着在ARM的IRQ模式下,中断处理程序自己要保存R8到R12这几个寄存器,然后退出中断处理时程序要恢复这几个寄存器,而FIQ模式由于这几个寄存器都有banked寄存器,模式切换时CPU自动保存这些值到banked寄存器,退出FIQ模式时自动恢复,所以这个过程FIQ比IRQ快.不要小看这几个寄存器,ARM在编译的时候,如果你FIQ中断处理程序足够用这几个独立的寄存器来运作,它就不会进行通用寄存器的压栈,这样也省了一些时间。
5 a4 X. F) L& H& T8 qFIQ 比 IRQ 有更高优先级,如果 FIQ 和 IRQ 同时产生,那么 FIQ 先处理。, y. p2 a W8 T N; Q
在symbian系统里,当CPU处于FIQ模式处理FIQ中断的过程中,预取指令异常,未定义指令异常,软中断全被禁止,所有的中断被屏蔽。所以FIQ就会很快执行,不会被其他异常或者中断打断,所以它又比IRQ快了。而IRQ不一样,当ARM处理IRQ模式处理IRQ中断时,如果来了一个FIQ中断请求,那正在执行的IRQ中断处理程序会被抢断,ARM切换到FIQ模式去执行这个FIQ,所以FIQ比IRQ快多了。7 [2 l: L. J4 T/ X' W/ A
另外FIQ的入口地址是0x1c,IRQ的入口地址是0x18。写过完整汇编系统的都比较明白这点的差别,18只能放一条指令,为了不与1C处的FIQ冲突,这个地方只能跳转,而FIQ不一样,1C以后没有任何中断向量表了,这样可以直接在1C处放FIQ的中断处理程序,由于跳转的范围限制,至少少了一条跳转指令。
' W8 x& o; @; I4 Q+ D7 ~
* d& B5 }$ a" d" _. x, z$ _
' n0 o3 k/ q/ P" `8 f" {6 x |
|