startup.s里对swi的处理做些修改:把原来的SWI_Handler注释掉,import swi_handler(新标号在swi.s中)。你可能是没有修改startup.s
中的swi处理程序入口,导致进入死循环。
AREA RESET, CODE, READONLY
ARM
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP ; Reserved Vector
; LDR PC, IRQ_Addr
LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr
LDR PC, FIQ_Addr
IMPORT SWI_Handler
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
;SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IRQ_Handler B IRQ_Handler
FIQ_Handler B FIQ_Handler
新建的swi.s文件如下
I_Bit EQU 0x80
F_Bit EQU 0x40
T_Bit EQU 0x20
AREA SWI_Area, CODE, READONLY
ARM
PRESERVE8
EXPORT SWI_Handler ; 供startup.s调用
SWI_Handler STMFD SP!, {R8, R12, LR}
MRS R12, SPSR
TST R12, #T_Bit ; 判断是SWI指令是处于哪种状态下
LDREQ R12, [LR,#-4] ; ARM: Load Word
BICEQ R12, R12, #0xFF000000 ; 获取中断号
LDRNEH R12, [LR,#-2] ; Thumb: Load Halfword
BICNE R12, R12, #0xFF00 ; 获取中断号
LDR R8, SWI_Count
CMP R12, R8 ; 判断中断号是否溢出
BHS SWI_Overflow
ADR R8, SWI_Table
LDR R12, [R8,R12,LSL #2] ; Load SWI Function Address
MOV LR, PC ; Return Address
BX R12 ; Call SWI Function
LDMFD SP!, {R8, R12, PC}^ ; Restore R12 and Return
SWI_Overflow B SWI_Overflow ; None Existing SWI
SWI_Cnt EQU (SWI_End-SWI_Table)/4
SWI_Count DCD SWI_Cnt
SWI_Table
DCD __SWI_0 ; SWI 0 Function Entry
DCD __SWI_1 ; SWI 1 Function Entry
SWI_End
; Enable IRQ
__SWI_0 MRS R0, SPSR
BIC R0, R0, #I_Bit
MSR SPSR_c, R0
BX LR
; Disable IRQ
__SWI_1 MRS R0, SPSR
ORR R0, R0, #I_Bit
MSR SPSR_c, R0
BX LR
END
在main函数前定义swi函数
void __swi(0) IRQ_Enable( void );
void __swi(1) IRQ_Disable( void );
然后就可以直接IRQ_Enable( )和IRQ_Disable( )来开关中断了。 |