CooCox 1.1.4 on mbed with simple blinky example

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers timer.c Source File

timer.c

Go to the documentation of this file.
00001 /**
00002  *******************************************************************************
00003  * @file       timer.c
00004  * @version    V1.1.4    
00005  * @date       2011.04.20
00006  * @brief      timer management implementation code of CooCox CoOS kernel.  
00007  *******************************************************************************
00008  * @copy
00009  *
00010  * INTERNAL FILE,DON'T PUBLIC.
00011  * 
00012  * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
00013  *******************************************************************************
00014  */ 
00015 
00016 
00017 
00018 /*---------------------------- Include ---------------------------------------*/
00019 #include <coocox.h>
00020 
00021 /*---------------------------- Variable Define -------------------------------*/
00022 #if CFG_TMR_EN > 0
00023 
00024 TmrCtrl    TmrTbl [CFG_MAX_TMR]= {{0}};/*!< Table which save timer control block.*/
00025 P_TmrCtrl  TmrList      = Co_NULL;      /*!< The header of the TmrCtrl list.      */
00026 U32        TmrIDVessel  = 0;         /*!< Timer ID container.                  */
00027 
00028 
00029 /**
00030  *******************************************************************************
00031  * @brief      Insert a timer into the timer list      
00032  * @param[in]  tmrID    Specify timer ID which insertted.        
00033  * @param[out] None  
00034  * @retval     E_INVALID_ID  Timer ID passed was invalid,insert fail.
00035  * @retval     E_OK          Insert successful.          
00036  *
00037  * @par Description
00038  * @details    This function is called to insert a timer into the timer list.  
00039  *******************************************************************************
00040  */
00041 static void InsertTmrList(OS_TCID tmrID )
00042 {
00043     P_TmrCtrl pTmr;
00044     S32 deltaTicks;
00045     U32 tmrCnt ;
00046     tmrCnt = TmrTbl[tmrID ].tmrCnt ;      /* Get timer time                     */
00047     
00048     if(tmrCnt == 0)                     /* Is timer time==0?                  */
00049     {
00050         return;                         /* Do nothing,return                  */
00051     }
00052     
00053     OsSchedLock();                      /* Lock schedule                      */
00054     if(TmrList == Co_NULL)                 /* Is no item in timer list?          */
00055     {
00056         TmrList = &TmrTbl[tmrID ];       /* Yes,set this as first item         */
00057     }
00058     else                  /* No,find correct place ,and insert inserted timer */
00059     {                                   
00060         pTmr       = TmrList ; 
00061         deltaTicks = tmrCnt ;            /* Get timer tick                     */
00062         
00063         /* find correct place */
00064         while(pTmr != Co_NULL)
00065         {                   
00066             deltaTicks -= pTmr->tmrCnt ; /* Get ticks with previous item       */
00067             if(deltaTicks < 0)          /* Is delta ticks<0?                  */  
00068             {   
00069                 /* Yes,get correct place */
00070                 if(pTmr->tmrPrev != Co_NULL)/* Is head item of timer list?        */
00071                 {   
00072                     /* No,insert into */
00073                     pTmr->tmrPrev ->tmrNext  = &TmrTbl[tmrID ]; 
00074                     TmrTbl[tmrID ].tmrPrev   = pTmr->tmrPrev ;
00075                     TmrTbl[tmrID ].tmrNext   = pTmr;
00076                     pTmr->tmrPrev           = &TmrTbl[tmrID ];
00077                 }
00078                 else                    /* Yes,set task as first item         */    
00079                 {
00080                     TmrTbl[tmrID ].tmrNext  = TmrList ;
00081                     TmrList->tmrPrev       = &TmrTbl[tmrID ];
00082                     TmrList               = &TmrTbl[tmrID ];
00083                 }
00084                 TmrTbl[tmrID ].tmrCnt             = TmrTbl[tmrID ].tmrNext ->tmrCnt +deltaTicks;
00085                 TmrTbl[tmrID ].tmrNext ->tmrCnt   -= TmrTbl[tmrID ].tmrCnt ; 
00086                 break;  
00087             }
00088             /* Is last item in list? */                                 
00089             else if((deltaTicks >= 0) && (pTmr->tmrNext  == Co_NULL))
00090             {   
00091                 /* Yes,insert into */
00092                 TmrTbl[tmrID ].tmrPrev  = pTmr;
00093                 pTmr->tmrNext          = &TmrTbl[tmrID ]; 
00094                 TmrTbl[tmrID ].tmrCnt   = deltaTicks;
00095                 break;  
00096             }
00097             pTmr = pTmr->tmrNext ;       /* Get the next item in timer list    */    
00098         }
00099     }
00100     OsSchedUnlock();                    /* Unlock schedule                    */
00101 }
00102 
00103 
00104 /**
00105  *******************************************************************************
00106  * @brief      Remove a timer from the timer list     
00107  * @param[in]  tmrID    Specify ID for a timer which removed form timer list.    
00108  * @param[out] None 
00109  * @retval     None
00110  *
00111  * @par Description
00112  * @details    This function is called to remove a timer from the timer list. 
00113  *******************************************************************************
00114  */
00115 static void RemoveTmrList(OS_TCID tmrID )
00116 {
00117     P_TmrCtrl pTmr;
00118     
00119     pTmr = &TmrTbl[tmrID ];
00120     
00121     OsSchedLock();                      /* Lock schedule                      */
00122     
00123     /* Is there only one item in timer list?                                  */
00124     if((pTmr->tmrPrev  == Co_NULL) && (pTmr->tmrNext  == Co_NULL))
00125     {       
00126         TmrList = Co_NULL;                 /* Yes,set timer list as Co_NULL         */
00127     }
00128     else if(pTmr->tmrPrev  == Co_NULL)      /* Is the first item in timer list?   */
00129     {   /* Yes,remove timer from list,and reset timer list                    */
00130         TmrList  = pTmr->tmrNext ;
00131         TmrList->tmrPrev  = Co_NULL;
00132         pTmr->tmrNext ->tmrCnt  += pTmr->tmrCnt ;
00133         pTmr->tmrNext     = Co_NULL;
00134     }
00135     else if(pTmr->tmrNext  == Co_NULL)      /* Is the last item in timer list?    */
00136     {
00137         /* Yes,remove timer form list */
00138         pTmr->tmrPrev ->tmrNext  = Co_NULL;
00139         pTmr->tmrPrev  = Co_NULL;
00140     }
00141     else                                /* No, remove timer from list         */
00142     {
00143         pTmr->tmrPrev ->tmrNext   =  pTmr->tmrNext ;
00144         pTmr->tmrNext ->tmrPrev   =  pTmr->tmrPrev ;
00145         pTmr->tmrNext ->tmrCnt   += pTmr->tmrCnt ;
00146         pTmr->tmrNext  = Co_NULL;
00147         pTmr->tmrPrev  = Co_NULL;
00148     }
00149     OsSchedUnlock();                    /* Unlock schedule                    */
00150 }
00151 
00152 
00153 /**
00154  *******************************************************************************
00155  * @brief      Create a timer      
00156  * @param[in]  tmrType     Specify timer's type.         
00157  * @param[in]  tmrCnt      Specify timer initial counter value.  
00158  * @param[in]  tmrReload   Specify timer reload value.
00159  * @param[in]  func        Specify timer callback function entry.
00160  * @param[out] None
00161  * @retval     E_CREATE_FAIL   Create timer fail.
00162  * @retval     others          Create timer successful.          
00163  *
00164  * @par Description
00165  * @details    This function is called to create a timer.
00166  *******************************************************************************
00167  */
00168 OS_TCID CoCreateTmr(U8 tmrType , U32 tmrCnt , U32 tmrReload , vFUNCPtr func)
00169 {
00170     U8 i;
00171 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00172     if((tmrType != TMR_TYPE_ONE_SHOT) && (tmrType != TMR_TYPE_PERIODIC))
00173     {
00174         return E_CREATE_FAIL;   
00175     }
00176     if(func == Co_NULL)
00177     {
00178         return E_CREATE_FAIL;
00179     }
00180 #endif
00181     OsSchedLock();                        /* Lock schedule                    */
00182     for(i = 0; i < CFG_MAX_TMR; i++)
00183     {
00184         if((TmrIDVessel  & (1 << i)) == 0) /* Is free timer ID?                */
00185         {
00186             TmrIDVessel  |= (1<<i);        /* Yes,assign ID to this timer      */
00187             OsSchedUnlock();              /* Unlock schedule                  */
00188             TmrTbl[i].tmrID      = i;      /* Initialize timer as user set     */
00189             TmrTbl[i].tmrType    = tmrType ;  
00190             TmrTbl[i].tmrState   = TMR_STATE_STOPPED;
00191             TmrTbl[i].tmrCnt     = tmrCnt ;
00192             TmrTbl[i].tmrReload  = tmrReload ;
00193             TmrTbl[i].tmrCallBack  = func;
00194             TmrTbl[i].tmrPrev    = Co_NULL;
00195             TmrTbl[i].tmrNext    = Co_NULL;
00196             return i;                     /* Return timer ID                  */
00197         }
00198     }
00199     OsSchedUnlock();                      /* Unlock schedule                  */
00200     return E_CREATE_FAIL;                 /* Error return                     */
00201 }
00202 
00203 
00204 /**
00205  *******************************************************************************
00206  * @brief      Start counter     
00207  * @param[in]  tmrID    Specify a timer which startted.      
00208  * @param[out] None 
00209  * @retval     E_INVALID_ID  The timer id passed was invalid,can't start timer  
00210  * @retval     E_OK          Insert a timer to timer list and start it successful. 
00211  *
00212  * @par Description
00213  * @details    This function is called to make a timer start countering. 
00214  *******************************************************************************
00215  */
00216 StatusType CoStartTmr(OS_TCID tmrID )
00217 {
00218 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00219     if(tmrID >= CFG_MAX_TMR)
00220     {
00221         return E_INVALID_ID;
00222     }
00223     if( (TmrIDVessel  & (1<<tmrID)) == 0)
00224     {
00225         return E_INVALID_ID;
00226     }
00227 #endif
00228     
00229     if(TmrTbl[tmrID].tmrState  == TMR_STATE_RUNNING)   /* Is timer running?    */
00230     {
00231         return E_OK;                              /* Yes,do nothing,return OK */
00232     }
00233     
00234     /* No,set timer status as TMR_STATE_RUNNING */
00235     TmrTbl[tmrID ].tmrState  = TMR_STATE_RUNNING; 
00236     InsertTmrList(tmrID);               /* Insert this timer into timer list  */
00237     return E_OK;                        /* Return OK                          */
00238 }
00239 
00240 
00241 
00242 /**
00243  *******************************************************************************
00244  * @brief      Stop countering for a spcify timer     
00245  * @param[in]  tmrID    Specify a timer which stopped.   
00246  * @param[out] None      
00247  * @retval     E_INVALID_ID  The timer id passed was invalid, stop failure.
00248  * @retval     E_OK          Stop a timer countering successful.
00249  *
00250  * @par Description
00251  * @details    This function is called to stop a timer from counting. 
00252  *******************************************************************************
00253  */
00254 StatusType CoStopTmr(OS_TCID tmrID )
00255 {   
00256 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00257     if(tmrID >= CFG_MAX_TMR)
00258     {
00259         return E_INVALID_ID;
00260     }
00261     if((TmrIDVessel  & (1<<tmrID)) == 0)
00262     {
00263         return E_INVALID_ID;
00264     }
00265 #endif
00266     
00267     
00268     if(TmrTbl[tmrID].tmrState  == TMR_STATE_STOPPED)/* Does timer stop running?*/
00269     {
00270         return E_OK;                    /* Yes,do nothing,return OK           */
00271     }
00272     RemoveTmrList(tmrID);             /* No,remove this timer from timer list */
00273     
00274     /* Set timer status as TMR_STATE_STOPPED  */
00275     TmrTbl[tmrID ].tmrState  = TMR_STATE_STOPPED; 
00276     return E_OK;                        /* Return OK                          */
00277 }
00278 
00279 
00280 /**
00281  *******************************************************************************
00282  * @brief      Delete a timer    
00283  * @param[in]  tmrID     Specify a timer which deleted.      
00284  * @param[out] None   
00285  * @retval     E_INVALID_ID  The timer id passed was invalid,deleted failure.   
00286  * @retval     E_OK          Delete a timer successful.
00287  *
00288  * @par Description
00289  * @details    This function is called to delete a timer which created before.  
00290  *******************************************************************************
00291  */
00292 StatusType CoDelTmr(OS_TCID tmrID )
00293 {
00294 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00295     if(tmrID >= CFG_MAX_TMR)
00296     {
00297         return E_INVALID_ID;
00298     }
00299     if( (TmrIDVessel  & (1<<tmrID)) == 0)
00300     {
00301         return E_INVALID_ID;
00302     }
00303 #endif
00304     
00305     if(TmrTbl[tmrID].tmrState  == TMR_STATE_RUNNING) /* Is timer running?      */
00306     {
00307         RemoveTmrList(tmrID);         /* Yes,remove this timer from timer list*/
00308     }
00309     TmrIDVessel  &=~(1<<tmrID );        /* Release resource that this timer hold*/
00310     return E_OK;                      /* Return OK                            */
00311 }
00312 
00313  
00314 /**
00315  *******************************************************************************
00316  * @brief      Get current counter of specify timer  
00317  * @param[in]  tmrID          Specify timer by ID.       
00318  * @param[out] E_INVALID_ID   Invalid ID was passed and get counter failure.      
00319  * @param[out] E_OK           Get current counter successful.    
00320  * @retval     Current counter of a timer which specify by id.           
00321  *
00322  * @par Description
00323  * @details    This function is called to obtain current counter of specify timer.
00324  *******************************************************************************
00325  */
00326 U32 CoGetCurTmrCnt(OS_TCID tmrID ,StatusType* perr)
00327 {
00328 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00329     if(tmrID >= CFG_MAX_TMR)
00330     {
00331         *perr = E_INVALID_ID;
00332         return 0;
00333     }
00334     if((TmrIDVessel  & (1<<tmrID)) == 0)
00335     {
00336         *perr = E_INVALID_ID;
00337         return 0;
00338     }
00339 #endif
00340     *perr = E_OK;
00341     return TmrTbl[tmrID ].tmrCnt ;        /* Return timer counter               */
00342 }
00343 
00344 
00345 /**
00346  *******************************************************************************
00347  * @brief      Setting for a specify timer              
00348  * @param[in]  tmrID       Specify timer by ID.
00349  * @param[in]  tmrCnt      Specify timer counter which need to be set.
00350  * @param[in]  tmrReload   Specify timer reload value which need to be set.      
00351  * @param[out] None  
00352  * @retval     E_INVALID_ID  The ID passed was invalid,set fail.
00353  * @retval     E_OK          Set timer counter successful.               
00354  *
00355  * @par Description
00356  * @details    This function is called to set timer counter and reload value.
00357  *******************************************************************************
00358  */
00359 StatusType CoSetTmrCnt(OS_TCID tmrID ,U32 tmrCnt ,U32 tmrReload )
00360 {
00361 #if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
00362     if(tmrID >= CFG_MAX_TMR)
00363     {
00364         return E_INVALID_ID;
00365     }
00366     if( (TmrIDVessel  & (1<<tmrID)) == 0)
00367     {
00368         return E_INVALID_ID;
00369     }
00370 #endif
00371     TmrTbl[tmrID ].tmrCnt     = tmrCnt ; /* Reset timer counter and reload value */
00372     TmrTbl[tmrID ].tmrReload  = tmrReload ;
00373                                     
00374     if(TmrTbl[tmrID].tmrState  == TMR_STATE_RUNNING)   /* Is timer running?    */
00375     {
00376         RemoveTmrList(tmrID);           /* Yes,reorder timer in timer list    */
00377         InsertTmrList(tmrID);   
00378     }
00379     return E_OK;                        /* Return OK                          */
00380 }
00381 
00382 
00383 /**
00384  *******************************************************************************
00385  * @brief      Timer counter dispose       
00386  * @param[in]  None      
00387  * @param[out] None  
00388  * @retval     None  
00389  *
00390  * @par Description
00391  * @details    This function is called to dispose timer counter.
00392  *******************************************************************************
00393  */
00394 void TmrDispose(void)
00395 {
00396     P_TmrCtrl   pTmr;
00397     
00398     pTmr = TmrList ;                     /* Get first item of timer list       */
00399     while((pTmr != Co_NULL) && (pTmr->tmrCnt  == 0) )
00400     {   
00401         if(pTmr->tmrType  == TMR_TYPE_ONE_SHOT)    /* Is a One-shot timer?     */
00402         {
00403             /* Yes,remove this timer from timer list                          */
00404             RemoveTmrList(pTmr->tmrID );
00405             
00406             /* Set timer status as TMR_STATE_STOPPED                          */
00407             pTmr->tmrState  = TMR_STATE_STOPPED;
00408             (pTmr->tmrCallBack )();          /* Call timer callback function   */
00409         }
00410         else if(pTmr->tmrType  == TMR_TYPE_PERIODIC)   /* Is a periodic timer? */
00411         {
00412             /* Yes,remove this timer from timer list                          */
00413             RemoveTmrList(pTmr->tmrID ); 
00414             pTmr->tmrCnt  = pTmr->tmrReload ;   /* Reset timer tick             */
00415             InsertTmrList(pTmr->tmrID );       /* Insert timer into timer list */
00416             (pTmr->tmrCallBack )();            /* Call timer callback function */
00417         }
00418         pTmr = TmrList ;                       /* Get first item of timer list */
00419     }
00420 }
00421 
00422 
00423 /**
00424  *******************************************************************************
00425  * @brief      Timer counter dispose in ISR    
00426  * @param[in]  None      
00427  * @param[out] None  
00428  * @retval     None  
00429  *
00430  * @par Description
00431  * @details    This function is called to dispose timer counter.
00432  *******************************************************************************
00433  */
00434 void isr_TmrDispose(void)
00435 {
00436     if(OSSchedLock  > 1)                 /* Is schedule lock?                  */
00437     {
00438         IsrReq = Co_TRUE;
00439         TimerReq   = Co_TRUE;               /* Yes,set timer request true         */
00440     }
00441     else
00442     {
00443         TmrDispose();                   /* No,call handler                    */
00444     }
00445 }    
00446 
00447 #endif