经过调试终于发现问题了。
OS_CPU_ARM_EXCEPT_HANDLER MRS R1, SPSR ; Save CPSR (i.e. exception's SPSR)
; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION ; SPSR.Mode = FIQ, IRQ, SVC, ABT, UND : Other exception ; SPSR.Mode = SYS : Task ; SPSR.Mode = USR : *unsupported state* AND R2, R1, #OS_CPU_ARM_MODE_MASK CMP R2, #OS_CPU_ARM_MODE_SYS//答案在这个地方,之前是系统模式,不跳转,顺序执行。
如果不是系统模式,就是进行嵌套处理。
BNE OS_CPU_ARM_EXCEPT_HANDLER_BreakExcept
;******************************************************************************************************** ; EXCEPTION HANDLER: TASK INTERRUPTED ;********************************************************************************************************
OS_CPU_ARM_EXCEPT_HANDLER_BreakTask MRS R2, CPSR ; Save exception's CPSR MOV R4, SP ; Save exception's stack pointer
; Change to SYS mode & disable interruptions MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
; SAVE TASK'S CONTEXT ONTO TASK'S STACK STMFD SP!, {R3} ; Push task's PC STMFD SP!, {LR} ; Push task's LR STMFD SP!, {R5-R12} ; Push task's R12-R5 LDMFD R4!, {R5-R9} ; Move task's R4-R0 from exception stack to task's stack STMFD SP!, {R5-R9}
TST R3, #1 ; See if called from Thumb mode ORRNE R1, R1, #OS_CPU_ARM_CONTROL_THUMB ; If yes, Set the T-bit STMFD SP!, {R1} ; Push task's CPSR (i.e. exception SPSR)
; if (OSRunning == 1) LDR R1, ?OS_Running LDRB R1, [R1] CMP R1, #1 BNE OS_CPU_ARM_EXCEPT_HANDLER_BreakTask_1
; HANDLE NESTING COUNTER LDR R3, ?OS_IntNesting ; OSIntNesting++; LDRB R4, [R3] ADD R4, R4, #1 STRB R4, [R3]
LDR R3, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP; LDR R4, [R3] STR SP, [R4]
OS_CPU_ARM_EXCEPT_HANDLER_BreakTask_1 MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE
LDR R1, ?OS_EXCEPT_HANDLER ; OS_EXCEPT_HANDLER(); MOV LR, PC BX R1
; Adjust exception stack pointer. This is needed because ; exception stack is not used when restoring task context. ADD SP, SP, #(14*4)
; Change to SYS mode & disable interruptions. MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
; Call OSIntExit(). This call MAY never return ; if a ready task with higher priority than ; the interrupted one is found. LDR R0, ?OS_IntExit MOV LR, PC BX R0
; RESTORE NEW TASK'S CONTEXT LDMFD SP!, {R0} ; Pop new task's CPSR MSR CPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC} ; Pop new task's context
;******************************************************************************************************** ; EXCEPTION HANDLER: EXCEPTION INTERRUPTED ;********************************************************************************************************
OS_CPU_ARM_EXCEPT_HANDLER_BreakExcept MRS R2, CPSR ; Save exception's CPSR
; Change to SYS mode & disable interruptions MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
; HANDLE NESTING COUNTER LDR R3, ?OS_IntNesting ; OSIntNesting++; LDRB R4, [R3] ADD R4, R4, #1 STRB R4, [R3]
MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE
LDR R3, ?OS_EXCEPT_HANDLER ; OS_EXCEPT_HANDLER(); MOV LR, PC BX R3
; Change to SYS mode & disable interruptions MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
; HANDLE NESTING COUNTER LDR R3, ?OS_IntNesting ; OSIntNesting--; LDRB R4, [R3] SUB R4, R4, #1 STRB R4, [R3]
MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE
LDMFD SP!, {R0-R12, PC}^ ; Pull working registers and return from exception.
[ 本帖最后由 lalahu 于 2011-6-3 12:45 编辑 ] |