ucos的时间管理机制(转) 收藏
一。时间管理机制
Ucos提供的延时基于系统时钟。在系统初始化时,会进行系统时钟的初始化。系统时钟一般由硬件的某个时钟提供,该时钟会定时中断,称为一个tick。在每个tick发生时,系统进入时钟中断ISR。ISR 调用OSTimeTick(). OSTimeTick()对OSTCBList链表中的每个任务的进行延时处理,即将任务的TCB中的.OSTimeDly--。若OSTimeDly=0, 如果任务不被挂起,则将任务就绪,等待调度。OSTCBList包含了系统中所有创建的任务。
任务延时,即将任务从就绪表中删除,将OSTimeDly置为合适的值。等待OSTimeDly=0时,再置为就绪,等待调度。
因此任务的延时,并不是要以延时任务时长,理想上总是tick中断间隔的N倍。
Ucos还允许对系统时钟tick进行计数,以计算自系统系统以来进行了多少个tick.
二、ucos提供的接口函数
void OSTimeDly (INT16U ticks).
功能:延时ticks个系统tick时长。当成功延时后,进行任务调度。
INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U milli)
功能:提供基于毫秒,秒等容易的用户接口。
INT8U OSTimeDlyResume (INT8U prio);
功能:恢复延时任务
INT32U OSTimeGet (void);
void OSTimeSet (INT32U ticks);
功能:返回,设置系统时钟tick计数.
三、关于延时功能的使用
虽然ucos提供了延时函数,但因为是基于系统时钟中断的,所有对于小于时钟中断时间间隔的延时,并不能提供;只能通过软件延时。
在很多情况下,可以通过信号量、邮箱等方式取代延时功能。
特别要注意的是,在多任务的运行环境中,即使任务延时已经完毕,但由于此时有高优先级的任务运行,此时任务仍不能运行。至任务可以运行时,实际的延时已经超过了预期的延时。
附:给出了OSTimeTick () 函数的具体程序
void OSTimeTick (void) //这个节拍服务函数是在OSTickISR函数中调用的,目的是在时钟节拍到来时,检查每个任务的任务控制块中的.OSTCBDly-1后是否为0,如果是,那么表明这个任务刚才是挂起的状态,此时应改变为就绪态
{
OS_TCB *ptcb;
OSTimeTickHook(); //
ptcb = OSTCBList; //时钟节拍到来时,将控制块双向链表的第一个控制块取出(并不是节拍之前运行的任务)
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { //空闲任务处于控制块双向链表的最后一个,如果取出的控制块为空闲任务的控制块,那么已经取到最后一个了,就结束
// OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) { //
if (--ptcb->OSTCBDly == 0) { //
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { //检查任务是否处于强制挂起状态,如果是,那再挂起一个时钟节拍,否则就将它就绪
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else { //
ptcb->OSTCBDly = 1; //
} //
}
}
ptcb = ptcb->OSTCBNext; //下一个任务控制块
// OS_EXIT_CRITICAL();
}
// OS_ENTER_CRITICAL(); //
OSTime++; //节拍计数器+1
// OS_EXIT_CRITICAL();
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhouyujia/archive/2009/11/03/4756626.aspx