您的位置:首页 > 其它

GNU ARM汇编--(五)中断汇编之嵌套中断处理

2013-05-11 21:19 274 查看
/article/1390137.html

在上篇《GNU ARM汇编--(四)中断汇编之非嵌套中断处理》中分析了最简单的中断处理的写法,再看TQ2440启动代码中的中断向量表的写法就一目了然了.今天抽时间对嵌套中断处理的学习做下整理.

嵌套中断处理的核心代码如下:

[cpp]
view plaincopyprint?

;/*
; * ____________________________________________________________________
; *
; * Copyright (c) 2004, Andrew N. Sloss, Chris Wright and Dominic Symes
; * All rights reserved.
; * ____________________________________________________________________
; *
; * NON-COMMERCIAL USE License
; *
; * Redistribution and use in source and binary forms, with or without
; * modification, are permitted provided that the following conditions
; * are met:
; *
; * 1. For NON-COMMERCIAL USE only.
; *
; * 2. Redistributions of source code must retain the above copyright
; * notice, this list of conditions and the following disclaimer.
; *
; * 3. Redistributions in binary form must reproduce the above
; * copyright notice, this list of conditions and the following
; * disclaimer in the documentation and/or other materials provided
; * with the distribution.
; *
; * 4. All advertising materials mentioning features or use of this
; * software must display the following acknowledgement:
; *
; * This product includes software developed by Andrew N. Sloss,
; * Chris Wright and Dominic Symes.
; *
; * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
; * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
; * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE
; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
; * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
; * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
; * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
; * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
; * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
; * OF SUCH DAMAGE.
; *
; * If you have questions about this license or would like a different
; * license please email :
; *
; * andrew@sloss.net
; *
; *
; */

;/***********************************************************************
; *
; * Module : nih9_9.s
; * Descriptions : Nested Interrupt Handler
; * Example : 9.9
; * OS : generic
; * Platform : generic
; * History :
; *
; * 31th December 2003
; * - added header
; *
; ***********************************************************************/

EXPORT nestedInterruptHandler

Maskmd EQU 0x1f ; processor mode mask
SVC32md EQU 0x13 ; SVC mode
I_Bit EQU 0x80 ; IRQ bit

FRAME_R0 EQU 0x00
FRAME_R1 EQU FRAME_R0+4
FRAME_R2 EQU FRAME_R1+4
FRAME_R3 EQU FRAME_R2+4
FRAME_R4 EQU FRAME_R3+4
FRAME_R5 EQU FRAME_R4+4
FRAME_R6 EQU FRAME_R5+4
FRAME_R7 EQU FRAME_R6+4
FRAME_R8 EQU FRAME_R7+4
FRAME_R9 EQU FRAME_R8+4
FRAME_R10 EQU FRAME_R9+4
FRAME_R11 EQU FRAME_R10+4
FRAME_R12 EQU FRAME_R11+4
FRAME_PSR EQU FRAME_R12+4
FRAME_LR EQU FRAME_PSR+4
FRAME_PC EQU FRAME_LR+4
FRAME_SIZE EQU FRAME_PC+4

AREA nih9_9,CODE,readonly

