ucosII 调度器上锁后执行OSTimeDly(n)的后果

今天写代码将调度器上锁了以后执行一个函数,结果在函数里用OSTimeDly(ticks)延时失效,经过阅读源码得知本该无效。

 

源码分析

给调度器上锁:

void OSSchedLock (void)
 
{
 
    if (OSRunning == TRUE) {
 
        OS_ENTER_CRITICAL();
 
        OSLockNesting++;
 
        OS_EXIT_CRITICAL();
 
    }
 
}
 


上面的函数将OSSchedLock()将OSLockNesting加1,而OSLockNesting是unsigned char类型的,

一般情况下OSLockNesting > 0 了(OSLockNesting自增前为255的话就为0);

 

任务延时:

void  OSTimeDly (INT16U ticks)
{
    INT8U      y;
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;



    cpu_sr = 0;                                  /* Prevent compiler warning                           */
#endif    
    if (ticks > 0) {                             /* 0 means no delay!                                  */
        OS_ENTER_CRITICAL();
        y            =  OSTCBCur->OSTCBY;        /* Delay current task                                 */
        OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0) {  
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBDly = ticks;              /* Load ticks in TCB                                  */
        OS_EXIT_CRITICAL();
        OS_Sched();                              /* Find next task to run!                             */
    }
}

上面的函数OSTimeDly(ticks)检测ticks是否大于0,一般传递延时都是大于0的,否则就是故意为了等时序了,

既然ticks>0,就会引发一次任务调度,执行OS_Sched()。

 

任务调度函数:

void  OS_Sched (void)
{
    INT8U      y;
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr;



    cpu_sr = 0;                                        /* Prevent compiler warning                     */
#endif    
    OS_ENTER_CRITICAL();
    if (OSIntNesting == 0) {                           /* Schedule only if all ISRs done and ...       */
        if (OSLockNesting == 0) {                      /* ... scheduler is not locked                  */
            y             = OSUnMapTbl[OSRdyGrp];      /* Get pointer to HPT ready to run              */
            OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
            if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy     */
                OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN > 0
                OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task      */
#endif
                OSCtxSwCtr++;                          /* Increment context switch counter             */
                OS_TASK_SW();                          /* Perform a context switch                     */
            }
        }
    }
    OS_EXIT_CRITICAL();
}


上面的函数OS_Sched ()检测到OSLockNesting != 0,自然不会执行if (OSLockNesting == 0)里面的内容,于是直接跳出函数了,

此时我们看PC指针是不是回到了OSTimeDly(ticks)的最后,那么此时程序将会执行的就是OSTimeDly(ticks)之后的代码了,

此处调度器上锁了,相当于OSTimeDly(ticks)白跑了一趟,而且飞快就跑完了,不但当前任务没挂起,而且也没有切换到其他任务,

没有真正的起到延时的作用

这就是为什么ucos说调度器上锁后用户不能调用任何能够引发调度的函数了,其实不是真的不能,是这样等于做无用功!

 

 

 

 

 

你可能感兴趣的:(ucosII 调度器上锁后执行OSTimeDly(n)的后果)