µC/OS-Ⅱ允许用户结束延时正处于延时期的任务。延时的任务可以不等待延时期满,而是通过其它任务取消延时来使自己处于就绪态。这可以通过调用OSTimeDlyResume()和指定要恢复的任务的优先级来完成。实际上,OSTimeDlyResume()也可以唤醒正在等待事件(参看第六章——任务间的通讯和同步)的任务,虽然这一点并没有提到过。在这种情况下,等待事件发生的任务会考虑是否终止等待事件。
OSTimeDlyResume()的代码如程序清单 L5.3所示,它首先要确保指定的任务优先级有效 [L5.3(1)]。接着,OSTimeDlyResume()要确认要结束延时的任务是确实存在的[L5.3(2)]。如果任务存在,OSTimeDlyResume()会检验任务是否在等待延时期满[L5.3(3)]。只要OS_TCB域中的OSTCBDly包含非0值就表明任务正在等待延时期满,因为任务调用了OSTimeDly(),OSTimeDlyHMSM()或其它在第六章中所描述的PEND函数。然后延时就可以通过强制命令OSTCBDly为0来取消[L5.3(4)]。延时的任务有可能已被挂起了,这样的话,任务只有在没有被挂起的情况下才能处于就绪状态[L5.3(5)]。当上面的条件都满足后,任务就会被放在就绪表中[L5.3(6)]。这时,OSTimeDlyResume()会调用任务调度程序来看被恢复的任务是否拥有比当前任务更高的优先级[L5.3(7)]。这会导致任务的切换。
程序清单 L 5.3 恢复正在延时的任务
INT8U OSTimeDlyResume (INT8U prio)
{
OS_TCB *ptcb;
if (prio >= OS_LOWEST_PRIO) { (1)
return (OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
ptcb = (OS_TCB *)OSTCBPrioTbl[prio];
if (ptcb != (OS_TCB *)0) { (2)
if (ptcb->OSTCBDly != 0) { (3)
ptcb->OSTCBDly = 0; (4)
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { (5)
OSRdyGrp |= ptcb->OSTCBBitY; (6)
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OSSched(); (7)
} else {
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (OS_TIME_NOT_DLY);
}
} else {
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);
}
}
注意,用户的任务有可能是通过暂时等待信号量、邮箱或消息队列来延时自己的(参看第六章)。可以简单地通过控制信号量、邮箱或消息队列来恢复这样的任务。这种情况存在的唯一问题是它要求用户分配事件控制块(参看6.00),因此用户的应用程序会多占用一些RAM。
让处在延时期的任务结束延时,OSTimeDlyResume()
最新推荐文章于 2021-11-23 16:45:08 发布