|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
" j# M7 s" F& A' t9.5 FIQ与IRQ异常中断处理程序
& E2 M% q& s% h5 Y* f
+ ~7 M3 J* O {# F7 Z9 nARM提供的FIQ与IRQ用于外部设备向CPU请求中断。9 w9 a+ w# `9 s# l2 m
1 O1 z8 M1 o) V/ ~5 p, \- f
9.5.1 不可重入的IRQ/FIQ异常中断处理程序
6 n( T0 C. j: U; e: X. j5 Z4 ~0 ]% x
;使用关键词_irq V0 g3 H5 l/ q( z3 W/ D
/ d& q* ^$ a3 Y U* G
__irq void IRQHandler (void)! g) W+ m5 m! i- g
{3 X) d+ Y& w: Y5 i& ]8 n
volatile unsigned int *base = (unsigned int *) 0x80000000;
7 O8 @6 O& Y. {# `
$ I3 x7 z3 O. G) Q; y if (*base == 1) // which interrupt was it?
y; v8 W) y, u; |: b2 \ {
_* d1 r( q3 E ~! X C_int_handler(); // process the interrupt
: E# A, u2 L" {* u2 h" Q }
! t& D# h+ ]5 Q *(base+1) = 0; // clear the interrupt
G0 g0 ^* Z8 L8 I}
: |3 [' f, ^, J% V
( g, \2 O* l' q6 n# q# y;对应的汇编程序2 N' } v& l; E- u5 V: a) {7 I
% b- y" H5 t0 x% ~IRQHandler PROC
. D B- o. n# x/ L STMFD sp!,{r0-r4,r12,lr}/ c( Z5 _& W! ?% Z8 ^
MOV r4,#0x80000000* U$ L' U( V8 P2 f# V
LDR r0,[r4,#0]
# O' _; G+ O& r0 }' b% r SUB sp,sp,#4
' P# ]0 z. x. n. t' [2 X, [ CMP r0,#1
. i1 N# l2 P6 I6 \/ u1 D BLEQ C_int_handler; P, h3 J1 e) H+ e, D
MOV r0,#08 \8 J7 G% ]& y, |, y$ y
STR r0,[r4,#4]# K# ]( U8 U+ P, H0 w7 I" R0 x
ADD sp,sp,#4
) M; v4 p( U3 m' o: i LDMFD sp!,{r0-r4,r12,lr}( R" Q: m/ F1 m# V# P( K; b* [: v, G
SUBS pc,lr,#4& @/ u# @# O5 ~ x/ c7 ^
ENDP+ D; e7 g/ m5 Z8 ~8 ^- @
3 Y4 I' C$ R3 M9 L
;不使用关键词_irq
7 O& D s) I7 k- C' d2 D/ a8 S% ~6 ^5 A' x# q, j/ ]& S/ q6 t, ]
void IRQHandler (void)
% S0 x; k, Z0 M' `{
: U) D" c G7 f4 @2 p, p' J# _ volatile unsigned int *base = (unsigned int *) 0x80000000;
, o( {- Y" ~: l# ^5 N- S: _" D* @) C9 `( `0 w
if (*base == 1) // which interrupt was it?; P* D0 }6 C" K, `
{
% j: S; d: N! ?2 s0 P C_int_handler(); // process the interrupt
$ @ `% A h3 X }! S8 r; g2 r2 c
*(base+1) = 0; // clear the interrupt
- Q) h+ i( c4 S( I- h2 d o- d}. c( ]: D! J, K2 M8 J f1 }* x
, h/ j0 l! W2 A: Z. j$ ]' m0 f;对应的汇编程序
: M4 r! z/ r3 T' `/ O# i. R. {) R" U4 R! m! V
IRQHandler PROC1 _2 \; O6 c t5 i" I
STMFD sp!,{r4,lr}- m) p7 N+ v; y# n4 O0 |' o
MOV r4,#0x80000000
2 R5 S# i5 I. J; d2 U, a LDR r0,[r4,#0]3 U% B7 E1 [# m* Y1 K1 J
CMP r0,#1
9 {+ f5 M8 Z9 z7 d$ f BLEQ C_int_handler: s7 ?: o* d8 V r9 }2 r9 H. [
MOV r0,#0
! d* k, F/ _! k8 k5 H$ x STR r0,[r4,#4]
- a3 N" A* i% v/ w, K$ |+ o7 e LDMFD sp!,{r4,pc}
% M/ @- v9 H8 z9 P! P& M9 N/ P END
o$ c2 A; |4 |; Y' |
( W8 {' ?( e) g, S, Q& H2 h' @$ d可重入的IRQ/FIQ异常中断处理程序 s" P3 H4 s. z$ z8 h/ F
4 b6 {$ T: c0 u( m2 p1、将返回地址保存到IRQ的数据栈中* q0 C. v. y. J0 U# [9 b
9 }0 c, h0 _: Z" `# _
2、保存工作寄存器和SPSR_irq0 z5 m& w& Y. G0 k/ v/ x
/ K, N1 x9 d3 N! s$ }: F1 d
3、清除中断标志位3 b# ]: t. L( T& H1 Y+ }+ H) |
8 V, T6 ^4 z% t4、将处理器切换到系统模式,重新使能IRQ/FIQ中断
$ y$ Z% u5 B z, _: b
) j% [6 v* d! X2 M5、保存用户模式的LR寄存器和被调用程序不保存的寄存器1 R2 i6 S. [2 q/ @7 I3 }
0 n' Y& T. l1 f4 ^
6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ
3 X, }: B/ u5 b. m1 v; X: _7 ^( Y# L7 V; U* ?) v( Q
7、切换到IRQ模式,禁止中断9 {9 _ F5 Z5 O0 ~: ]( L
. ^2 L" |4 `7 V4 h/ k( {
8、恢复工作组寄存器和寄存器LR_irq+ E6 ~2 Q1 U% V2 N/ z# v
2 ?: ~. m7 k) O$ F) z/ n: f4 w
9、从IRQ异常中断处理程序中返回
) t/ r( n, o6 O: @: O& P1 x" n' A1 a2 u$ b \# r# Z5 @9 d9 t
PRESERVE8# B5 v. C) \# ?% H! _1 {
' }! q# N& I- Y AREA INTERRUPT, CODE, READONLY
7 w# B5 t9 c! j8 K: n" A4 d) z" B% t IMPORT C_irq_handler/ f8 I; \3 L/ q$ }
IRQ
Q& Z& H2 O9 {+ U9 z. p SUB lr, lr, #4 ; construct the return address: R" S% w; [3 \) [" X
STMFD sp!, {lr} ; and push the adjusted lr_IRQ s8 S3 q `1 b) F
MRS r14, SPSR ; copy spsr_IRQ to r14, j) p8 b8 _0 V( U( \" I# q( y
STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ1 \$ [1 d9 S' F- @% H2 ~( I
/ j: F5 }3 G0 N Q3 a( T/ g% E
; Add instructions to clear the interrupt here- v+ X& R2 J) _, [: c
; then re-enable interrupts.- N9 a6 a% r/ C& B
( v z6 T9 n2 P2 A/ c: U, s0 s1 m6 b: `" V* x/ u
MSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
3 ~; J+ W1 ]8 i/ D$ M ; enabled. USR mode registers
: X9 v# \' `6 D ; are now current.
/ U! Y T6 ~( t* H/ Q" v8 K STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee
3 ~" }2 }2 x( m4 S4 ]8 E ; saved registers+ W6 a: V- \) W# T$ Y
BL C_irq_handler ; branch to C IRQ handler." H5 j, Z) @# X4 y* D- u
LDMFD sp!, {r0-r3, lr} ; restore registers* r# ^4 u9 T4 p, H0 H5 t% \
MSR CPSR_c, #0x92 ; switch to IRQ mode and disable
4 V* T& S0 A- m3 Q0 @ ; IRQs. FIQ is still enabled.9 b% ?. B# J; s
Q- q1 o/ @/ E% L3 g/ C5 }6 L
LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ4 W: r9 i5 W+ z8 V3 N* b& N, ]
MSR SPSR_cf, r14( j7 O* _# Z6 n9 Z
LDMFD sp!, {pc}^ ; return from IRQ.' J9 s# C) I0 V$ T) ]$ A$ r0 }, o2 Q
END g0 ` n" B* @+ d% Y3 E/ P( ^
$ j- M5 h* e" B: f( W
9.5.2 IRQ异常中断处理程序例程
: i7 p! D! e" Q7 t6 i) p7 r% G3 j/ v$ t+ `' \9 _: [5 g# r
;保存返回地址
. M' L: b+ i, E) R8 B* P, q9 F) U4 L6 S% V7 X( S' u+ f
SUB LR,LR #4
: m! G2 s* l4 j) J& s! |$ f# Y( t8 H. B) r1 Y1 ]) C) k7 }6 q
STMFD SP!,{LR}" S7 ?2 W, M# a8 w8 [9 Y9 @7 _
0 t) @ I ^$ {1 a9 B
;保存SPSR及工作组寄存器R12
: U0 w% V! Y: J: ~* Y" @- }' p
! M1 x5 u! R8 Y7 U, M/ O2 j) X MRS R14,SPSR. o" u0 M* D. M, T
) } U8 y' H- X0 q6 b
STMFD SP!,{R12,R14}: ^" c, ^& w6 M, i
/ w" m+ i8 E- v& g ;读取中断控制器的基地址
/ K0 l7 r# P- D! O3 @
- }* \& ~% M# |7 }5 ^& P- `5 i. W MOV R12 , #IntBase! D* I+ N5 ?0 A# u `
% N. D; E) N( g ]* t! Y ;读取优先级最高的中断源的优先级- U9 e, E% b# r. a% v
2 ^3 ^9 n8 P; e! t& e7 S& b7 x: T LDR R12 ,[R12,#IntLevel]
- @% q0 i2 V$ w+ u8 t5 p7 S/ |/ @" X5 ?6 n
;使能中断
" h" S2 S8 H+ S: y' P6 J; B& N/ n6 H! D: m1 i% V6 F* a
MRS R14,CPSR
7 B Z, ~$ H: Y4 H1 O9 J) A
- o$ n5 @. T" K1 ` BIC R14,R14,#0X80
& T& b! h5 H4 z7 R/ p) G( s3 x
2 h7 x$ t ~3 H MSR CPSR_c ,R145 O3 `; R% L& N3 K
- ^/ l) Q) {; }( z8 T! t. T ]" @
;跳转到优先级最高的中断对应的中断处理程序
2 b7 W( C9 l3 E' u) S3 S$ e: U
( J2 M9 P, j$ g9 X8 K+ m) A! r- @; c LDR PC, [PC,R12,LSR #2]. B0 u' G8 D/ p* q3 W* \
+ y4 k! G# u9 @* t ;加入一条NOP指令,实现跳转表的地址计算方法8 }2 e2 U" W6 g j0 n( O7 z
; J: u+ P* M# q, ` L6 \
NOP
( ^! ~1 X; Y) O/ ]2 O) s$ t/ a, l. ]9 \. U
;中断处理程序地址表
5 `! G2 P2 r, c6 x+ L7 n) n9 z2 o+ r( y# s# Y
;优先级为0的中断对应的中断处理程序地址3 ?! ?0 G! b/ a7 R
$ T5 t5 H7 i+ G- W5 d8 k- e4 i/ F6 j
DCD Priority0Handler1 i$ P9 \, ^+ `- c, w- K4 c% z
9 I& F: N; s9 X6 G
;优先级为1的中断对应的中断处理程序地址' I" m" p$ w% l, X4 y# R
2 ^9 L5 B' H5 k V
DCD Priority1Handler# Y( f5 \, k( f' c/ ?
) Z0 t, c8 F8 Q4 T
;优先级为2的中断对应的中断处理程序地址0 K- G Q+ I: S3 C/ F9 i, b
. z1 m) v! ]4 P( r0 l
DCD Priority2Handler
4 g8 ~# o* F6 C3 M. z7 ?* j6 N6 K9 Q3 n* ^7 ?" M$ o
$ N5 q: X+ z5 p: y e& A8 ]. n9 b6 l# N. }( y: Q
;优先级为0的中断对应的中断处理程序& V7 D* R! H2 ?" M( G% i
0 x4 ?$ |" r' ] Priority0Handler# A% w7 F1 j+ V! ]
6 D, E) k6 D7 {5 s, |0 X, R6 L
;保存工作寄存器
/ R" N. z4 H: q" A' C2 `. u3 _
0 a) d3 D' n! N0 y STMFD SP!,[R0-R11]& N# o* {2 [( Y$ x
& x8 @/ K' @1 s2 i4 a7 r! U ;这里为中断处理程序的程序体) o1 G5 y# J3 l% ]* F
2 T1 p" i' m* g* n
;...
! `3 @6 q- B7 F: W9 R1 W# h' I% K/ x X: O, e& O" I
;恢复工作寄存器4 E1 j8 f3 E0 M
9 [3 |5 Y Q$ X# d8 ^ LDMFD SP! ,{R0-R11}; U9 i; q4 T' U" l7 I0 ~3 J
+ ~, i3 R2 `. D5 K. O ;禁止中断! Q$ v- S/ h" j4 l7 R, R
5 H X3 o( y6 t: [ \2 U# m$ n
MRS R12,CPSR
3 r2 Y$ l" g9 N+ p
( p9 U( s' l4 ~9 L ORR R12,R12
* o: `% r% O3 x7 _! I5 t6 F) z' T6 H7 ]
MSR CPSR_c, R12
7 }4 o* z4 p0 I( [* }7 j; e0 h, J
# z* L0 X- ^" e" Z( X ;恢复SPSR和寄存器R12
J/ r9 K+ x9 y! f) E. o! @
9 b) | Z) q1 Y) p! m LDMFD SP!, {R12,R14}$ i! |1 [& v7 D9 c' ~* z( r
; A( V. b4 ^3 z1 ^" m+ c2 M MSR SPSR_csxf, R14
. `. J* V6 [; G6 s9 y7 u% f7 z6 x6 q
1 Y4 k `* ?+ M/ ~+ u ;从优先级为0的中断程序返回( Y! w0 K) o9 X3 R
4 J2 {- t1 s @" x8 E! C
LDMFD SP!, {PC}^3 R+ _# @' @& L, |; u4 r: W( u
5 [' L# \; Y F ( |7 N7 ^! {" e6 p; ]
& T* e9 L% b4 ^0 X; v: f/ z' Q U ;优先级为1的中断对应的中断处理程序地址
- j) L3 N8 j x- M' {
2 e; i: o7 U* v: s% g, Q Priority1Handler
2 @5 k9 k0 P( ]9 a
! _- a ^; d$ m8 F; s5 B1 }+ g7 _ ;... |
|