在移植ucos2.86的版本到STM32f103时,遇到的一些疑问
移植ucosii 所遇到的疑问:
1、在任务调度函数中void OS_Sched (void)有这么两行代码:
void OS_Sched (void){
。。。。。。。。。。。//省略
if (OSPrioHighRdy != OSPrioCur) {
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
。。。。。。。。。。。。//省略
}
为什么只要判断就绪的最高优先级任务不是当前任务就可以了呢?UCOS不是可剥夺型的内核嘛?应该是就绪任务表中的最高优先级任务小于或者说优先级高于当前任务,就进行任务切换嘛?
解答:
其实不用做比较的原因不是其他的函数做了这个工作,是因为连当前运行的任务也在整个就绪任务表中,就绪的任务变为运行态以后,并没用把他从就绪表中删除,所以就绪任务表中最高就绪优先级的任务只用两种情况一种是比当前运行态的任务优先级高的任务进入了就绪态,一个就是当前运行的任务。就绪的任务只有当调用OSTaskDel()或者OSTaskSuspend()以后,才会从就绪表中删除。
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-0x20?
解答:
因为0x20=32,所以R0=R0-32,相当于向后移动一个单元(一个字长)。
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]决定的嘛?
解答:
在<<Cortex-M3权威指南>>的最后附录E中,E.2(设计Fault服务例程)中的E.2.2.2上报入栈的PC一节中有范例,通过LR.2来确定当时使用的是MSP还是PSP。