CoOS Demonstrator adapted to mbed Hardware.

Dependencies:   mbed

Revision:
0:57690853989a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/time.c	Fri Dec 03 19:45:30 2010 +0000
@@ -0,0 +1,376 @@
+/**
+ *******************************************************************************
+ * @file       time.c
+ * @version    V1.1.3    
+ * @date       2010.04.26
+ * @brief      time management implementation code of CooCox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; 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 = 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 0         */
+    }
+    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 == 0)
+    {
+        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 0?         */
+        {
+            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 = TRUE;
+        TimeReq = TRUE;                 /* Yes,set time request true          */
+    }
+    else
+    {
+        TimeDispose();                  /* No,call handler                    */
+    }
+}
+
+
+#endif