nestedInterruptHandler ; instruction state : comment
SUB r14,r14,#4 ; 2 :
STMDB r13!,{r0-r3,r12,r14} ; 2 : save context
; <insert code here>
BL read_RescheduleFlag ; 3 : more processing
CMP r0,#0 ; 3 : if processing?
LDMNEIA r13!,{r0-r3,r12,pc}^ ; 4 : then return
MRS r2,SPSR ; 5 : copy SPSR_irq
MOV r0,r13 ; 5 : copy r13_irq
ADD r13,r13,#6*4 ; 5 : reset stack
MRS r1,CPSR ; 6 : copy CPSR
BIC r1,r1,#Maskmd ; 6 :
ORR r1,r1,#SVC32md ; 6 :
MSR CPSR_c,r1 ; 6 : change SVC mode
SUB r13,r13,#FRAME_SIZE-FRAME_R4 ; 7 : make stack space
STMIA r13,{r4-r11} ; 7 : save r4-r11
LDMIA r0,{r4-r9} ; 7 : r4-r9 IRQ stack
BIC r1,r1,#I_Bit ; 8 :
MSR CPSR_c,r1 ; 8 : enable int
STMDB r13!,{r4-r7} ; 9 : save r4-r7 SVC
STR r2,[r13,#FRAME_PSR] ; 9 : save PSR
STR r8,[r13,#FRAME_R12] ; 9 : save r12
STR r9,[r13,#FRAME_PC] ; 9 : save pc
STR r14,[r13,#FRAME_LR] ; 9 : save lr
; <insert code here>
LDMIA r13!,{r0-r12,r14} ; 11 : restore context
MSR SPSR_cxsf,r14 ; 11 : restore SPSR
LDMIA r13!,{r14,pc}^ ; 11 : return

read_RescheduleFlag
; <implement your own reschedule flag code here>
MOV r0,#0 ; more processing
MOV pc,r14 ; return

END

;/*
; *  ____________________________________________________________________
; *
; *  Copyright (c) 2004, Andrew N. Sloss, Chris Wright and Dominic Symes
; *  All rights reserved.
; *  ____________________________________________________________________
; *
; *  NON-COMMERCIAL USE License
; *
; *  Redistribution and use in source and binary forms, with or without
; *  modification, are permitted provided that the following conditions
; *  are met:
; *
; *  1. For NON-COMMERCIAL USE only.
; *
; *  2. Redistributions of source code must retain the above copyright
; *     notice, this list of conditions and the following disclaimer.
; *
; *  3. Redistributions in binary form must reproduce the above
; *     copyright notice, this list of conditions and the following
; *     disclaimer in the documentation and/or other materials provided
; *     with the distribution.
; *
; *  4. All advertising materials mentioning features or use of this
; *     software must display the following acknowledgement:
; *
; *     This product includes software developed by Andrew N. Sloss,
; *     Chris Wright and Dominic Symes.
; *
; *   THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
; *   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
; *   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE
; *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
; *   OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
; *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
; *   OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
; *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
; *   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
; *   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
; *   OF SUCH DAMAGE.
; *
; *  If you have questions about this license or would like a different
; *  license please email :
; *
; *  andrew@sloss.net
; *
; *
; */

;/***********************************************************************
; *
; *  Module       : nih9_9.s
; *  Descriptions : Nested Interrupt Handler
; *  Example      : 9.9
; *  OS           : generic
; *  Platform     : generic
; *  History      :
; *
; *  31th December 2003
; *  - added header
; *
; ***********************************************************************/

EXPORT nestedInterruptHandler

Maskmd     EQU 0x1f                     ; processor mode mask
SVC32md    EQU 0x13                     ; SVC mode
I_Bit      EQU 0x80                     ; IRQ bit

FRAME_R0   EQU 0x00
FRAME_R1   EQU FRAME_R0+4
FRAME_R2   EQU FRAME_R1+4
FRAME_R3   EQU FRAME_R2+4
FRAME_R4   EQU FRAME_R3+4
FRAME_R5   EQU FRAME_R4+4
FRAME_R6   EQU FRAME_R5+4
FRAME_R7   EQU FRAME_R6+4
FRAME_R8   EQU FRAME_R7+4
FRAME_R9   EQU FRAME_R8+4
FRAME_R10  EQU FRAME_R9+4
FRAME_R11  EQU FRAME_R10+4
FRAME_R12  EQU FRAME_R11+4
FRAME_PSR  EQU FRAME_R12+4
FRAME_LR   EQU FRAME_PSR+4
FRAME_PC   EQU FRAME_LR+4
FRAME_SIZE EQU FRAME_PC+4

AREA nih9_9,CODE,readonly

nestedInterruptHandler ; instruction       state : comment
SUB     r14,r14,#4                 ; 2 :
STMDB   r13!,{r0-r3,r12,r14}       ; 2 : save context
; <insert code here>
BL      read_RescheduleFlag        ; 3 : more processing
CMP     r0,#0                      ; 3 : if processing?
LDMNEIA r13!,{r0-r3,r12,pc}^       ; 4 :   then return
MRS     r2,SPSR                    ; 5 : copy SPSR_irq
MOV     r0,r13                     ; 5 : copy r13_irq
ADD     r13,r13,#6*4               ; 5 : reset stack
MRS     r1,CPSR                    ; 6 : copy CPSR
BIC     r1,r1,#Maskmd              ; 6 :
ORR     r1,r1,#SVC32md             ; 6 :
MSR     CPSR_c,r1                  ; 6 : change SVC mode
SUB     r13,r13,#FRAME_SIZE-FRAME_R4 ; 7 : make stack space
STMIA   r13,{r4-r11}               ; 7 : save r4-r11
LDMIA   r0,{r4-r9}                 ; 7 : r4-r9 IRQ stack
BIC     r1,r1,#I_Bit               ; 8 :
MSR     CPSR_c,r1                  ; 8 : enable int
STMDB   r13!,{r4-r7}               ; 9 : save r4-r7 SVC
STR     r2,[r13,#FRAME_PSR]        ; 9 : save PSR
STR     r8,[r13,#FRAME_R12]        ; 9 : save r12
STR     r9,[r13,#FRAME_PC]         ; 9 : save pc
STR     r14,[r13,#FRAME_LR]        ; 9 : save lr
; <insert code here>
LDMIA   r13!,{r0-r12,r14}          ; 11 : restore context
MSR     SPSR_cxsf,r14              ; 11 : restore SPSR
LDMIA   r13!,{r14,pc}^             ; 11 : return

read_RescheduleFlag
; <implement your own reschedule flag code here>
MOV     r0,#0                      ; more processing
MOV     pc,r14                     ; return

END


代码的关键就是在中断后切换到SVC模式下,利用svc mode的stack来实现中断嵌套过程的备份以及恢复操作.从代码中可以看到,从R0到PC都在栈中有备份,这里我们叫栈帧.记得《深入理解计算机系统》一书在讲x86汇编的函数调用时也是栈帧的概念.这点上中断嵌套和函数调用有相似之处.有了这个栈帧,利用压栈出栈操作就一切ok了.

刚看这个代码,对有个地方有疑问,就是觉得中断开早了:

BIC r1,r1,#I_Bit ; 8 :

MSR CPSR_c,r1 ; 8 : enable int

STMDB r13!,{r4-r7} ; 9 : save r4-r7 SVC

STR r2,[r13,#FRAME_PSR] ; 9 : save PSR

STR r8,[r13,#FRAME_R12] ; 9 : save r12

STR r9,[r13,#FRAME_PC] ; 9 : save pc

STR r14,[r13,#FRAME_LR] ; 9 : save lr

觉得开中断的代码应该放在后面,这样才能保证svc mode下的stack frame不会被破坏.但在草稿纸上画一下irq和svc下的stack图,就发现堆栈操作并没有问题.可以假设刚开中断立马就有新的中断了,r4-r7 r8 r9都有在STMIA r13,{r4-r11} 中保存到svc的stack中,LDMIA r0,{r4-r9} 和STMDB r13!,{r4-r7} 保证了最初的r0-r3在栈中,而LDMIA r0,{r4-r9}和STR r8,[r13,#FRAME_R12]
以及STR r9,[r13,#FRAME_PC] 保证了R12和PC,保证正确返回.(这里的r9装的是r14_irq,所以pc就是r14_irq,这样就保证了从中断服务例程中返回).至于STR r14,[r13,#FRAME_LR]中的r14是r14_svc,将其压入svc的stack中,中断例程用bl就不会出现错误了,在最后LDMIA r13!,{r14,pc}^ 中r14得到恢复.而r2保存的是spsr,也就是svc模式的状态,一直不变,不用担心会被覆盖.

最后,再看了一遍图,觉得r10和r11的帧可以省去,因为r4-r9是用来存atpcs的r0-r3,r12,r14,而r10和r11用不到.貌似可以省点空间和时间,具体的待会实验一下.

下面给出实际的嵌套中断处理,利用r10来保存INTOFFSET的值,根据该值来判定是什么中断,从而做不同的处理.具体的效果是:代码会做流水灯的动作,Key1代表INT1,中断处理动作是4个灯全全亮然后全灭,Key4代表代表INT0,中断处理动作是第一个灯和第三个灯亮,然后第二个灯和第四个灯亮.

[cpp]
view plaincopyprint?

/*
simple interruption
copyleft@dndxhej@gmail.com
*/

.equ Maskmd, 0x1f @ processor mode mask
.equ SVC32md, 0x13 @ SVC mode
.equ I_Bit, 0x80 @ IRQ bit

.equ FRAME_R0, 0x00
.equ FRAME_R1, FRAME_R0+4
.equ FRAME_R2, FRAME_R1+4
.equ FRAME_R3, FRAME_R2+4
.equ FRAME_R4, FRAME_R3+4
.equ FRAME_R5, FRAME_R4+4
.equ FRAME_R6, FRAME_R5+4
.equ FRAME_R7, FRAME_R6+4
.equ FRAME_R8, FRAME_R7+4
.equ FRAME_R9, FRAME_R8+4
.equ FRAME_R10, FRAME_R9+4
.equ FRAME_R11, FRAME_R10+4
.equ FRAME_R12, FRAME_R11+4
.equ FRAME_PSR, FRAME_R12+4
.equ FRAME_LR, FRAME_PSR+4
.equ FRAME_PC, FRAME_LR+4
.equ FRAME_SIZE, FRAME_PC+4

.equ NOINT, 0xc0
.equ WTCON, 0x53000000
.equ GPBCON, 0x56000010 @led
.equ GPBDAT, 0x56000014 @led
.equ GPBUP, 0x56000018 @led
.equ GPFCON, 0x56000050 @interrupt config
.equ EINTMASK, 0x560000a4
.equ EXTINT0, 0x56000088
.equ EXTINT1, 0x5600008c
.equ EXTINT2, 0x56000090
.equ INTMSK, 0x4A000008
.equ EINTPEND, 0x560000a8

.equ INTSUBMSK, 0X4A00001C

.equ SRCPND, 0X4A000000
.equ INTPND, 0X4A000010

.equ INTOFFSET, 0x4A000014

.global _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
@b irq
ldr pc, _irq
ldr pc, _fiq

_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq

.balignl 16,0xdeadbeef

reset:

ldr r3, =WTCON
mov r4, #0x0
str r4, [r3] @ disable watchdog

ldr r0, =GPBCON
ldr r1, =0x15400
str r1, [r0]

ldr r2, =GPBDAT
ldr r1, =0x160
str r1, [r2]

bl delay

msr cpsr_c, #0xd2 @进入中断模式
ldr sp, =0xc00 @中断模式的栈指针定义

msr cpsr_c, #0xd3 @进入svc模式
ldr sp, =0xfff @设置svc模式的栈指针

@--------------------------------------------

ldr r0, =GPBUP
ldr r1, =0x03f0
str r1, [r0]

ldr r0, =GPFCON
ldr r1, =0x2ea@0x2
str r1, [r0]

ldr r0, =EXTINT0
@ldr r1, =0x8f888@0x0@0x8f888 @~(7|(7<<4)|(7<<8)|(7<<16))
ldr r1, =0xafaaa
str r1, [r0]

ldr r0, =EINTPEND
ldr r1, =0xf0@0b10000
str r1, [r0]

ldr r0, =EINTMASK
ldr r1, =0x00@0b00000
str r1, [r0]

ldr r0, =SRCPND
ldr r1, =0xff@0x1@0b11111
str r1, [r0]

ldr r0, =INTPND
ldr r1, =0xff@0x1@0b11111
str r1, [r0]

ldr r0, =INTMSK
ldr r1, =0xffffff00@0b00000
str r1, [r0]

MRS r1, cpsr
BIC r1, r1, #0x80
MSR cpsr_c, r1

bl main

irq:
sub r14,r14,#4 @ 2 :
stmdb sp!,{r0-r3,r12,r14} @ 2 : save context
@ <insert code here>
@BL read_RescheduleFlag @ 3 : more processing
@CMP r0,#0 @ 3 : if processing?
@LDMNEIA sp!,{r0-r3,r12,pc}^ @ 4 : then return
@@@@@@@@@@@@@@@@
ldr r10,=INTOFFSET @用r10保存中断的offset
ldr r10,[r10]

ldr r0,=EINTPEND
ldr r1,=0xf0
str r1,[r0]

ldr r0, =SRCPND
ldr r1, =0x3f@0b11111
str r1, [r0]

ldr r0, =INTPND
ldr r1, =0x3f@0b11111
str r1, [r0]
@@@@@@@@@@@@@@
mrs r2,SPSR @ 5 : copy SPSR_irq
mov r0,sp @ 5 : copy sp_irq
add sp,sp,#6*4 @ 5 : reset stack
mrs r1,CPSR @ 6 : copy CPSR
bic r1,r1,#Maskmd @ 6 :
orr r1,r1,#SVC32md @ 6 :
msr CPSR_c,r1 @ 6 : change SVC mode
sub sp,sp,#FRAME_SIZE-FRAME_R4 @ 7 : make stack space
stmia sp,{r4-r11} @ 7 : save r4-r11
ldmia r0,{r4-r9} @ 7 : r4-r9 IRQ stack

bic r1,r1,#I_Bit @ 8 :
msr CPSR_c,r1 @ 8 : enable int
stmdb sp!,{r4-r7} @ 9 : save r4-r7 SVC
str r2,[sp,#FRAME_PSR] @ 9 : save PSR
str r8,[sp,#FRAME_R12] @ 9 : save r12
str r9,[sp,#FRAME_PC] @ 9 : save pc
str r14,[sp,#FRAME_LR] @ 9 : save lr

@ <insert code here>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

cmp r10,#0x0
bleq blink1

cmp r10,#0x1
bleq blink3

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
LDMIA sp!,{r0-r12,r14} @ 11 : restore context
MSR SPSR_cxsf,r14 @ 11 : restore SPSR
LDMIA sp!,{r14,pc}^ @ 11 : return

delay:

ldr r3,=0xffff

delay1:
sub r3,r3,#1

cmp r3,#0x0

bne delay1

mov pc,lr

blink1:
ldr r0, =GPBDAT
ldr r1, =0x000
str r1, [r0]

ldr r3,=0xffff

delay2:
sub r3,r3,#1

cmp r3,#0x0

bne delay2

ldr r0, =GPBDAT
ldr r1, =0x1f0
str r1, [r0]

ldr r3,=0xffff

delay3:
sub r3,r3,#1

cmp r3,#0x0

bne delay3

mov pc,lr

blink2:
ldr r0, =GPBDAT
ldr r1, =0x140
str r1, [r0]

ldr r3,=0xffff

delay12:
sub r3,r3,#1

cmp r3,#0x0

bne delay12

ldr r0, =GPBDAT
ldr r1, =0xa0
str r1, [r0]

ldr r3,=0xffff

delay13:
sub r3,r3,#1

cmp r3,#0x0

bne delay13
mov pc,lr

blink3:
ldr r0, =GPBDAT
ldr r1, =0x0a0
str r1, [r0]

stmfd sp!,{lr}

bl delay

ldr r0, =GPBDAT
ldr r1, =0x140
str r1, [r0]

bl delay

ldmfd sp!,{lr}
mov pc,lr

main:
ledloop:

ldr r1,=0x1c0
str r1,[r2]
bl delay

ldr r1,=0x1a0
str r1,[r2]
bl delay

ldr r1,=0x160
str r1,[r2]
bl delay

ldr r1,=0x0e0
str r1,[r2]
bl delay

b ledloop

undefined_instruction:
nop
software_interrupt:
nop
prefetch_abort:
nop
data_abort:
nop
not_used:
nop
fiq:
nop

/*
simple interruption
copyleft@dndxhej@gmail.com
*/

.equ	Maskmd,	0x1f                     @ processor mode mask
.equ	SVC32md,     0x13                     @ SVC mode
.equ	I_Bit,       0x80                     @ IRQ bit

.equ	FRAME_R0,    0x00
.equ	FRAME_R1,    FRAME_R0+4
.equ	FRAME_R2,    FRAME_R1+4
.equ	FRAME_R3,    FRAME_R2+4
.equ	FRAME_R4,    FRAME_R3+4
.equ	FRAME_R5,    FRAME_R4+4
.equ	FRAME_R6,    FRAME_R5+4
.equ	FRAME_R7,    FRAME_R6+4
.equ	FRAME_R8,    FRAME_R7+4
.equ	FRAME_R9,    FRAME_R8+4
.equ	FRAME_R10,   FRAME_R9+4
.equ	FRAME_R11,   FRAME_R10+4
.equ	FRAME_R12,   FRAME_R11+4
.equ	FRAME_PSR,   FRAME_R12+4
.equ	FRAME_LR,    FRAME_PSR+4
.equ	FRAME_PC,    FRAME_LR+4
.equ	FRAME_SIZE,  FRAME_PC+4

.equ   NOINT, 0xc0
.equ	WTCON,	0x53000000
.equ 	GPBCON,	0x56000010  	@led
.equ	GPBDAT,	0x56000014  	@led
.equ   GPBUP,        0x56000018    @led
.equ 	GPFCON, 0x56000050  	@interrupt config
.equ	EINTMASK, 0x560000a4
.equ 	EXTINT0,  0x56000088
.equ 	EXTINT1,  0x5600008c
.equ 	EXTINT2,  0x56000090
.equ	INTMSK,	 0x4A000008
.equ   EINTPEND,     0x560000a8

.equ   INTSUBMSK,    0X4A00001C

.equ   SRCPND,   0X4A000000
.equ   INTPND,   0X4A000010

.equ	INTOFFSET,	0x4A000014

.global _start
_start:		b	reset
ldr     pc, _undefined_instruction
ldr 	pc, _software_interrupt
ldr	pc, _prefetch_abort
ldr	pc, _data_abort
ldr	pc, _not_used
@b	irq
ldr 	pc, _irq
ldr 	pc, _fiq

_undefined_instruction:		.word undefined_instruction
_software_interrupt:		.word software_interrupt
_prefetch_abort:		.word prefetch_abort
_data_abort:			.word data_abort
_not_used:			.word not_used
_irq:				.word irq
_fiq:				.word fiq

.balignl 16,0xdeadbeef

reset:

ldr     r3, =WTCON
mov	r4, #0x0
str	r4, [r3]	@ disable watchdog

ldr	r0, =GPBCON
ldr	r1, =0x15400
str	r1, [r0]

ldr	r2, =GPBDAT
ldr	r1, =0x160
str	r1, [r2]

bl delay

msr cpsr_c, #0xd2 @进入中断模式
ldr sp, =0xc00 @中断模式的栈指针定义

msr cpsr_c, #0xd3 @进入svc模式
ldr sp, =0xfff @设置svc模式的栈指针

@--------------------------------------------

ldr	r0, =GPBUP
ldr	r1, =0x03f0
str	r1, [r0]

ldr	r0, =GPFCON
ldr	r1, =0x2ea@0x2
str	r1, [r0]

ldr	r0, =EXTINT0
@ldr	r1, =0x8f888@0x0@0x8f888      @~(7|(7<<4)|(7<<8)|(7<<16))
ldr	r1, =0xafaaa
str	r1, [r0]

ldr	r0, =EINTPEND
ldr	r1, =0xf0@0b10000
str	r1, [r0]

ldr	r0, =EINTMASK
ldr	r1, =0x00@0b00000
str	r1, [r0]

ldr	r0, =SRCPND
ldr	r1, =0xff@0x1@0b11111
str	r1, [r0]

ldr	r0, =INTPND
ldr	r1, =0xff@0x1@0b11111
str	r1, [r0]

ldr	r0, =INTMSK
ldr	r1, =0xffffff00@0b00000
str	r1, [r0]

MRS r1, cpsr
BIC r1, r1, #0x80
MSR cpsr_c, r1

bl     main

irq:
sub     r14,r14,#4                 @ 2 :
stmdb   sp!,{r0-r3,r12,r14}       @ 2 : save context
@ <insert code here>
@BL      read_RescheduleFlag        @ 3 : more processing
@CMP     r0,#0                      @ 3 : if processing?
@LDMNEIA sp!,{r0-r3,r12,pc}^       @ 4 :   then return
@@@@@@@@@@@@@@@@
ldr r10,=INTOFFSET           @用r10保存中断的offset
ldr r10,[r10]

ldr r0,=EINTPEND
ldr r1,=0xf0
str r1,[r0]

ldr	r0, =SRCPND
ldr	r1, =0x3f@0b11111
str	r1, [r0]

ldr	r0, =INTPND
ldr	r1, =0x3f@0b11111
str	r1, [r0]
@@@@@@@@@@@@@@
mrs     r2,SPSR                    @ 5 : copy SPSR_irq
mov     r0,sp                     @ 5 : copy sp_irq
add     sp,sp,#6*4               @ 5 : reset stack
mrs     r1,CPSR                    @ 6 : copy CPSR
bic     r1,r1,#Maskmd              @ 6 :
orr     r1,r1,#SVC32md             @ 6 :
msr     CPSR_c,r1                  @ 6 : change SVC mode
sub     sp,sp,#FRAME_SIZE-FRAME_R4 @ 7 : make stack space
stmia   sp,{r4-r11}               @ 7 : save r4-r11
ldmia   r0,{r4-r9}                 @ 7 : r4-r9 IRQ stack

bic     r1,r1,#I_Bit               @ 8 :
msr     CPSR_c,r1                  @ 8 : enable int
stmdb   sp!,{r4-r7}               @ 9 : save r4-r7 SVC
str     r2,[sp,#FRAME_PSR]        @ 9 : save PSR
str     r8,[sp,#FRAME_R12]        @ 9 : save r12
str     r9,[sp,#FRAME_PC]         @ 9 : save pc
str     r14,[sp,#FRAME_LR]        @ 9 : save lr

@ <insert code here>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

cmp	r10,#0x0
bleq	blink1

cmp	r10,#0x1
bleq	blink3

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
LDMIA   sp!,{r0-r12,r14}          @ 11 : restore context
MSR     SPSR_cxsf,r14              @ 11 : restore SPSR
LDMIA   sp!,{r14,pc}^             @ 11 : return

delay:

ldr r3,=0xffff

delay1:
sub r3,r3,#1

cmp r3,#0x0

bne delay1

mov pc,lr

blink1:
ldr	r0, =GPBDAT
ldr	r1, =0x000
str	r1, [r0]

ldr r3,=0xffff

delay2:
sub r3,r3,#1

cmp r3,#0x0

bne delay2

ldr	r0, =GPBDAT
ldr	r1, =0x1f0
str	r1, [r0]

ldr r3,=0xffff

delay3:
sub r3,r3,#1

cmp r3,#0x0

bne delay3

mov pc,lr

blink2:
ldr	r0, =GPBDAT
ldr	r1, =0x140
str	r1, [r0]

ldr r3,=0xffff

delay12:
sub r3,r3,#1

cmp r3,#0x0

bne delay12

ldr	r0, =GPBDAT
ldr	r1, =0xa0
str	r1, [r0]

ldr r3,=0xffff

delay13:
sub r3,r3,#1

cmp r3,#0x0

bne delay13
mov pc,lr

blink3:
ldr	r0, =GPBDAT
ldr	r1, =0x0a0
str	r1, [r0]

stmfd	sp!,{lr}

bl delay

ldr	r0, =GPBDAT
ldr	r1, =0x140
str	r1, [r0]

bl delay

ldmfd	sp!,{lr}
mov pc,lr

main:
ledloop:

ldr r1,=0x1c0
str r1,[r2]
bl delay

ldr r1,=0x1a0
str r1,[r2]
bl delay

ldr r1,=0x160
str r1,[r2]
bl delay

ldr r1,=0x0e0
str r1,[r2]
bl delay

b ledloop

undefined_instruction:
nop
software_interrupt:
nop
prefetch_abort:
nop
data_abort:
nop
not_used:
nop
fiq:
nop


代码比较繁琐,有几点值得注意:在嵌套中断处理中,压栈后先保存INTOFFSET的值,再清中断(SRCPND和INTPND).因为SRCPND和INTPND清除后INTOFFSET就自动清除了,所以要先保存.在中断服务程序中,是可以用bl跳转到各自的中断服务程序的,比如blne blink1和blne blink3,值得对比的blink1和blink3,他们的不同在于blink1自己用代码做了延时,而blink3是调用bl delay做的延时,那么这个时候要注意的就是lr的push和pop操作,不然lr就被覆盖了,程序不能正确返回了.

注意了以上两点,程序上达到了嵌套处理的效果.因为采用的是下降边沿触发,而按键没有防抖处理,有时候单按一个键就有嵌套中断了.最后总结一下这种处理的优缺点:优点是在为一个中断处理服务完成前允许其它中断,以缩短中断延迟;而缺点是不处理中断的优先级,因此低优先级的中断会阻塞高优先级的中断.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: