|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
: B/ P9 ]4 I5 Z
9.5 FIQ与IRQ异常中断处理程序
) j& l4 f4 g5 R! N" \9 [$ U- y- E. ]7 F" \& M6 x
ARM提供的FIQ与IRQ用于外部设备向CPU请求中断。& m" z4 l N6 _1 v% S. O
$ z @* U3 s7 K+ I& H+ R2 H2 K3 c6 Y
9.5.1 不可重入的IRQ/FIQ异常中断处理程序
$ `; o$ l9 C0 H* u% z6 J6 }) a, T5 T u1 M/ y6 [- \- _, y
;使用关键词_irq' j# Q# C& V) `2 W
: X% D4 q% K, n. {; R& [
__irq void IRQHandler (void)# s+ S; r( F# [- f, [4 D$ p8 I
{
% c: \7 t7 _% Z1 E w volatile unsigned int *base = (unsigned int *) 0x80000000;' B* l5 \. D( P) q2 X2 B
; B* a" _4 e; X
if (*base == 1) // which interrupt was it?
8 Z/ D, u4 z2 I, T. y* v( d {' b% r5 b9 }6 F8 G. I* @$ {
C_int_handler(); // process the interrupt
2 j' d7 e. n$ X8 U( ]2 U. h }
6 R. G$ |, ]. ^) M/ o *(base+1) = 0; // clear the interrupt' N% W5 n; i# l9 C
}* C; e: d+ Z; A8 M2 @9 j
% o5 N; ^. @# L7 T, @
;对应的汇编程序& @( u3 n. {, U" r j
" y; m. k; o5 v, X$ cIRQHandler PROC
& [8 [% u8 V3 X) j STMFD sp!,{r0-r4,r12,lr}( u% |0 j+ Y7 O7 t3 j9 H5 {: R
MOV r4,#0x800000004 G3 ?" ~* f" A8 L
LDR r0,[r4,#0]# I* i6 }$ i" N" p/ c" K6 P
SUB sp,sp,#4
6 d ^+ `7 B" R* f; x CMP r0,#1 e2 P: w% A1 i) i
BLEQ C_int_handler
m1 n B! R. b' V/ H; M& ?2 G MOV r0,#0! M* m7 A! y* a6 }4 G) n
STR r0,[r4,#4]
3 y2 S- B) K: A ADD sp,sp,#4
( h, |) y" H, Z8 W6 r' u7 F: b" B$ R$ Y LDMFD sp!,{r0-r4,r12,lr}
# H" E7 K& a6 ]4 `+ t6 v SUBS pc,lr,#43 v0 K% t% Y$ J. w. }! c! I4 Z! W/ a
ENDP
' c' ~& d; w* } h$ L% c4 V" C% s7 M* d" ^; _( y& E
;不使用关键词_irq
+ M( a' S$ U0 _- j' q/ \ j6 M! K) @3 V5 n2 f+ j! ^
void IRQHandler (void)
# T* Z. G2 N a{
4 `0 P& Q* D; F. O. t volatile unsigned int *base = (unsigned int *) 0x80000000;# X: f: e' O9 p- l ^& ]; V: Z7 c- \
! ?3 f! e; G0 W% t6 V) K if (*base == 1) // which interrupt was it?- q0 J& i. w& d$ v! e% z8 D3 F
{- ]/ G# x" }# ?3 t6 Q; V5 ?: u6 ~2 `
C_int_handler(); // process the interrupt
& I% ]3 j+ J; j0 T& p }
6 w% n) \' e4 Y) ~ *(base+1) = 0; // clear the interrupt% P* s9 L6 Y' z* v: Q* l/ B
}
$ |9 u& E9 T: H( I% n4 H% U! r( P9 S, g% ?* I
;对应的汇编程序
, Q$ a5 ~+ Y" Q6 M. h$ A" F. m
8 q( ]7 O0 ^% J, Y3 cIRQHandler PROC. i0 Y5 ]6 o N
STMFD sp!,{r4,lr} W% p8 }5 O/ k& `, y9 k7 O6 A
MOV r4,#0x80000000
% k8 `! ?. k) O( r* W. o; B. S6 ` LDR r0,[r4,#0]
9 z) g/ p* f' D# b9 b CMP r0,#1
7 n- i, o/ ]! d3 L" r5 k' W; c- Q BLEQ C_int_handler& N. x' g P: n/ e7 G+ z
MOV r0,#0$ v9 \7 Z1 D( r3 U
STR r0,[r4,#4]; P$ @: E7 C$ R0 ?
LDMFD sp!,{r4,pc}1 s n' z; A: n/ ^* |$ @
END
: g9 C$ K8 u+ q3 ^6 C' R, l8 i, J N$ V5 {3 N- a3 D% Z. k
可重入的IRQ/FIQ异常中断处理程序) I! \" `9 w# V# u7 b: V+ [2 q
; n+ `0 y9 ~. t
1、将返回地址保存到IRQ的数据栈中# Y# V1 \: |; f' q% W
; D) r7 H4 F# q1 t0 K" B. B7 r; r* M, R
2、保存工作寄存器和SPSR_irq
9 S. a. n' m. d+ e6 A8 b
% d, Y( s( L$ \4 S3 P/ u3、清除中断标志位' @' j0 S. I3 r+ i; x% g% L# U" H
% A" Q# d7 v/ a' c3 ~: |
4、将处理器切换到系统模式,重新使能IRQ/FIQ中断, P0 m$ f) g$ Q- O$ M! a
( x) `- @. K6 K# K+ r$ h
5、保存用户模式的LR寄存器和被调用程序不保存的寄存器. K" @3 s2 F) l0 t. X7 @& O
1 E8 v4 V) k- ^+ a0 M7 Y- o1 R5 g
6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ5 u8 \ T8 \$ U" h' S
! e9 {* S5 `* } t9 g" V8 h+ C
7、切换到IRQ模式,禁止中断
, t5 X! E& E, g& W9 M# ~9 y1 f) c8 |: ]9 d5 f
8、恢复工作组寄存器和寄存器LR_irq) x8 c4 ^& @! \- j# I
+ a* E; m7 h8 @9、从IRQ异常中断处理程序中返回
2 C/ x1 A7 ?8 o8 v A* H, _; J, A" u7 o- W( Y7 Z# b
PRESERVE8: \1 W O; S( D# H- G5 c; ~
, S4 X7 J! q0 f8 D
AREA INTERRUPT, CODE, READONLY3 a6 ^( n3 y: |1 p6 k6 e
IMPORT C_irq_handler
4 l% G! S3 T) q, k" LIRQ/ n6 l2 }/ o9 P' F1 _
SUB lr, lr, #4 ; construct the return address4 p, J4 d5 `- }: |. `9 Y
STMFD sp!, {lr} ; and push the adjusted lr_IRQ0 J" ~) ]# E4 I4 o `6 k) K
MRS r14, SPSR ; copy spsr_IRQ to r146 L) w C6 V0 T- m6 [, p$ A/ d+ L/ K
STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ1 D' X1 s1 M, @8 w& {; D
+ p7 A: B2 g% s& G ; Add instructions to clear the interrupt here6 b5 w' t1 b* U; F2 N
; then re-enable interrupts.
( p. k2 C2 J% }5 L4 N/ B
( m4 T: [% i6 A/ E( }* S; L& }% c# D
: J% l% I: G" q+ j" pMSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
1 r m, w/ m) f2 G& [ ; enabled. USR mode registers& U2 \& |( W A$ I
; are now current.% Y2 t' h' B1 R5 R, o, W
STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee ; T) a: K% M4 K( h
; saved registers
6 D2 b# J( X) D; A5 I" W# M BL C_irq_handler ; branch to C IRQ handler.
: ~' u. {3 }6 v& ~2 t LDMFD sp!, {r0-r3, lr} ; restore registers
$ \2 N5 O2 k" J MSR CPSR_c, #0x92 ; switch to IRQ mode and disable% D1 s* L# G4 Y* {/ x x* p) a
; IRQs. FIQ is still enabled.; j, X6 q1 D( k7 w9 I
8 H& O: P5 |9 z LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ6 O. R8 \. U) r2 J
MSR SPSR_cf, r14
! C3 Y" }9 A8 q" d2 `% q4 f LDMFD sp!, {pc}^ ; return from IRQ.
/ h: T, m; H/ @ END6 q ?/ } |/ r- o' o* @: o
( X& ?- y* x$ f1 K% l
9.5.2 IRQ异常中断处理程序例程
/ O0 |9 [' s! v& {/ s+ V2 {' h+ x% `2 m7 c3 e
;保存返回地址
7 w, k" [6 J! \8 m, a7 {1 L6 m7 b
SUB LR,LR #42 s! H; J) p- z- z7 b; r
5 \2 z: [$ h& p STMFD SP!,{LR}4 A, P3 B4 M& J
+ X7 G& |7 \5 B! D, Y2 H& {' Q2 A
;保存SPSR及工作组寄存器R12
1 z: r* B. v: E) P z7 [, B' L X- U3 ~ ~7 c+ d! e
MRS R14,SPSR5 B+ B7 {6 N! J1 c2 ~6 Y
" ^# o) t/ D1 r8 |# ~, V
STMFD SP!,{R12,R14}0 W7 L5 m! V# W7 Y& C0 d( t3 v0 z
1 @9 X( o+ P5 U$ \$ t
;读取中断控制器的基地址# y# c. t2 X4 _
$ {/ r1 S: z# E; u7 v& p: J MOV R12 , #IntBase
9 X5 P( J w2 w, w% W
4 D7 p/ b! l! y& U$ V+ _ ;读取优先级最高的中断源的优先级
6 P; d" x8 J1 R' K% B! u
8 A2 ?$ r; _& _% T LDR R12 ,[R12,#IntLevel]. Q& N6 N( f1 x, D2 C, ^
* t+ b/ y- v* \* u1 n0 D7 e, ~* R
;使能中断6 k$ W9 s2 P1 @( }3 N. m j
& V' r3 c# D4 b& h
MRS R14,CPSR0 n! M3 ]8 x+ h! ]4 p
- D* z$ _9 X& v# z* q! l0 }9 L
BIC R14,R14,#0X809 H# v: j- n# w. ~( R! d
6 }: |) Y+ D9 h4 |) g* j5 e& @ MSR CPSR_c ,R14
! e( i0 D( e; f; [! s; W, v) Z! x6 o5 |; M/ q
;跳转到优先级最高的中断对应的中断处理程序4 z3 ?" z' X* I- C. j+ D
; @9 H# \0 c/ u2 k
LDR PC, [PC,R12,LSR #2]
/ w2 L8 U8 V% W5 U, j/ @4 C' n+ h; u* a7 f8 F1 j
;加入一条NOP指令,实现跳转表的地址计算方法: M# t8 h- ] l7 k3 [5 q* O
+ V7 _. s) @. a9 F2 T! S- O
NOP% Z: i" Q0 v( B* F$ N$ x
8 [0 U! L2 T+ Y, {0 }" N" Q
;中断处理程序地址表
* X0 O4 q+ a q2 C: h& _, B
! }+ y7 S* A- \ ;优先级为0的中断对应的中断处理程序地址
2 T* y) x+ H! m* u" \
7 \( Z) _) i& y DCD Priority0Handler
5 S, K# ?) z5 h, M
( [- Q' W" K# m) O3 }, h ;优先级为1的中断对应的中断处理程序地址
. G" T+ n0 w4 a4 ~7 Q
) {8 l: Y8 H7 `2 d. z) N DCD Priority1Handler
: o w" I% f" Q* p% w/ I
8 J/ x- Y7 l9 O) O8 x+ ?) Z ;优先级为2的中断对应的中断处理程序地址
! ^+ O6 m0 i7 c0 I& }7 g& r. x; |
/ C# ?4 o Q7 }) N" a2 _ DCD Priority2Handler+ ~8 [5 y% X0 b) D1 C! V$ ~, i* E
" L* y7 G) h% g! w9 o# I& O9 I5 K
. e! a7 V2 I3 W( @: |2 v
' ~0 F7 m, J6 Q/ @$ I* J8 Y( A
;优先级为0的中断对应的中断处理程序+ i0 z" t( r! B4 j% N
) |- s8 f% S- y$ ], W3 z
Priority0Handler _6 m2 i1 O+ ?' y [- I$ b
# c- w" W% `/ L3 t ;保存工作寄存器
{, H* {$ O8 E3 U
8 i6 Z8 P' e, v0 `3 U STMFD SP!,[R0-R11]
" n, R6 [2 W$ t/ c- [$ |/ Y
1 f! C/ B0 s2 e) g ;这里为中断处理程序的程序体
, z- ^, k* P2 Y; y* j' v# J$ V2 |$ F7 O9 \) @
;.../ f* H6 m6 ~0 F \$ W9 {, h0 Z
+ S& d: ]9 F5 G6 P; _+ ^7 a
;恢复工作寄存器
4 N# f: l* A$ `4 v. ~( \6 _5 ]( L& _) O* H! ^2 W
LDMFD SP! ,{R0-R11}+ H3 v$ |+ V4 N$ h8 K
8 h- N, d( J- t3 w' Q3 G, `6 J6 H ;禁止中断9 I6 I6 j0 K5 T3 V n
: G( ]2 _; F% s3 G MRS R12,CPSR
. n( E) J' l) N' j/ k, ~3 O. p, a( f) R2 Q9 Y B/ h1 q# K4 @# D
ORR R12,R12
7 A) A) I5 O: G0 m5 e# b9 B$ l" W3 |7 D# c3 s( ]& n9 n3 M
MSR CPSR_c, R12
/ A9 J2 Q+ ~1 `/ |- v
( F/ S# M A; H! d3 K1 S ;恢复SPSR和寄存器R12* t; @4 X3 O* |5 j
) M/ g: ~- `: ~5 U
LDMFD SP!, {R12,R14}
! e' z3 P$ b$ u) N5 [9 |' F7 v2 G3 L% D$ m1 ` O; Z
MSR SPSR_csxf, R14
& h" A: }1 Z# ?$ ]. A1 D0 `8 A
* p8 D$ u& \1 _ ;从优先级为0的中断程序返回6 u# a' a* S% o* X: x! k9 k
4 |4 e) W4 i5 k; P$ c5 c' `1 W" A LDMFD SP!, {PC}^
0 B" H4 i" F. B
0 U( b# \! B7 ^2 o5 ~" V5 u) _
% L! O* n% Z4 l& q4 \, I3 C2 l- Q; N/ c3 m; T$ b% L$ U8 s
;优先级为1的中断对应的中断处理程序地址
/ o l( G9 Q9 L& M* Z* U) b3 H
# F( { u; S8 x4 O5 b! w2 S& H" j9 Q Priority1Handler1 [- j# ` c6 v, ?
9 @: ~) \' A# I1 V ;... |
|