最近研究了一下光盘中关于ucos2一种的问题 其中关于任务切换函数不是很明白 光盘源代码如下:
OSIntCtxSw ;下面为保存任务环境 1 LDR R2, [SP, #20] ;获取PC 2 LDR R12, [SP, #16] ;获取R12 3 MRS R0, CPSR
4 MSR CPSR_c, #(NoInt | SYS32Mode) 5 MOV R1, LR 6 STMFD SP!, {R1-R2} ;保存LR,PC 7 STMFD SP!, {R4-R12} ;保存R4-R12
8 MSR CPSR_c, R0 9 LDMFD SP!, {R4-R7} ;获取R0-R3 10 ADD SP, SP, #8 ;出栈R12,PC 11 MSR CPSR_c, #(NoInt | SYS32Mode) 12 STMFD SP!, {R4-R7} ;保存R0-R3 13 LDR R1, =OsEnterSum ;获取OsEnterSum 14 LDR R2, [R1] 15 STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum
;保存当前任务堆栈指针到当前任务的TCB 16 LDR R1, =OSTCBCur 17 LDR R1, [R1] 18 STR SP, [R1]
19 BL OSTaskSwHook ;调用钩子函数 ;OSPrioCur <= OSPrioHighRdy 20 LDR R4, =OSPrioCur 21 LDR R5, =OSPrioHighRdy 22 LDRB R6, [R5] 23 STRB R6, [R4] ;OSTCBCur <= OSTCBHighRdy 24 LDR R6, =OSTCBHighRdy 25 LDR R6, [R6] 26 LDR R4, =OSTCBCur 27 STR R6, [R4] OSIntCtxSw_1 ;获取新任务堆栈指针 28 LDR R4, [R6] 29 ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP 30 LDR LR, [SP, #-8] 31 MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式 32 MOV SP, R4 ;设置堆栈指针
33 LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum ;恢复新任务的OsEnterSum 34 LDR R3, =OsEnterSum 35 STR R4, [R3] 36 MSR SPSR_cxsf, R5 ;恢复CPSR 37 LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
我的理解是: 1-15是将当前模式(也就是管理模式或者是IRQ中断模式)下的R0-R3,R12和LR(也就是用户/系统模式下的PC)转移到系统模式的堆栈当中,同时将R4-R11和LR(用户/系统模式下LR)保存到系统模式的堆栈当中。 18是将系统模式的堆栈指针赋给OSTCBCur->OSTCBStkPtr
这是为什么啊? 在任务切换的时候应该将当前任务运行的上下文保存到当前任务的堆栈中才可以啊
我查看了一下你们公司的ARM问题.pdf资料文档。看到了对126问的回答:其中说:任务是运行在用户/系统模式下的,这两个模式使用同一个SP,这时系统模式的SP指向的就是任务的堆栈
为什么系统模式的SP指向的就是任务的堆栈?
系统运行时每个任务都分配了自己的堆栈,用户/系统模式也有自己的堆栈 他们应该是不同地址空间的啊
不是很明白啊
请指教 谢谢!
|