初级会员
- 积分
- 69
- 金钱
- 69
- 注册时间
- 2012-5-19
- 在线时间
- 0 小时
|
首先我把我有疑问的这段代码挑选出来,然后选出里面有疑问的代码:
OS_CPU_PendSVHandler ;xPSR, PC, LR, R12, R0-R3 已自动保存
CPSID I ;任务切换期间需要关中断
MRS R0, PSP ;R0 = PSP
;如果PSP == 0,跳到OS_CPU_PendSVHandler_nosave 执行 #1
CBZ R0, OS_CPU_PendSVHandler_nosave
;保存R4-R11 到任务堆栈
SUBS R0, R0, #0x20 ;R0 -= 0x20
STM R0, {R4-R11} ;保存 R4-R11到任务堆栈
;OSTCBCur->OSTCBStkPtr = SP;
LDR R1, =OSTCBCur ;R1 = &OSTCBCur
LDR R1, [R1] ;R1 = *R1 (R1 = OSTCBCur)
STR R0, [R1] ;*R1 = R0 (*OSTCBCur = SP) #2
OS_CPU_PendSVHandler_nosave
;调用OSTaskSwHook()
 USH {R14} ;保存R14,因为后面要调用函数
LDR R0, =OSTaskSwHook ;R0 = &OSTaskSwHook
BLX R0 ;调用OSTaskSwHook()
POP {R14} ;恢复 R14
;OSPrioCur = OSPrioHighRdy;
LDR R0, =OSPrioCur ;R0 = &OSPrioCur
LDR R1, =OSPrioHighRdy ;R1 = &OSPrioHighRdy
LDRB R2, [R1] ;R2 = *R1 (R2 = OSPrioHighRdy)
STRB R2, [R0] ;*R0 = R2 (OSPrioCur = OSPrioHighRdy)
;OSTCBCur = OSTCBHighRdy;
LDR R0, =OSTCBCur ;R0 = &OSTCBCur
LDR R1, =OSTCBHighRdy ;R1 = &OSTCBHighRdy
LDR R2, [R1] ;R2 = *R1 (R2 = OSTCBHighRdy)
STR R2, [R0] ;*R0 = R2 (OSTCBCur = OSTCBHighRdy)
LDR R0, [R2] ;R0 = *R2 (R0 = OSTCBHighRdy), 此时 R0是新任
的 SP
;SP = OSTCBHighRdy->OSTCBStkPtr #3
LDM R0, {R4-R11} ;从任务堆栈SP恢复R4-R11
ADDS R0, R0, #0x20 ;R0 += 0x20
MSR  SP, R0 SP = R0,用新任务的 SP加载PSP
ORR LR, LR, #0x04 ;确保 LR 位2 为 1,返回后使用进程堆栈 #4
CPSIE I ;开中断
BX LR ;中断返回
END
然后下面这些是我的不解之处,希望能有人帮忙解答出来:
移植ucosii 所遇到的疑问:
1、在任务调度函数中void OS_Sched (void)有这么两行代码:
void OS_Sched (void){
。。。。。。。。。。。//省略
if (OSPrioHighRdy != OSPrioCur) {
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
。。。。。。。。。。。。//省略
}
为什么只要判断就绪的最高优先级任务不是当前任务就可以了呢?UCOS不是可剥夺型的内核嘛?应该是就绪任务表中的最高优先级任务小于或者说优先级高于当前任务,就进行任务切换嘛?
2、在os_cpu_a.asm文件中的PendSV 中断处理函数OS_CPU_PendSVHandler里面有这么一段话:
;保存R4-R11 到任务堆栈
SUBS R0, R0, #0x20 ;R0 -= 0x20 //有疑问的地方
//为什么要先让R0=R0-20?
STM R0, {R4-R11} ;保存 R4-R11到任务堆栈
;OSTCBCur->OSTCBStkPtr = SP;
LDR R1, =OSTCBCur ;R1 = &OSTCBCur
LDR R1, [R1] ;R1 = *R1 (R1 = OSTCBCur)
STR R0, [R1] ;*R1 = R0 (*OSTCBCur = SP) #2
(加颜色为有疑问的地方。)为什么要先让R0=R0-20?
3、在os_cpu_a.asm文件中的PendSV 中断处理函数OS_CPU_PendSVHandler的最后几句代码里面有这么一条代码:
ORR LR, LR, #0x04 ;确保 LR 位2 为 1,返回后使用进程堆栈 #4
为什么在这里要确保LR的位2为1?
有人这么解释的“因为在中断处理函数中使用的是 MSP,所以在返回任务后必须使用PSP,所以LR位2 必须为 1。”但是如果这么样的话,我又有疑问了,是使用MSP还是PSP不是由CONTROL[1]决定的嘛?
|
|