|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
5 y0 S6 `) f0 \& l9 v
9.5 FIQ与IRQ异常中断处理程序. Y) F4 b S( M) y( B6 a) Z
c: X' T% r7 C, _8 N/ ?3 vARM提供的FIQ与IRQ用于外部设备向CPU请求中断。
( u4 u! v$ U) d; K, A: b% u! Z0 }
7 ?3 g, _9 }. [& c. J8 ^9 C9.5.1 不可重入的IRQ/FIQ异常中断处理程序6 O, S! U0 n8 I! `) b5 f
( r% k9 T3 \- U/ ~6 ?: c+ g# a) W;使用关键词_irq
- ]: h% J0 S5 ?! l" j
9 o- s7 [% T$ Q0 L- P/ v__irq void IRQHandler (void)
* H1 _: X+ @) H: L{4 Q( \8 y" }1 E6 y% E. j& B; ]
volatile unsigned int *base = (unsigned int *) 0x80000000;
; j; Y( l; H) K4 T9 J0 ?
5 x$ u% N& K2 b' ]/ q- d! N8 J G if (*base == 1) // which interrupt was it?" W6 I' P" z1 C4 x. L8 S* ^* a
{ [3 C* D$ @4 v* n2 d7 A
C_int_handler(); // process the interrupt }7 A7 Q2 W/ \2 P9 z: c% P& G7 ~; I( \
}
, ?+ ?# r- D0 { b4 N, U *(base+1) = 0; // clear the interrupt
$ c8 |, {0 p& X) x7 e4 J M}
' A* G6 v, Z" I- Y1 V
3 w' C5 ~! R i;对应的汇编程序
+ g4 u* k- g8 R& v1 U6 O
$ T) t+ Z; S3 n7 B+ s5 W" `IRQHandler PROC
) K& w/ ^6 o& w2 b/ \4 \ STMFD sp!,{r0-r4,r12,lr}
. u, }! Z4 x( s$ P- p' T' U9 A: z8 ^ MOV r4,#0x80000000, [5 W! ?0 n' ^# F; M
LDR r0,[r4,#0]
0 D9 P: [# J- |7 J9 ]3 b SUB sp,sp,#4- N2 p! S' }( F0 h
CMP r0,#1
& ~- }$ r3 H% V3 m3 m BLEQ C_int_handler
* A& ]: {1 S3 v/ @3 D MOV r0,#0
- {1 T# p" y3 a STR r0,[r4,#4]% N& M2 c" @* S3 q
ADD sp,sp,#4% _# D- ~* K, h6 o1 W* v
LDMFD sp!,{r0-r4,r12,lr}
' t, j; g) y6 b SUBS pc,lr,#4
# m( T& s1 W3 a2 w4 _, N. G- | ENDP
/ W4 h( s! e$ f4 L; N- b) G" |% d5 C+ D$ B' W. |
;不使用关键词_irq% v0 |7 ^0 p0 }- ]/ Y
. s. {* g$ j9 H" E+ Y/ R5 @
void IRQHandler (void)5 a9 o! h/ `: A/ D7 y, [0 Y# v' K
{% t, w U6 ] w- w
volatile unsigned int *base = (unsigned int *) 0x80000000;
9 t* S" L$ Z: L! ~; y3 K& r: L4 k- X& T- h# |' [$ V
if (*base == 1) // which interrupt was it?7 a) u. E, c0 O0 f# R/ ~% [
{
* }3 i" ~- K: ~9 |) @ C_int_handler(); // process the interrupt ?7 J& |0 R2 O, W- x
}
. O+ C& L2 _/ P5 g *(base+1) = 0; // clear the interrupt- E6 H# x9 ]5 H# M) V8 X2 Q, ?
}
, U. u' [( o2 u# O3 e0 }) u& ~5 ~" N* {
;对应的汇编程序
6 k6 a9 R; {# q8 G( V+ y5 b
' E+ b' e( x' |: q8 zIRQHandler PROC! b& @% |2 X! Y4 ^$ p- ?' e* k
STMFD sp!,{r4,lr}
) @- l8 J* h# \: D5 u MOV r4,#0x80000000
" c6 R( Y" X. M; O LDR r0,[r4,#0]. v( v' D6 O' H
CMP r0,#1
% u+ ^- i' G9 I6 { BLEQ C_int_handler
# P, ^: G) a3 o/ o# E4 \ MOV r0,#0' V _" t4 f' U0 T4 I
STR r0,[r4,#4], s' u/ {6 a6 e) B2 A
LDMFD sp!,{r4,pc}" t8 J+ j2 Q1 j4 r; P2 r
END, d- |* q! e. y* L
; U3 z* S1 h; B9 J. y% @- ~+ ~; k可重入的IRQ/FIQ异常中断处理程序
( c. ^' N. ^ Q% M1 Y K, Q
" x o' X: d6 |1、将返回地址保存到IRQ的数据栈中2 \8 G$ V* q5 b3 ?3 B( B
+ M! U# a4 Z$ V( b' w0 c( j `2、保存工作寄存器和SPSR_irq; Y3 j6 y) D v1 f
5 T) u$ {$ m: @. V2 _3 ^! ^
3、清除中断标志位. V _( h/ G n' x6 k
$ f! O6 L. I0 ?% L/ l6 g4、将处理器切换到系统模式,重新使能IRQ/FIQ中断0 l r3 a8 m0 G+ E0 ]; R1 P0 L4 K: w
9 @7 ]: |; a, M% P' E5、保存用户模式的LR寄存器和被调用程序不保存的寄存器
$ ` g( i" @9 l6 k2 s
! |& i# K/ S/ R/ c6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ# T- O: v" O" v( Q; n$ T; j
/ u. p1 [* S) }+ [
7、切换到IRQ模式,禁止中断
' e: ^/ t3 t2 U8 {5 Z( K: {7 x# G0 R4 R7 O1 V/ N
8、恢复工作组寄存器和寄存器LR_irq
; j! R! k, E/ w: ?) C2 h8 q7 J% s D1 @2 N
9、从IRQ异常中断处理程序中返回# ]. t6 @0 m2 Q
# r9 H* n- H0 DPRESERVE8
4 {: w& t2 i- W/ o6 F* ?3 d+ |, h+ c' ], @2 s
AREA INTERRUPT, CODE, READONLY; e& u: N! L$ Q6 |
IMPORT C_irq_handler
; U; A% X. U' `: C i: Z# @# TIRQ
* a( N4 w* N+ B# w SUB lr, lr, #4 ; construct the return address3 ` v, @$ ?" ?1 W
STMFD sp!, {lr} ; and push the adjusted lr_IRQ1 O. Q7 A/ g/ P
MRS r14, SPSR ; copy spsr_IRQ to r14
2 U. H& C& P: I+ Z2 j3 n4 k' a; b STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ
, u, w- Z0 |8 ~ |
5 f) z3 u2 S, B ~/ N+ h ; Add instructions to clear the interrupt here
& ~8 ]9 ]. j) n# @. X5 i7 H ; then re-enable interrupts.
1 B9 w2 x) T. m9 b% ^$ a% @
U* X7 D' Z: p# S$ @& o( u
7 P" W. X2 J% I- E# { F% A$ vMSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ3 w$ G; c* V% a0 E% y" [
; enabled. USR mode registers
; ~& S/ t9 `& l9 | ; are now current.
# w$ s& g$ D, |6 w- i+ m STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee , p0 z/ b6 M. Q! B8 [& _
; saved registers
3 F! d& G1 U/ j BL C_irq_handler ; branch to C IRQ handler.$ p5 l8 C# p# U( I# ?+ f
LDMFD sp!, {r0-r3, lr} ; restore registers
+ T& i% m0 `9 F: g8 l MSR CPSR_c, #0x92 ; switch to IRQ mode and disable. Z' d8 W) t. u+ J; \7 d+ g( F
; IRQs. FIQ is still enabled.
( Y2 T i& i% c+ B, q) h Y
+ p8 |) R2 D' V) g& \6 s" Y, t' j LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ1 z$ |& L9 J, e" Z) Y+ E1 {4 \
MSR SPSR_cf, r14
0 h4 Z3 j" q8 x2 x( | LDMFD sp!, {pc}^ ; return from IRQ.! U3 p/ {: t% h6 g3 J# ^& \7 n
END
5 E: B* `. A( i# w" H. z: z2 C7 Q2 Z5 P: r# e
9.5.2 IRQ异常中断处理程序例程
4 u3 R: b/ k0 M8 Y
" z. m$ ?* b# Q2 q* P+ e;保存返回地址+ @' J0 V) J7 r
8 M3 D1 ^/ \+ v. h9 L SUB LR,LR #4* U+ s: ~" {" E8 z/ x
/ R9 F( q6 j0 g1 m STMFD SP!,{LR}) T5 Z7 I6 F! m8 _# k% j- Y. g
1 d1 M% b# a2 @3 o, G% k' l! I' o ;保存SPSR及工作组寄存器R120 Z0 v- K, ]* S& {/ A8 G5 D
6 ?$ T O$ g$ o% w) Z" K MRS R14,SPSR, F) n, Z# Y) g8 h/ D2 Z( t6 |0 X
o) e) v2 f a" M9 w ?1 @ STMFD SP!,{R12,R14}9 M; ?3 s! s, _2 n/ `, n7 v# t$ u
0 y% `3 [6 h* q9 M
;读取中断控制器的基地址
# M# o* W, J/ T. k# S! \
, }; N R d- L' c MOV R12 , #IntBase
' k1 _6 M' I) ]7 W- R5 F% o
$ I2 f* {7 ]% e5 ^( m, M0 ] ;读取优先级最高的中断源的优先级
0 G6 ^; b. L7 N! J/ q& Y- x
% @- v+ C5 W, c5 Q$ H, q, X LDR R12 ,[R12,#IntLevel]+ m1 s4 z/ Z$ k6 l! L, I
/ z3 M3 v2 E {+ \5 u! l
;使能中断
$ Y5 C1 M9 n& R9 d9 i) I/ \! |$ X+ b& k; x Q
MRS R14,CPSR7 x5 [1 u$ I2 V" x
$ n% y% V# ^; ~' N: m# X
BIC R14,R14,#0X804 b+ v6 n+ T4 c( K9 b( Q# V* i
9 { l" N& b1 r$ F5 t; _0 ~# i
MSR CPSR_c ,R14$ x2 E: G2 b% [8 _
" [4 t2 G7 {; C+ R
;跳转到优先级最高的中断对应的中断处理程序8 X% f- q4 m: U1 z( S0 i0 o) B
1 H, S9 r, W# y+ N
LDR PC, [PC,R12,LSR #2]/ Q3 ]1 u! q. ?5 U: Q r& \' P
- A; [8 r- e1 z; S3 R/ K. h
;加入一条NOP指令,实现跳转表的地址计算方法$ v2 H2 p# s& Y* A' |
" W( J1 J0 u9 a: y! M ~. Z NOP
2 ]6 G2 U; ^: K5 K5 I# x6 U
* X. U- j% g5 k) M* @$ a- |0 Y) K6 U2 e ;中断处理程序地址表
1 e1 A5 ~; V9 l+ q* p: v
1 N; ?. D' j4 {% Z5 ]8 B ;优先级为0的中断对应的中断处理程序地址2 Z0 A, p5 ?3 M: B
1 e2 i7 ~: `' u1 e5 v; ^ DCD Priority0Handler* d, N) P3 T6 W
% ?# G! b" }0 f# u ;优先级为1的中断对应的中断处理程序地址; d' i3 _: W0 c8 g" h! J
0 X4 w$ a8 g# N$ U
DCD Priority1Handler
% n4 c# k' _* P# {6 E
' t. N, `2 ~/ ] ;优先级为2的中断对应的中断处理程序地址
/ x- q5 O1 s3 r9 |: S! _( @8 m7 h( `! i4 o5 x. D: E
DCD Priority2Handler% M. F$ v7 h% d, c' P! U$ Z0 n
1 w/ p! c+ V' i4 M
9 y3 \8 L$ F* b- B H7 M2 ^ t) t R& j! S( T2 ?# a3 x2 F
;优先级为0的中断对应的中断处理程序
" Q2 {* K( a: b6 `6 C+ d5 h
$ {& O# ~. D- g2 Z0 `9 q Priority0Handler
# K" {) {* G, f+ q" D7 i+ x* P. d
( b/ `, |5 p7 m! m- b1 D7 ^. x* ? ;保存工作寄存器
D: \4 C9 j, v6 h' U% C4 v
G- w: n$ R! t6 \- R; n3 I STMFD SP!,[R0-R11]0 F, t. N; f/ U+ W
* y$ `* R7 `7 A1 ~! W4 X ;这里为中断处理程序的程序体
0 ]% v' e' q6 G' J' |4 Y/ [; J/ s0 o( Y$ w
;..." `: w. F) D" X
5 m$ O& V! p* @: Q
;恢复工作寄存器
) K1 c A! ?. U+ P
- y' m8 d5 b: r: V1 t: p. g( S. | LDMFD SP! ,{R0-R11}! }2 [4 r- n6 R$ |, S
w/ f7 B( d0 U$ b- |; M) E ;禁止中断$ ]2 V- T9 T3 a; |6 V+ T
8 G2 a1 U2 L5 o* t7 e
MRS R12,CPSR, A6 Y1 q) C1 {! ^+ b/ t- ?
8 H- w$ o- u9 R: Z
ORR R12,R121 v- |( U/ c$ e. x
! m! t* Q+ p/ a0 y& L MSR CPSR_c, R12
' l u( P9 U. {- @
, a8 r7 v! z6 d9 H: Z1 [. R ;恢复SPSR和寄存器R12" t. A% n" N- k
0 w5 B% {1 ?6 k7 u6 ^0 T
LDMFD SP!, {R12,R14}
, p" J8 r# K4 H: r- J
. o$ r: f: t9 O9 O+ ]" \" m4 e MSR SPSR_csxf, R14' ^' d# ~5 d- E( r
6 }8 b" U, N9 {# o+ H( g ;从优先级为0的中断程序返回
) ^# e; X, H0 [9 o5 m6 i6 a; z! U
1 U# f3 K, E) b9 Z LDMFD SP!, {PC}^
% F- |6 g% u" u6 _: O6 T1 H/ l* \ |, o' ?) c$ A& }' Y' ~7 O
: E. J& f8 w( K* g5 V. R% F
! L$ ?. F9 B! [. g2 H& i
;优先级为1的中断对应的中断处理程序地址
) Y# G8 D7 [. U' m* Z8 t
0 @; f6 [: g. G- `7 Z! c Priority1Handler3 E6 ]9 \) m! O; M2 e
/ j* o+ W5 X' j8 S: ]9 v$ i% b
;... |
|