UCOS挂起与延时

#if OS_TASK_SUSPEND_EN > 0u
INT8U  OSTaskSuspend (INT8U prio)
{
    BOOLEAN    self;
    OS_TCB    *ptcb;
    INT8U      y;
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif

#if OS_ARG_CHK_EN > 0u
    if (prio == OS_TASK_IDLE_PRIO) {                            /* Not allowed to suspend idle task    */
        return (OS_ERR_TASK_SUSPEND_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO) {                               /* Task priority valid ?               */
        if (prio != OS_PRIO_SELF) {
            return (OS_ERR_PRIO_INVALID);
        }
    }
#endif
    OS_ENTER_CRITICAL();
    if (prio == OS_PRIO_SELF) {                                 /* See if suspend SELF                 */
        prio = OSTCBCur->OSTCBPrio;
        self = OS_TRUE;
    } else if (prio == OSTCBCur->OSTCBPrio) {                   /* See if suspending self              */
        self = OS_TRUE;
    } else {
        self = OS_FALSE;                                        /* No suspending another task          */
    }
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb == (OS_TCB *)0) {                                  /* Task to suspend must exist          */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_SUSPEND_PRIO);
    }
    if (ptcb == OS_TCB_RESERVED) {                              /* See if assigned to Mutex            */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_NOT_EXIST);
    }
    y            = ptcb->OSTCBY;
    OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX;                   /* Make task not ready                 */
    if (OSRdyTbl[y] == 0u) {
        OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
    }
    ptcb->OSTCBStat |= OS_STAT_SUSPEND;                         /* Status of task is 'SUSPENDED'       */
    OS_EXIT_CRITICAL();
    if (self == OS_TRUE) {                                      /* Context switch only if SELF         */
        OS_Sched();                                             /* Find new highest priority task      */
    }
    return (OS_ERR_NONE);
}

挂起函数原型.判断挂起的是否是自己.如果是,就删除就绪,  状态做挂起记录ptcb->OSTCBStat |= OS_STAT_SUSPEND; 并任务调度.如果挂起的是别的任务 不调度.

 

延时函数原型如下 

void  OSTimeTick (void)
{
    OS_TCB    *ptcb;
#if OS_TICK_STEP_EN > 0
    BOOLEAN    step;
#endif

#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_TIME_TICK_HOOK_EN > 0
    OSTimeTickHook();                                      /* Call user definable hook */
#endif

#if OS_TIME_GET_SET_EN > 0
    OS_ENTER_CRITICAL();                                   /* Update the 32-bit tick counter */
    OSTime++;
    OS_EXIT_CRITICAL();
#endif

    if(OSRunning==OS_TRUE) 
	   {
         #if OS_TICK_STEP_EN > 0
             switch(OSTickStepState) 
			    {                         /* Determine whether we need to process a tick  */
                  case OS_TICK_STEP_DIS:                         /* Yes, stepping is disabled */
                           step = OS_TRUE;
                           break;

                  case OS_TICK_STEP_WAIT:                        /* No,  waiting for uC/OS-View to set ... */
                           step = OS_FALSE;                       /* .. OSTickStepState to OS_TICK_STEP_ONCE */
                           break;

                  case OS_TICK_STEP_ONCE:                        /* Yes, process tick once and wait for next ... */
                           step = OS_TRUE;                       /*... step command from uC/OS-View */
                           OSTickStepState = OS_TICK_STEP_WAIT;
                           break;

                  default:                                       /* Invalid case, correct situation */
                           step = OS_TRUE;
                           OSTickStepState = OS_TICK_STEP_DIS;
                           break;
                }
             if(step==OS_FALSE)    /* Return if waiting for step command  */
			    {                           
                  return;
                }
           #endif

             ptcb = OSTCBList;                          /* Point at first TCB in TCB list  */
             while(ptcb->OSTCBPrio!=OS_TASK_IDLE_PRIO)  /* Go through all TCBs in TCB list */
			    {     
                  OS_ENTER_CRITICAL();
                  if(ptcb->OSTCBDly!=0)    /* No, Delayed or waiting for event with TO */
				     {                                  
                       if(--ptcb->OSTCBDly==0) 		    /* Decrement nbr of ticks to end of delay */
					      {                             
                                                           /* Check for timeout */
                            if((ptcb->OSTCBStat&OS_STAT_PEND_ANY)!=OS_STAT_RDY) 
							   {
                                 ptcb->OSTCBStat&=~(INT8U)OS_STAT_PEND_ANY;  /* Yes, Clear status flag */
                                 ptcb->OSTCBStatPend = OS_STAT_PEND_TO;      /* Indicate PEND timeout */
                               } 
							else 
							   {
                                 ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
                               }

                            if((ptcb->OSTCBStat&OS_STAT_SUSPEND)==OS_STAT_RDY) /*Is task suspended? */
							   {  
                                  OSRdyGrp|= ptcb->OSTCBBitY;             /* No, Make ready */
                                  OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;
                               }
                          }
                      }
                   ptcb = ptcb->OSTCBNext;  /* Point at next TCB in TCB list */
                   OS_EXIT_CRITICAL();
                }
       }
}

其中 

                            if((ptcb->OSTCBStat&OS_STAT_PEND_ANY)!=OS_STAT_RDY) 
							   {
                                 ptcb->OSTCBStat&=~(INT8U)OS_STAT_PEND_ANY;  /* Yes, Clear status flag */
                                 ptcb->OSTCBStatPend = OS_STAT_PEND_TO;      /* Indicate PEND timeout */
                               } 
							else 
							   {
                                 ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
                               }

                            if((ptcb->OSTCBStat&OS_STAT_SUSPEND)==OS_STAT_RDY) /*Is task suspended? */
							   {  
                                  OSRdyGrp|= ptcb->OSTCBBitY;             /* No, Make ready */
                                  OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;
                               }

可见挂起状态下延时函数继续-1.  并根据延时是否到0,挂起是否恢复.判断是否把挂起任务 添加入就绪表. 当挂起恢复延时结束时才加入.

同样在OSTaskResume() 恢复里面也有判断是否延时等待. 两者都满足 才添加到就绪表中.

你可能感兴趣的:(UCOS挂起与延时)