本文共 3137 字,大约阅读时间需要 10 分钟。
;******************************************************************************;Vectors.s;******************************************************************************;定义堆栈的大小,根据需要改变FIQ_STACK_LENGTH EQU 0IRQ_STACK_LENGTH EQU 64ABT_STACK_LENGTH EQU 0UND_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 VectorsCODE32
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 ResetUndefinedAddr DCD UndefinedSWI_Addr DCD SoftwareInterruptPrefetchAddr DCD PrefetchAbortDataAbortAddr DCD DataAbortnouse DCD 0IRQ_Addr DCD IRQ_HandlerFIQ_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, NOINITIrqStackSpace SPACE IRQ_STACK_LENGTH * 4 ;中断模式堆栈空间FiqStackSpace SPACE FIQ_STACK_LENGTH * 4 ;快速中断模式堆栈空间AbtStackSpace SPACE ABT_STACK_LENGTH * 4 ;中止义模式堆栈空间UndtStackSpace SPACE UND_STACK_LENGTH * 4 ;未定义模式堆栈 END
转载地址:http://lenqj.baihongyu.com/