浅析μC/OS-II OSTimeDly()函数和OSTimeTick()函数工作原理

浅析μC / OS - II v2 . 85内核OSTimeDly ( ) 函数工作原理

文章来源 : http : //gliethttp.cublog.cn[转载请声明出处]

//----------------------------------------------------------------------
//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 ;
         }
//延时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,那么什么也不做
}
//----------------------------------------------------------------------
//2.OSTimeTick()--在定时中断里引用的系统滴答函数
void  OSTimeTick  ( void )
{
    OS_TCB  * ptcb ;
# if  OS_TICK_STEP_EN  >  0
    BOOLEAN step ;
# endif
# if  OS_CRITICAL_METHOD  = =  3
    OS_CPU_SR cpu_sr  =  0 ; //该3方式将使中断状态寄存器放入堆栈中

# endif

# if  OS_TIME_TICK_HOOK_EN  >  0
    OSTimeTickHook ( ) ;
# endif
# if  OS_TIME_GET_SET_EN  >  0
    OS_ENTER_CRITICAL ( ) ;
    OSTime + + ;
    OS_EXIT_CRITICAL ( ) ;
# endif
     if   ( OSRunning  = =  OS_TRUE )   {
# if  OS_TICK_STEP_EN  >  0
//控制内核的tick
         switch   ( OSTickStepState )   {
             case  OS_TICK_STEP_DIS :
                 step  =  OS_TRUE ;
                  break ;
             case  OS_TICK_STEP_WAIT :
                 step  =  OS_FALSE ;
                  break ;
             case  OS_TICK_STEP_ONCE :
//本次tick将将影响到task的OSTCBDly域
//但以后的tick将一直被屏蔽,不会影响到OSTCBDly域
//直到外部将OSTickStepState改变为止[gliethttp]
                 step  =  OS_TRUE ;
                 OSTickStepState  =  OS_TICK_STEP_WAIT ;
                  break ;
             default :
                 step  =  OS_TRUE ; //本次tick将影响到task的OSTCBDly域
                 OSTickStepState  =  OS_TICK_STEP_DIS ;
                  break ;
         }
         if   ( step  = =  OS_FALSE )   {
             return ;
         }
# endif
        ptcb  =  OSTCBList ;
//2007-09-08 gliethttp
//OSTCBList是一个按进程创建的先后顺序链接成的task单向链表,最后创建的task在最前面,最先创建的
//task在单向链表的尾端,
//所以OS_TaskIdle空闲进程在链表的最后,因为它最先创建
         while   ( ptcb - > OSTCBPrio  ! =  OS_TASK_IDLE_PRIO )   {
            OS_ENTER_CRITICAL ( ) ;
             if   ( ptcb - > OSTCBDly  ! =  0 )   {
                 if   ( - - ptcb - > OSTCBDly  = =  0 )   {
//该task的延时时间已到,解析此次延时是OSTimeDly()引起的,还是OSQPend()之类超时引起的[gliethttp]
                     if   ( ( ptcb - > OSTCBStat  &  OS_STAT_PEND_ANY )   ! =  OS_STAT_RDY )   {
                         //2007-09-08 gliethttp
                         //如:由OSSemPend (pevent,timeout,perr);定义的timeout已经到了,对应task需要运行了
                         //超时时间到,所以不论当前进程是在做什么,只要时间一到
                         //该task就可以运行了,所以清除所有事件标志,之后状态标示为OS_STAT_PEND_TO(超时)
                        ptcb - > OSTCBStat  & =   ~ ( INT8U ) OS_STAT_PEND_ANY ;
                        ptcb - > OSTCBStatPend  =  OS_STAT_PEND_TO ; //超时异常
                     }   else   {
                         //2007-09-08 gliethttp
                         //说明该task调用的是OSTimeDly()
                        ptcb - > OSTCBStatPend  =  OS_STAT_PEND_OK ; //正常结束
                     }
                     if   ( ( ptcb - > OSTCBStat  &  OS_STAT_SUSPEND )   = =  OS_STAT_RDY )   {
                         //2007-09-08 gliethttp
                         //如果该task没有suspend,那么把当前就绪的task加入到运行调度器的就绪控制矩阵中
                         //等待被调度
                        OSRdyGrp  | =  ptcb - > OSTCBBitY ;
                        OSRdyTbl [ ptcb - > OSTCBY ]   | =  ptcb - > OSTCBBitX ;
                     }
                 }
             }
            ptcb  =  ptcb - > OSTCBNext ; //继续运算下一个task的OSTCBDly时间域
            OS_EXIT_CRITICAL ( ) ;
         }
     }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值