OSIntCtxSw
;下面为保存任务环境
LDR R2, [SP, #20] ;获取PC
LDR R12, [SP, #16] ;获取R12
MRS R0, CPSR
MSR CPSR_c, #(NoInt | SYS32Mode)
MOV R1, LR
STMFD SP!, {R1-R2} ;保存LR,PC
STMFD SP!, {R4-R12} ;保存R4-R12
MSR CPSR_c, R0
LDMFD SP!, {R4-R7} ;获取R0-R3
ADD SP, SP, #8 ;出栈R12,PC
MSR CPSR_c, #(NoInt | SYS32Mode)
STMFD SP!, {R4-R7} ;保存R0-R3
LDR R1, =OsEnterSum ;获取OsEnterSum
LDR R2, [R1]
STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum
;保存当前任务堆栈指针到当前任务的TCB
LDR R1, =OSTCBCur
LDR R1, [R1]
STR SP, [R1]
BL OSTaskSwHook ;调用钩子函数
;OSPrioCur <= OSPrioHighRdy
LDR R4, =OSPrioCur
LDR R5, =OSPrioHighRdy
LDRB R6, [R5]
STRB R6, [R4]
;OSTCBCur <= OSTCBHighRdy
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
LDR R4, =OSTCBCur
STR R6, [R4]
OSIntCtxSw_1
;获取新任务堆栈指针
LDR R4, [R6]
ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
LDR R3, =OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
上面红色的部分看不懂,这段函数是任务切换函数,和中断任务切换。中断任务切换和任务切换的有一部分一样,所以共用。任务切换就是把低优先级的任务入栈,高优先级的任务出栈。
ARM7的特殊性,有7中工作模式。任务工作在系统模式或用户模式。其他的模式都是用异常进入的。
上面的代码让我和困惑,LDR R2,[SP,#20];怎么是获取PC值呢,这个PC应该是该函数上次保存的吧,这次的任务切换应该给它覆盖掉,因为要保持PC也是要从当前的工作寄存器中读取呀。还有就是R12有什么特殊的意义没有,问什么要单独保存。R0-R3,和R4-R11也不同,是什么规则???ATPCS只是ARM,THUMB程序调用规则,和你要保存的寄存器也没有什么关系呀!!!!!!!十分不理解上面的代码到底是怎么来的,有什么规则吗?还请各位高手给点指点,谢谢大家了!!!!!! |