μcos-II中运行的程序是多任务的,但每次只能有一个任务获得CPU使用权然后运行程序,而每个任务自身却又都是无限循环的,那么问题就来了,既然每个任务都是无限循环的,那么一旦高优先级任务获得了CPU使用权后,低优先级任务是怎么得到执行的呢?
这就涉及到了任务延时的问题,为了保证任务能够进行切换,每个任务就得在自己执行的程序里面调用延时函数,例如OSTimeDly()函数,使当前的任务在运行到延时函数的时候,让出CPU的使用权,使得CPU去执行其它的任务。通过这样的方法,使得任务间可以进行不断地切换,OSTimeDly()函数代码如下:
这就涉及到了任务延时的问题,为了保证任务能够进行切换,高优先级任务就得在自己执行的程序里面调用延时函数,例如OSTimeDly()函数,使当前的任务在运行到延时函数的时候,让出CPU的使用权,使得CPU去执行其它的任务。通过这样的方法,使得低优先级任务可以得到执行,OSTimeDly()函数代码如下:
void OSTimeDly (INT16U ticks)
{
#if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3
OS_CPU_SR cpu_sr;
#endif
if (ticks > 0) {
//如果延时设定为0值,表示不想对任务延时,返回调用任务
OS_ENTER_CRITICAL(); //关闭中断
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
/* Delay current task */
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
//非0值会使得任务延时函数OSTimeDly()将当前任务从就绪表中移除
OSTCBCur->OSTCBDly = ticks; //接着,这个延时节拍数会被保存在当前任务的OS_TCB中
OS_EXIT_CRITICAL(); //打开中断
OS_Sched(); //既然任务已经不再处于就绪任务,(任务调度),任务调度程序会执行下一个优先级最高的就绪任务
}
}
μcos-II中运行的程序是多任务的,但每次只能有一个任务获得CPU使用权然后运行程序,而每个任务自身却又都是无限循环的,那么问题就来了,既然每个任务都是无限循环的,那么μcos-II系统是怎么做到任务之间能够相互切换的呢?这就涉及到了任务延时的问题,为了保证任务能够进行切换,每个任务就得在自己执行的程序里面调用延时函数,例如OSTimeDly()函数,使当前的任务在运行到延时函数的时候,让出CPU的使用权,使得CPU去执行其它的任务。通过这样的方法,使得任务间可以进行不断地切换,OSTimeDly()函数代码如下:
INT8U OSTimeDlyResume (INT8U prio)
{
OS_TCB *ptcb;
if (prio >= OS_LOWEST_PRIO) { /*优先级判别*/
return (OS_ERR_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio]; /*任务必须存在才能恢复 */
if (ptcb == (OS_TCB *)0) {
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST); /*任务优先级指针表中没有此任务*/
}
if (ptcb == OS_TCB_RESERVED) {
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST); /*任务还是不存在,该任务块被其他任务占用*/
}
if (ptcb->OSTCBDly == 0u) { /*任务是否被延时,或设置了超时,若没有,本函数将无的放矢*/
OS_EXIT_CRITICAL();
return (OS_ERR_TIME_NOT_DLY); (1)
}
ptcb->OSTCBDly = 0u; /*OSTCBDly被强行设置为0*/
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) (2)
/*都是我们熟悉的数据结构,如果任务在等待事件的发生*/
{
ptcb->OSTCBStat&= ~OS_STAT_PEND_ANY; /*清OSTCBStat中的事件等待标志*/ (3)
ptcb->OSTCBStatPend=OS_STAT_PEND_TO; /*指示不再等待的原因是因为超时*/
}
else {
/*对于只是时间延时的任务*/
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;/*结束等待的原因是等待结束了(恢复了延时的任务)*/
}
/*如果任务不是被挂起,对被挂起的任务一定要用OSTaskResume 来恢复*/
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { (4)
/*以下使任务就绪*/
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
/*被恢复的任务可能是比现在运行的任务具有更高的优先级,因此在这里执行一次任务调度,不需要等到
时钟中断*/
OS_Sched();
}
else {
OS_EXIT_CRITICAL(); /*任务是被挂起的,不允许使用本函数恢复*/
}
return (OS_ERR_NONE);
}