#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() 恢复里面也有判断是否延时等待. 两者都满足 才添加到就绪表中.