μCOS-II系统之时间管理函数OSTimeDly()

μC/OS-II提供了若干个时间管理服务函数,可以满足任务在运行过程中对时间管理的需求。在使用时间管理服务函数时,必须十分清楚一个事实:时间管理 服务函数是以系统节拍为处理单位的,实际的时间与希望的时间是有误差的,最坏的情况下误差接近一个系统节拍。因此时间管理服务函数只能用在对时间精度要求 不高的场合,或者时间间隔较长的场合。

下面来分析系统延时函数OSTimeDly()调用图解:

渭COS-II系统之时间管理函数OSTimeDly()

 

在Task中,一般执行一段时间之后调用OSTimeDly推迟一段时间再继续运行,OSTimeDly将本进程从Ready TCBList中删除,然后将Delay的时间设置给OSTCBDly,最后调用OS_Sched进行进程调度。

//----------------------------------------------------------------------
//1.OSTimeDly()函数
void OSTimeDly (INT16U ticks)
{
    INT8U y;
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr = 0;
#endif
    if (OSIntNesting > 0) {
        return;//在中断处理函数中调用了OSTimeDly(),那么直接退出
    }
    if (ticks > 0) {
        OS_ENTER_CRITICAL();
//调用OSTimeDly()的进程自己把自己从就绪控制矩阵中拿下来,
//即:去掉调度器(x,y)矩形阵列(OSRdyTbl,OSRdyGrp)中该task对应的bit位,使得调度器不考虑
//该task的调度
        y = OSTCBCur->OSTCBY;
        OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0) {
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }

y为当前进程所在Group,OSRdyTbl[y]为该Group所在字节,&=~则将该字节中本进程所占用的Bit清零。如果 OSRdyTbl[y]为0,则说明这个Group中没有进程处于Ready状态,则将OSRdyGrp中该Group所占用的Bit清零。
//延时ticks值,放入OSTCBDly单元,在os时钟滴答处理函数OSTimeTick()中,会处理该单元[gliethttp]
        OSTCBCur->OSTCBDly = ticks;
        OS_EXIT_CRITICAL();
//因为本task正在运行,所以本task现在的优先级最高,现在本task已经将自己从就绪控制矩阵中--调度器(x,y)矩形阵列
//把自己摘掉,所以调度函数OS_Sched()一定会切换到另一个task中执行新task的代码[gliethttp]
        OS_Sched();//具体参见《浅析μC/OS-II v2.85内核调度函数》
    }//ticks==0,那么什么也不做
}

posted @ 2013-03-08 22:43  顶顶顶顶  阅读(689)  评论(0)    收藏  举报