为什么说ucos ii是可剥夺的内核。

学习自:http://blog.csdn.net/lovekwf/article/details/8215355


即当高优先级的任务由于时钟DLY被阻塞时,一个低优先级的任务正无限循环中。当更高优先级的任务时间片延时到0时,会剥夺低优先级任务的执行。笔者在ccs下挖根寻源,找到了它可以剥夺的原因。

在此前先要了解,Ucos是实时操作系统,CPU被用来按照一个Tick,一个Tick的去执行指令,而每一个Tick是由分频的定时器产生的,每一个Tick(嘀嗒)都会引起系统的一次中断, tick (an interrupt generated by a hardware timer at a fixed time interval),它的ISR是OSTimeTick();一个Tick会调用一次OSTimeTick(),该函数内部会对OSTime(全局变量)加一。

还要了解,TCBlist是一个双向链表,它的每一个元素是一个TCB(任务控制块),包含了每一个任务的堆栈,优先级大小,以及状态信息(比如被切换了几次),待延时的Tick数(OSTCBDLY),OSTCBStat(任务当前状态)等重要信息。中断处理函数中会遍历每一个TCB,并会将OSTCBDLY不为0 的任务的OSTCBDLY减一。当判断OSTCBDLY为0时,会更新OSRdyGrp(一个全局变量记录当前就绪任务),否则其OSTCBStat继续是阻塞的。

有这些认识,遗憾的发现没有在这个Tick中断服务程序中发现OSIntctxsw(),OSShed()调用。那么OS究竟是如何在有更高优先级进入就绪时,产生调度的呢?

用汇编跟踪,发现,所有的中断在服务开始的时候会调用OSIntEnter(),主要内容是增加嵌套调用的计数。而与之对应的是在所有中断服务结束之前,内核会调用OSIntExit()(在OS_Core.c中)。

这两个函数成对出现,在OSIntExit(),发现了OS_ShedNew();进入这个函数,终于发现,原来这个函数会计算所有目前就绪的任务的最高的优先级,并判断如果这个值和当前在执行任务的优先级是否相同,如果相同的话,就继续执行当前任务,否则OSIntTcxSw()做上下文切换。

切换就不用多说了,把任务的上下文切换,就是把R0-R12,LR,PC和SPSR等寄存器换成更高优先级的任务的上下文。


总结:每一次Tick中断都会引起中断,在中断退出时,会把切换到当前所有就绪的任务中最高优先级任务。


你可能感兴趣的:(操作系统,CC++)