;******************************************************************************
;Vectors.s
;******************************************************************************
;定義堆棧的大小,根據需要改變
FIQ_STACK_LENGTH EQU 0
IRQ_STACK_LENGTH EQU 64
ABT_STACK_LENGTH EQU 0
UND_STACK_LENGTH EQU 0
;VICVectAddr寄存器地址
VICVectAddr EQU 0xFFFFF030
;用於置位程序狀態寄存器的I位(IRQ中斷屏蔽位)
NoInt EQU 0x80
;引入的外部標號在這聲明
IMPORT FIQ_Exception ;快速中斷異常處理程序
IMPORT SoftwareInterrupt ;軟中斷入口
IMPORT Reset ;復位向量入口
IMPORT OSIntCtxSw ;中斷中任務切換函數
IMPORT OSIntExit ;中斷退出函數
IMPORT OSTCBCur ;指向當前任務TCB的指針
IMPORT OSTCBHighRdy ;指向將要運行的任務TCB的指針(最高優先級任務)
IMPORT OSIntNesting ;中斷嵌套計數器
;給外部使用的標號在這聲明,InitStack是必須的
EXPORT InitStack
EXPORT Vectors
CODE32
AREA StartUp,CODE,READONLY
ENTRY
;中斷向量表
Vectors
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0] ;VICVectAddr寄存器的地址0xFFFFF030
LDR PC, FIQ_Addr
ResetAddr DCD Reset
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
nouse DCD 0
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
;中斷服務程序與C語言的接口的宏定義
MACRO
$IRQ_Label HANDLER $IRQ_Exception
EXPORT $IRQ_Label ;輸出的標號
IMPORT $IRQ_Exception ;引用的外部標號
$IRQ_Label
SUB LR, LR, #4 ;計算返回地址
STMFD SP!, {R0-R3, R12, LR} ;保存任務環境
MRS R3, SPSR ;保存狀態
STMFD SP!, {R3}
LDR R2, =OSIntNesting ;OSIntNesting++
LDRB R1, [R2]
ADD R1, R1, #1
STRB R1, [R2]
BL $IRQ_Exception ;調用C語言的中斷處理程序
;MSR寫狀態寄存器指令使得CPSR[7:0]=0b10010010
;作用爲關IRQ中斷
MSR CPSR_c, #0x92
BL OSIntExit ;調用OSIntExit
;比較OSTCBHighRdy和OSTCBCur
;作用爲判斷在退出中斷處理之後是否進行任務切換
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR R1, =OSTCBCur
LDR R1, [R1]
CMP R0, R1
LDMFD SP!, {R3}
MSR SPSR_cxsf, R3 ;SPSR[31:0]=R3
LDMEQFD SP!, {R0-R3, R12, PC}^ ;不進行任務切換則恢復任務環境
LDR PC, =OSIntCtxSw ;進行任務切換則調用OSIntCtxSw
MEND
;未定義指令
Undefined
b Undefined
;取指令中止
PrefetchAbort
b PrefetchAbort
;取數據中止
DataAbort
b DataAbort
;中斷(HANDLER宏調用)
IRQ_Handler HANDLER IRQ_Exception
;快速中斷
FIQ_Handler
STMFD SP!, {R0-R3, LR}
BL FIQ_Exception
LDMFD SP!, {R0-R3, LR}
SUBS PC, LR, #4
;定時器0中斷(HANDLER宏調用)
Timer0_Handler HANDLER Timer0
;/***********************************************************************************
;**函數名稱: InitStack
;** 功能描述: 初始化堆棧
;** 輸 入: 無
;** 輸 出 : 無
;** 全局變量: 無
;** 調用模塊: 無
;***********************************************************************************
InitStack
MOV R0, LR ;使用R0來保存返回地址
;設置中斷模式堆棧
MSR CPSR_c, #0xd2
LDR SP, StackIrq
;設置快速中斷模式堆棧
MSR CPSR_c, #0xd1
LDR SP, StackFiq
;設置中止模式堆棧
MSR CPSR_c, #0xd7
LDR SP, StackAbt
;設置未定義模式堆棧
MSR CPSR_c, #0xdb
LDR SP, StackUnd
;設置系統模式堆棧
MSR CPSR_c, #0xdf
LDR SP, StackIrq
MOV PC, R0 ;使用R0來返回
StackIrq DCD (IrqStackSpace + IRQ_STACK_LENGTH * 4 - 4)
StackFiq DCD (FiqStackSpace + FIQ_STACK_LENGTH * 4 - 4)
StackAbt DCD (AbtStackSpace + ABT_STACK_LENGTH * 4 - 4)
StackUnd DCD (UndtStackSpace + UND_STACK_LENGTH * 4 - 4)
;/* 分配堆棧空間 */
AREA MyStacks, DATA, NOINIT
IrqStackSpace SPACE IRQ_STACK_LENGTH * 4 ;中斷模式堆棧空間
FiqStackSpace SPACE FIQ_STACK_LENGTH * 4 ;快速中斷模式堆棧空間
AbtStackSpace SPACE ABT_STACK_LENGTH * 4 ;中止義模式堆棧空間
UndtStackSpace SPACE UND_STACK_LENGTH * 4 ;未定義模式堆棧
END