|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
* H7 \5 I+ s7 n& M9.5 FIQ与IRQ异常中断处理程序
/ A8 @' S- ?+ I" L
! G9 O5 e- X, L9 {ARM提供的FIQ与IRQ用于外部设备向CPU请求中断。7 F% ]/ W3 K1 y( `1 G( |
/ K, p8 ^! q0 X0 D: x# o6 ]1 S9.5.1 不可重入的IRQ/FIQ异常中断处理程序
. i6 P( @5 w" p
2 Q% J$ z% v4 t2 z. C;使用关键词_irq
3 d4 K5 F" {) q+ [6 V) x% n$ @
) X0 L7 `- n2 e" p* M/ c( P__irq void IRQHandler (void)+ l8 n7 @& V# o* H+ R- b+ K8 X& V
{2 r3 Y9 {1 y# A) u4 t& ?
volatile unsigned int *base = (unsigned int *) 0x80000000;2 [2 X* w/ t! X4 f" \9 s" k. n4 |7 C
- s p2 q& O# E! H% A1 V if (*base == 1) // which interrupt was it?* [) t+ F0 p% q }, `) ~' \) R8 v
{+ k8 ~6 R$ T# f3 I" k7 v
C_int_handler(); // process the interrupt. R, a3 B. M; s) \
}3 L U5 J v/ ~/ e
*(base+1) = 0; // clear the interrupt
- f$ Y# w" G6 p/ L, z4 V/ r}5 [" N/ B3 o/ A. n
' S, {2 o9 T9 ] _* S7 B;对应的汇编程序
( Y4 m$ z) m, z9 L N+ K. v; }4 y. r# J1 Y; i+ W
IRQHandler PROC
. l) p; i0 B5 d0 n2 f6 N3 V STMFD sp!,{r0-r4,r12,lr}
- P/ @* o' o( \8 E MOV r4,#0x80000000
* Y5 e# K+ R' u6 |: Q LDR r0,[r4,#0]
* z+ X: ?* M, I; Y9 h1 H5 z9 q SUB sp,sp,#4
3 r3 p0 Z0 F( ?/ m! a+ v CMP r0,#1! ? m" M: H8 s# W. z! D# F/ n( A' e
BLEQ C_int_handler
* ~' h4 d. \5 R8 A MOV r0,#00 c! f4 n2 U& k/ s6 B. ^ C; Z
STR r0,[r4,#4]
8 m9 @/ q3 l0 ^% L4 N+ J g/ U ADD sp,sp,#45 C% W5 {# W C1 _
LDMFD sp!,{r0-r4,r12,lr}0 ^8 `3 o( b3 Q+ M* z* E+ L4 x& E
SUBS pc,lr,#4( ` I- x7 A6 F( v4 [ b
ENDP
5 l5 ]; x5 d, R
( S# M" J# g7 j6 P# l, D1 p1 `;不使用关键词_irq/ s# O2 W' H8 l- t$ v! q- L
' t J& N: z. K- |. k
void IRQHandler (void)
8 j6 L) F, F. h. _ Y+ J{
: a1 T# E0 \. G volatile unsigned int *base = (unsigned int *) 0x80000000;
0 v/ N( @: Y% W$ P1 [9 c6 y4 I. K% a
if (*base == 1) // which interrupt was it?' h+ q3 w7 ?- |- q% U/ w) B, A6 H
{
7 J) L4 d2 }' E1 a C_int_handler(); // process the interrupt& C7 c" c5 A: R; ~) ]9 l8 y% F4 O
}% l5 m) z% d* A6 B
*(base+1) = 0; // clear the interrupt
' ~9 G, i6 W; U}( K$ v7 Q5 }5 ? Q
; _2 i& \# c! T8 C2 Z8 W0 a; f;对应的汇编程序
* ]+ E& L( e. i- V( m# Q9 j& G, ^" ^; O% I. h) k
IRQHandler PROC
5 R) d- U/ ]6 y% a9 i9 G6 S+ { STMFD sp!,{r4,lr}
4 V5 V1 W% ?- l2 s0 U MOV r4,#0x80000000' x# R$ W9 L- H& }! E
LDR r0,[r4,#0]
" u; c4 ~. @2 u K3 d CMP r0,#1& A6 I5 c/ [6 y: a6 F/ b
BLEQ C_int_handler( c' X1 y& E) U" X# ]5 K
MOV r0,#0# V; B% ]7 W* Q# Y5 b( s0 s
STR r0,[r4,#4]
* S; T* x, S6 ^+ Z- [6 f. |2 F LDMFD sp!,{r4,pc}
# D; V# T3 G/ r6 s3 z; v4 L END) ?* j* ~+ n" I. _0 C& [
# S0 r0 x+ P7 v5 r) p6 {
可重入的IRQ/FIQ异常中断处理程序2 U- T$ c" }" `% E4 }, D, L; a
1 K" y; U M5 R" S) G
1、将返回地址保存到IRQ的数据栈中
! V7 k- G% i8 d$ N; W2 a: g; t! I" P4 K. N5 T- _
2、保存工作寄存器和SPSR_irq1 m. O9 |7 m$ q
, y4 g' U1 F* P, M
3、清除中断标志位
8 k0 b9 @* U, |+ h
# o5 p+ Y9 I2 \' y7 W4、将处理器切换到系统模式,重新使能IRQ/FIQ中断
. f8 ^, u" z9 G9 f& n
8 o* Q7 @5 Y; B# R, p% _5、保存用户模式的LR寄存器和被调用程序不保存的寄存器. G' i9 D" U0 q
: I2 Y Q* }# c5 _3 q( g6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ
8 `$ M# U2 Y' v3 c
# h1 M, K* o+ C7、切换到IRQ模式,禁止中断- W& |: P% L6 {* N: ]1 ~: Q: _
" K4 Y8 O8 c4 H3 |4 t( l1 l5 L. c. r
8、恢复工作组寄存器和寄存器LR_irq
F1 X# l, Y$ ~, }2 f
% k' u! P9 j3 P( }9、从IRQ异常中断处理程序中返回2 Z% m/ C& m5 \
* I7 j3 y: X8 }9 Z% qPRESERVE8
; A. D6 x6 G9 ~. \( a
4 s% m% Y: a+ G2 m# l AREA INTERRUPT, CODE, READONLY
/ `: D/ g+ q8 p6 `/ g7 P, S, @; J IMPORT C_irq_handler
8 v( \, _( ?. D. A5 eIRQ v9 l0 P" ?! p2 o
SUB lr, lr, #4 ; construct the return address& e* F+ j% j! t0 A/ N
STMFD sp!, {lr} ; and push the adjusted lr_IRQ$ ~* @. T7 T! W: b
MRS r14, SPSR ; copy spsr_IRQ to r14
4 o0 H& F0 ^. b( K$ u0 |; O STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ
6 \) D% J# `( g) O( q' [( f% X, c
5 X0 Z/ f- f, p* K( D0 m0 c8 b ; Add instructions to clear the interrupt here: x: v' ?; ?: \& q! }4 O* c
; then re-enable interrupts.
1 O$ x% u, W0 }
1 _6 U/ w: _+ n, r
8 k7 R3 B6 _! M3 f5 @& Y. LMSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
% b- q, A3 t9 D$ \ ; enabled. USR mode registers7 d% W5 B! G5 R1 O* X( Y2 g/ k/ p
; are now current.5 f7 L. c# S( C
STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee $ @5 {' e( ]) q& y
; saved registers
- a: R+ m1 ?) j+ a+ w& K) R BL C_irq_handler ; branch to C IRQ handler.
- U& S* E% z6 E) R LDMFD sp!, {r0-r3, lr} ; restore registers g4 e) z. A; j) A
MSR CPSR_c, #0x92 ; switch to IRQ mode and disable5 W- D$ u* y3 [# _, U: q, [/ _
; IRQs. FIQ is still enabled.
; X& K. `% J1 N$ m4 G3 G
5 u) \- P w9 T, T7 Y5 x; g) v LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ8 j5 Z7 u$ J9 a# B
MSR SPSR_cf, r14
) J! m4 k! j6 \5 ], l1 P LDMFD sp!, {pc}^ ; return from IRQ.
% i+ c! u. L; V- Y7 h1 }7 f END7 |# P; G4 f9 j2 Q+ x* Z a+ ~' m
& a: _* Y' A1 a9.5.2 IRQ异常中断处理程序例程5 ~) i" w( W& d$ b
* C0 m U7 C2 W;保存返回地址
% W8 s! a0 [& i/ k7 y \( [9 ^+ y5 ` L' u
SUB LR,LR #4
2 L/ t2 O( q" m5 Z5 N9 p
. f" R' i. b$ O0 ]+ w5 C9 t8 j: k STMFD SP!,{LR}
V% q5 T. R/ `* a7 x- \& H% X' t8 _- d" p" e7 j
;保存SPSR及工作组寄存器R12
2 ~' U% U# D' Z" B& n% U2 P0 v* X! n6 [ f
MRS R14,SPSR
8 u% {3 X/ v, c9 `3 z, X0 Y3 v" w$ A. v1 {/ {, B" F% o6 a0 R
STMFD SP!,{R12,R14}5 m* ~1 Y6 |. u$ k6 `. i
! c* i; Q/ m, L7 N0 F- U
;读取中断控制器的基地址
( \/ y4 a- \* \; |0 y; v
% E- ]+ v9 u4 `8 c, R+ p" H MOV R12 , #IntBase: F# `. U2 ~$ L# o! Q4 ]( c
, [; s& [" R3 o0 o ;读取优先级最高的中断源的优先级* |' {+ X- T" m3 I2 Q5 M) z; T
?. R. Z/ t/ T
LDR R12 ,[R12,#IntLevel]0 e, r' C' y6 C# E
9 C! ]" L$ e2 G5 ?$ J9 H0 l$ G ;使能中断
. Z' Q9 Q8 V# x' R {; y! p
1 H2 g# K0 _2 o0 _: | MRS R14,CPSR
# V, |- ?/ N! {4 k. `* h6 V. F' E$ U6 u! @% w2 m
BIC R14,R14,#0X80: g; S% K4 r& N& ^5 ^$ m. x
3 a/ [$ R4 K3 z4 G! N MSR CPSR_c ,R14
- c$ A7 _: A# P8 N- q# J8 k$ V' }( v
;跳转到优先级最高的中断对应的中断处理程序1 B- @( k) g/ r! B9 x
" L. x0 p. s/ K& `1 P3 F LDR PC, [PC,R12,LSR #2]$ S9 a2 [0 W1 y9 K# |( O
) W9 ?& b- X& I" E7 A
;加入一条NOP指令,实现跳转表的地址计算方法# k* v& C% g, h1 a: P
6 ^6 p) H6 u1 `' V. A) q6 {
NOP
3 Q0 F2 d1 T; h' S4 u5 p7 F
. ]/ a; B& P* ~. X. ^ ;中断处理程序地址表
' ~6 d* h3 e) ?' Z3 ?7 u1 W8 b% t3 [. L7 x; n
;优先级为0的中断对应的中断处理程序地址% D' V- D! u% B7 O! X z- s9 }
; d: H4 m8 R' `( d# h2 w# i# {: `
DCD Priority0Handler+ X- F- G3 J* L: [* G& t" @
6 U8 E9 J: l$ \# t" l+ e% O6 O# e ;优先级为1的中断对应的中断处理程序地址
0 ?% O5 `1 W# a
$ K- \( ^4 ] u2 P& }. }+ k6 H! j5 v DCD Priority1Handler
. Q7 {5 Y' Q6 a8 F$ B( J' J' }2 U, b$ H; ?0 @3 m: K
;优先级为2的中断对应的中断处理程序地址
# ?- j" K- V7 q1 f7 J0 F1 `5 h( \% K8 l( A1 w: m) g6 p
DCD Priority2Handler5 l* L8 l; a4 L* R
: B$ y9 S9 Y; z8 G0 P, S
c/ ^6 ]& \) J7 k
- P# n) j3 _8 \, g' Q3 s3 O
;优先级为0的中断对应的中断处理程序3 |2 S- T: V& k
! A8 l6 M4 R% Z/ U0 M! b+ } Priority0Handler/ e1 a/ w8 C- t3 `
( o* ]; }% t, X1 M1 d' u ;保存工作寄存器
' n) N( w: l# c% \/ ~7 [6 C/ @/ X+ `
- s6 C- q- Q# c- N STMFD SP!,[R0-R11]9 K9 ?5 C/ l/ b- q' K4 _, S' n7 X
. z. f# g" ~% A: x3 ?; h
;这里为中断处理程序的程序体
, e9 I/ [- g7 ?& q, m5 d7 w9 a% a
u R' E( D$ I6 L ;...- n9 ?* h ~( W C1 F. V
, B J2 i9 V0 X3 J6 I* w1 S: F ;恢复工作寄存器# Z: B7 C" _* K0 v5 X& W
: y6 E9 z/ I7 S; O: Q- M1 o/ e8 o- @
LDMFD SP! ,{R0-R11}
$ v2 [4 ^8 a9 B; q0 w$ X4 w3 }9 [- Y% t/ c& H
;禁止中断
) w6 A2 }: `; T1 w
7 N& E% G/ W' P' K MRS R12,CPSR* M1 O( w! a: O$ l/ x5 u) A
q1 A( a/ S& b: U* I
ORR R12,R12
, h% `% c" S7 K, J+ [2 v/ c7 s" v, N3 j- T w
MSR CPSR_c, R12* ~) {# \8 b: a4 @/ l9 L
% E! {( ?5 {" p! u+ `
;恢复SPSR和寄存器R12: |# _! K8 m/ U- W! q9 Q- S5 D
" p4 f* U9 m, Q" Q( O
LDMFD SP!, {R12,R14}, C7 s& K6 E% K; {8 x
- m' I5 c9 \; E/ L0 V/ z
MSR SPSR_csxf, R14
8 l4 R6 Y% W+ k: p* [. b- V! N* O8 @- p6 j+ b2 `5 R& o) o
;从优先级为0的中断程序返回
2 B9 U; q9 ~) M, B- O+ t% w9 B3 S3 |4 a; M6 Z: i
LDMFD SP!, {PC}^
* o8 t& ^0 j! W# y
1 o/ E6 d; D( S% m
2 ?: ^; }3 K: @; V. h9 v) I+ l {
! L& ]* @6 v' V4 m4 a ;优先级为1的中断对应的中断处理程序地址
4 t. `( }9 u& [7 E0 ^
8 N0 z' o/ v4 g, f Priority1Handler/ q" R. h8 o* A; X9 `
$ O0 T+ [. S# U$ z
;... |
|