![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Quick and dirty CoOS + LWIP ( Webserver )
Diff: CoOS/kernel/time.c
- Revision:
- 0:94897d537b31
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CoOS/kernel/time.c Sat Sep 10 22:41:10 2011 +0000 @@ -0,0 +1,376 @@ +/** + ******************************************************************************* + * @file time.c + * @version V1.1.4 + * @date 2011.04.20 + * @brief time management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * INTERNAL FILE,DON'T PUBLIC. + * + * <h2><center>© COPYRIGHT 2009 CooCox </center></h2> + ******************************************************************************* + */ + + + +/*---------------------------- Include ---------------------------------------*/ +#include <coocox.h> + +#if CFG_TASK_WAITTING_EN > 0 + +/*---------------------------- Variable Define -------------------------------*/ +P_OSTCB DlyList = 0; /*!< Header pointer to the DELAY list.*/ + + +/** + ******************************************************************************* + * @brief Insert into DELAY list + * + * @param[in] ptcb Task that want to insert into DELAY list. + * @param[in] ticks Delay system ticks. + * @param[out] None + * @retval None. + * + * @par Description + * @details This function is called to insert task into DELAY list. + ******************************************************************************* + */ +void InsertDelayList(P_OSTCB ptcb,U32 ticks) +{ + S32 deltaTicks; + P_OSTCB dlyNext; + + if(ticks == 0) /* Is delay tick == 0? */ + return; /* Yes,do nothing,return */ + if(DlyList == 0) /* Is no item in DELAY list? */ + { + ptcb->delayTick = ticks; /* Yes,set this as first item */ + DlyList = ptcb; + } + else + { + /* No,find correct place ,and insert the task */ + dlyNext = DlyList; + deltaTicks = ticks; /* Get task delay ticks */ + + /* Find correct place */ + while(dlyNext != 0) + { + /* Get delta ticks with previous item */ + deltaTicks -= dlyNext->delayTick; + if(deltaTicks < 0) /* Is delta ticks<0? */ + { + /* Yes,get correct place */ + if(dlyNext->TCBprev != 0) /* Is head item of DELAY list? */ + { + dlyNext->TCBprev->TCBnext = ptcb; /* No,insert into */ + ptcb->TCBprev = dlyNext->TCBprev; + ptcb->TCBnext = dlyNext; + dlyNext->TCBprev = ptcb; + } + else /* Yes,set task as first item */ + { + ptcb->TCBnext = DlyList; + DlyList->TCBprev = ptcb; + DlyList = ptcb; + } + ptcb->delayTick = ptcb->TCBnext->delayTick+deltaTicks; + ptcb->TCBnext->delayTick -= ptcb->delayTick; + break; + } + /* Is last item in DELAY list? */ + else if((deltaTicks >= 0) && (dlyNext->TCBnext == 0) ) + { + ptcb->TCBprev = dlyNext; /* Yes,insert into */ + dlyNext->TCBnext = ptcb; + ptcb->delayTick = deltaTicks; + break; + } + dlyNext = dlyNext->TCBnext; /* Get the next item in DELAY list */ + } + } + + ptcb->state = TASK_WAITING; /* Set task status as TASK_WAITING */ + TaskSchedReq = Co_TRUE; +} + + +/** + ******************************************************************************* + * @brief Remove from the DELAY list + * @param[in] ptcb Task that want to remove from the DELAY list. + * @param[out] None + * @retval None + * + * @par Description + * @details This function is called to remove task from the DELAY list. + ******************************************************************************* + */ +void RemoveDelayList(P_OSTCB ptcb) +{ + + /* Is there only one item in the DELAY list? */ + if((ptcb->TCBprev == 0) && ( ptcb->TCBnext == 0)) + { + DlyList = 0; /* Yes,set DELAY list as Co_NULL */ + } + else if(ptcb->TCBprev == 0) /* Is the first item in DELAY list? */ + { + /* Yes,remove task from the DELAY list,and reset the list */ + DlyList = ptcb->TCBnext; + ptcb->TCBnext->delayTick += ptcb->delayTick; + ptcb->TCBnext->TCBprev = 0; + ptcb->TCBnext = 0; + + } + else if(ptcb->TCBnext == 0) /* Is the last item in DELAY list? */ + { + ptcb->TCBprev->TCBnext = 0; /* Yes,remove task form DELAY list */ + ptcb->TCBprev = 0; + } + else /* No, remove task from DELAY list */ + { + ptcb->TCBprev->TCBnext = ptcb->TCBnext; + ptcb->TCBnext->TCBprev = ptcb->TCBprev; + ptcb->TCBnext->delayTick += ptcb->delayTick; + ptcb->TCBnext = 0; + ptcb->TCBprev = 0; + } + ptcb->delayTick = INVALID_VALUE; /* Set task delay tick value as invalid */ +} + +/** + ******************************************************************************* + * @brief Get current ticks + * @param[in] None + * @param[out] None + * @retval Return current system tick counter. + * + * @par Description + * @details This function is called to obtain current system tick counter. + ******************************************************************************* + */ +U64 CoGetOSTime(void) +{ + return OSTickCnt; /* Get system time(tick) */ +} + + +/** + ******************************************************************************* + * @brief Delay current task for specify ticks number + * @param[in] ticks Specify system tick number which will delay. + * @param[out] None + * @retval E_CALL Error call in ISR. + * @retval E_OK The current task was insert to DELAY list successful,it + * will delay specify time. + * @par Description + * @details This function delay specify ticks for current task. + * + * @note This function be called in ISR,do nothing and return immediately. + ******************************************************************************* + */ +StatusType CoTickDelay(U32 ticks) +{ + if(OSIntNesting >0) /* Is call in ISR? */ + { + return E_CALL; /* Yes,error return */ + } + + if(ticks == INVALID_VALUE) /* Is tick==INVALID_VALUE? */ + { + return E_INVALID_PARAMETER; /* Yes,error return */ + } + if(ticks == 0) /* Is tick==0? */ + { + return E_OK; /* Yes,do nothing ,return OK */ + } + if(OSSchedLock != 0) /* Is OS lock? */ + { + return E_OS_IN_LOCK; /* Yes,error return */ + } + OsSchedLock(); /* Lock schedule */ + InsertDelayList(TCBRunning,ticks); /* Insert task in DELAY list */ + OsSchedUnlock(); /* Unlock schedule,and call task schedule */ + return E_OK; /* Return OK */ +} + + +/** + ******************************************************************************* + * @brief Reset task delay ticks + * @param[in] ptcb Task that want to insert into DELAY list. + * @param[in] ticks Specify system tick number which will delay . + * @param[out] None + * @retval E_CALL Error call in ISR. + * @retval E_INVALID_ID Invalid task id. + * @retval E_NOT_IN_DELAY_LIST Task not in delay list. + * @retval E_OK The current task was inserted to DELAY list + * successful,it will delay for specify time. + * @par Description + * @details This function delay specify ticks for current task. + ******************************************************************************* + */ +StatusType CoResetTaskDelayTick(OS_TID taskID,U32 ticks) +{ + P_OSTCB ptcb; + + +#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ + if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM) + { + return E_INVALID_ID; + } +#endif + + ptcb = &TCBTbl[taskID]; +#if CFG_PAR_CHECKOUT_EN >0 + if(ptcb->stkPtr == Co_NULL) + { + return E_INVALID_ID; + } +#endif + + if(ptcb->delayTick == INVALID_VALUE) /* Is tick==INVALID_VALUE? */ + { + return E_NOT_IN_DELAY_LIST; /* Yes,error return */ + } + OsSchedLock(); /* Lock schedule */ + RemoveDelayList(ptcb); /* Remove task from the DELAY list */ + + if(ticks == 0) /* Is delay tick==0? */ + { + InsertToTCBRdyList(ptcb); /* Insert task into the DELAY list */ + } + else + { + InsertDelayList(ptcb,ticks); /* No,insert task into DELAY list */ + } + OsSchedUnlock(); /* Unlock schedule,and call task schedule */ + return E_OK; /* Return OK */ +} + + +/** + ******************************************************************************* + * @brief Delay current task for detail time + * @param[in] hour Specify the number of hours. + * @param[in] minute Specify the number of minutes. + * @param[in] sec Specify the number of seconds. + * @param[in] millsec Specify the number of millseconds. + * @param[out] None + * @retval E_CALL Error call in ISR. + * @retval E_INVALID_PARAMETER Parameter passed was invalid,delay fail. + * @retval E_OK The current task was inserted to DELAY list + * successful,it will delay for specify time. + * @par Description + * @details This function delay specify time for current task. + * + * @note If this function called in ISR,do nothing and return immediately. + ******************************************************************************* + */ +#if CFG_TIME_DELAY_EN >0 +StatusType CoTimeDelay(U8 hour,U8 minute,U8 sec,U16 millsec) +{ + U32 ticks; +#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ + if(OSIntNesting > 0) + { + return E_CALL; + } + if((minute > 59)||(sec > 59)||(millsec > 999)) + return E_INVALID_PARAMETER; +#endif + if(OSSchedLock != 0) /* Is OS lock? */ + { + return E_OS_IN_LOCK; /* Yes,error return */ + } + + /* Get tick counter from time */ + ticks = ((hour*3600) + (minute*60) + (sec)) * (CFG_SYSTICK_FREQ)\ + + (millsec*CFG_SYSTICK_FREQ + 500)/1000; + + CoTickDelay(ticks); /* Call tick delay */ + return E_OK; /* Return OK */ +} +#endif + + + + +/** + ******************************************************************************* + * @brief Dispose time delay + * @param[in] None + * @param[out] None + * @retval None + * + * @par Description + * @details This function is called to dispose time delay of all task. + ******************************************************************************* + */ +void TimeDispose(void) +{ + P_OSTCB dlyList; + + dlyList = DlyList; /* Get first item of DELAY list */ + while((dlyList != 0) && (dlyList->delayTick == 0) ) + { + +#if CFG_EVENT_EN > 0 + if(dlyList->eventID != INVALID_ID) /* Is task in event waiting list? */ + { + RemoveEventWaittingList(dlyList); /* Yes,remove task from list */ + } +#endif + +#if CFG_FLAG_EN > 0 + if(dlyList->pnode != 0) /* Is task in flag waiting list? */ + { + RemoveLinkNode((P_FLAG_NODE)dlyList->pnode); /* Yes,remove task from list */ + } +#endif + dlyList->delayTick = INVALID_VALUE; /* Set delay tick value as invalid*/ + DlyList = dlyList->TCBnext; /* Get next item as the head of DELAY list*/ + dlyList->TCBnext = 0; + + InsertToTCBRdyList(dlyList); /* Insert task into READY list */ + + dlyList = DlyList; /* Get the first item of DELAY list */ + if(dlyList != 0) /* Is DELAY list as Co_NULL? */ + { + dlyList->TCBprev = 0; /* No,initialize the first item */ + } + } +} + + +/** + ******************************************************************************* + * @brief Dispose time delay in ISR + * @param[in] None + * @param[out] None + * @retval None + * + * @par Description + * @details This function is called in systick interrupt to dispose time delay + * of all task. + ******************************************************************************* + */ +void isr_TimeDispose(void) +{ + if(OSSchedLock > 1) /* Is schedule lock? */ + { + IsrReq = Co_TRUE; + TimeReq = Co_TRUE; /* Yes,set time request Co_TRUE */ + } + else + { + TimeDispose(); /* No,call handler */ + } +} + + +#endif