INT8U OSTmrNameGet( OS_TMR * ptmr, INT8U * pdest, INT8U * perr ) { INT8U len; #if OS_ARG_CHK_EN > 0 if ( perr == ( INT8U * ) 0 ) { return ( 0 ); } if ( pdest == ( INT8U * ) 0 ) { *perr = OS_ERR_TMR_INVALID_DEST; return ( 0 ); } if ( ptmr == ( OS_TMR * ) 0 ) { *perr = OS_ERR_TMR_INVALID; return ( 0 ); } #endif if ( ptmr->OSTmrType != OS_TMR_TYPE ) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return ( 0 ); } if ( OSIntNesting > 0 ) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return ( 0 ); } OSTmr_Lock( ); switch ( ptmr->OSTmrState ) { case OS_TMR_STATE_RUNNING: case OS_TMR_STATE_STOPPED: case OS_TMR_STATE_COMPLETED: len = OS_StrCopy( pdest, ptmr->OSTmrName ); OSTmr_Unlock( ); *perr = OS_NO_ERR; return ( len ); case OS_TMR_STATE_UNUSED: /* Timer is not allocated */ OSTmr_Unlock( ); *perr = OS_ERR_TMR_INACTIVE; return ( 0 ); default: OSTmr_Unlock( ); *perr = OS_ERR_TMR_INVALID_STATE; return ( 0 ); } }
BOOLEAN OSTmrStart( OS_TMR * ptmr, INT8U * perr ) { #if OS_ARG_CHK_EN > 0 if ( perr == ( INT8U * ) 0 ) { /* Validate arguments */ return ( OS_FALSE ); } if ( ptmr == ( OS_TMR * ) 0 ) { *perr = OS_ERR_TMR_INVALID; return ( OS_FALSE ); } #endif if ( ptmr->OSTmrType != OS_TMR_TYPE ) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return ( OS_FALSE ); } if ( OSIntNesting > 0 ) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return ( OS_FALSE ); } OSTmr_Lock( ); switch ( ptmr->OSTmrState ) { case OS_TMR_STATE_RUNNING: /* Restart the timer */ OSTmr_Unlink( ptmr ); /* ... Stop the timer */ OSTmr_Link( ptmr, OS_TMR_LINK_DLY ); /* ... Link timer to timer wheel */ OSTmr_Unlock( ); *perr = OS_NO_ERR; return ( OS_TRUE ); case OS_TMR_STATE_STOPPED: /* Start the timer */ case OS_TMR_STATE_COMPLETED: OSTmr_Link( ptmr, OS_TMR_LINK_DLY ); /* ... Link timer to timer wheel */ OSTmr_Unlock( ); *perr = OS_NO_ERR; return ( OS_TRUE ); case OS_TMR_STATE_UNUSED: /* Timer not created */ OSTmr_Unlock( ); *perr = OS_ERR_TMR_INACTIVE; return ( OS_FALSE ); default: OSTmr_Unlock( ); *perr = OS_ERR_TMR_INVALID_STATE; return ( OS_FALSE ); } }
BOOLEAN OSTmrDel( OS_TMR * ptmr, INT8U * perr ) { #if OS_ARG_CHK_EN > 0 if ( perr == ( INT8U * ) 0 ) { /* Validate arguments */ return ( OS_FALSE ); } if ( ptmr == ( OS_TMR * ) 0 ) { *perr = OS_ERR_TMR_INVALID; return ( OS_FALSE ); } #endif if ( ptmr->OSTmrType != OS_TMR_TYPE ) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return ( OS_FALSE ); } if ( OSIntNesting > 0 ) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return ( OS_FALSE ); } OSTmr_Lock( ); switch ( ptmr->OSTmrState ) { case OS_TMR_STATE_RUNNING: OSTmr_Unlink( ptmr ); /* Remove from current wheel spoke */ OSTmr_Free( ptmr ); /* Return timer to free list of timers */ OSTmr_Unlock( ); *perr = OS_NO_ERR; return ( OS_TRUE ); case OS_TMR_STATE_STOPPED: /* Timer has not started or ... */ case OS_TMR_STATE_COMPLETED: /* ... timer has completed the ONE-SHOT time */ OSTmr_Free( ptmr ); /* Return timer to free list of timers */ OSTmr_Unlock( ); *perr = OS_NO_ERR; return ( OS_TRUE ); case OS_TMR_STATE_UNUSED: /* Already deleted */ OSTmr_Unlock( ); *perr = OS_ERR_TMR_INACTIVE; return ( OS_FALSE ); default: OSTmr_Unlock( ); *perr = OS_ERR_TMR_INVALID_STATE; return ( OS_FALSE ); } }
static void OSTmr_Task( void *p_arg ) { INT8U err; OS_TMR *ptmr; OS_TMR *ptmr_next; OS_TMR_CALLBACK pfnct; OS_TMR_WHEEL *pspoke; INT16U spoke; ( void ) p_arg; /* Not using 'p_arg', prevent compiler warning */ for ( ;; ) { OSSemPend( OSTmrSemSignal, 0, &err ); /* Wait for signal indicating time to update timers */ OSTmr_Lock( ); OSTmrTime++; /* Increment the current time */ spoke = OSTmrTime % OS_TMR_CFG_WHEEL_SIZE; /* Position on current timer wheel entry */ pspoke = &OSTmrWheelTbl[spoke]; ptmr = pspoke->OSTmrFirst; while ( ptmr != ( OS_TMR * ) 0 ) { ptmr_next = ptmr->OSTmrNext; /* Point to next timer to update because current ... */ /* ... timer could get unlinked from the wheel. */ if ( OSTmrTime == ptmr->OSTmrMatch ) { /* Process each timer that expires */ pfnct = ptmr->OSTmrCallback; /* Execute callback function if available */ if ( pfnct != ( OS_TMR_CALLBACK ) 0 ) { ( *pfnct ) ( ptmr, ptmr->OSTmrCallbackArg ); } OSTmr_Unlink( ptmr ); /* Remove from current wheel spoke */ if ( ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC ) { OSTmr_Link( ptmr, OS_TMR_LINK_PERIODIC ); /* Recalculate new position of timer in wheel */ } else { ptmr->OSTmrState = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */ } } ptmr = ptmr_next; } OSTmr_Unlock( ); } }
INT8U OSTmrStateGet( OS_TMR * ptmr, INT8U * perr ) { INT8U state; #if OS_ARG_CHK_EN > 0 if ( perr == ( INT8U * ) 0 ) { return ( 0 ); } if ( ptmr == ( OS_TMR * ) 0 ) { *perr = OS_ERR_TMR_INVALID; return ( 0 ); } #endif if ( ptmr->OSTmrType != OS_TMR_TYPE ) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return ( 0 ); } if ( OSIntNesting > 0 ) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return ( 0 ); } OSTmr_Lock( ); state = ptmr->OSTmrState; switch ( state ) { case OS_TMR_STATE_UNUSED: case OS_TMR_STATE_STOPPED: case OS_TMR_STATE_COMPLETED: case OS_TMR_STATE_RUNNING: *perr = OS_NO_ERR; break; default: *perr = OS_ERR_TMR_INVALID_STATE; break; } OSTmr_Unlock( ); return ( state ); }
BOOLEAN OSTmrStop (OS_TMR *ptmr, INT8U opt, void *callback_arg, INT8U *perr) { OS_TMR_CALLBACK pfnct; #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate arguments */ return (OS_FALSE); } if (ptmr == (OS_TMR *)0) { *perr = OS_ERR_TMR_INVALID; return (OS_FALSE); } #endif if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return (OS_FALSE); } if (OSIntNesting > 0) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } OSTmr_Lock(); switch (ptmr->OSTmrState) { case OS_TMR_STATE_RUNNING: OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ *perr = OS_ERR_NONE; switch (opt) { case OS_TMR_OPT_CALLBACK: pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ if (pfnct != (OS_TMR_CALLBACK)0) { (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); /* Use callback arg when timer was created */ } else { *perr = OS_ERR_TMR_NO_CALLBACK; } break; case OS_TMR_OPT_CALLBACK_ARG: pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ if (pfnct != (OS_TMR_CALLBACK)0) { (*pfnct)((void *)ptmr, callback_arg); /* ... using the 'callback_arg' provided in call */ } else { *perr = OS_ERR_TMR_NO_CALLBACK; } break; case OS_TMR_OPT_NONE: break; default: *perr = OS_ERR_TMR_INVALID_OPT; break; } OSTmr_Unlock(); return (OS_TRUE); case OS_TMR_STATE_COMPLETED: /* Timer has already completed the ONE-SHOT or ... */ case OS_TMR_STATE_STOPPED: /* ... timer has not started yet. */ OSTmr_Unlock(); *perr = OS_ERR_TMR_STOPPED; return (OS_TRUE); case OS_TMR_STATE_UNUSED: /* Timer was not created */ OSTmr_Unlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSTmr_Unlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (OS_FALSE); } }
INT32U OSTmrRemainGet (OS_TMR *ptmr, INT8U *perr) { INT32U remain; #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { return (0); } if (ptmr == (OS_TMR *)0) { *perr = OS_ERR_TMR_INVALID; return (0); } #endif if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return (0); } if (OSIntNesting > 0) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (0); } OSTmr_Lock(); switch (ptmr->OSTmrState) { case OS_TMR_STATE_RUNNING: remain = ptmr->OSTmrMatch - OSTmrTime; /* Determine how much time is left to timeout */ OSTmr_Unlock(); *perr = OS_ERR_NONE; return (remain); case OS_TMR_STATE_STOPPED: /* It's assumed that the timer has not started yet */ switch (ptmr->OSTmrOpt) { case OS_TMR_OPT_PERIODIC: if (ptmr->OSTmrDly == 0) { remain = ptmr->OSTmrPeriod; } else { remain = ptmr->OSTmrDly; } OSTmr_Unlock(); *perr = OS_ERR_NONE; break; case OS_TMR_OPT_ONE_SHOT: default: remain = ptmr->OSTmrDly; OSTmr_Unlock(); *perr = OS_ERR_NONE; break; } return (remain); case OS_TMR_STATE_COMPLETED: /* Only ONE-SHOT that timed out can be in this state */ OSTmr_Unlock(); *perr = OS_ERR_NONE; return (0); case OS_TMR_STATE_UNUSED: OSTmr_Unlock(); *perr = OS_ERR_TMR_INACTIVE; return (0); default: OSTmr_Unlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (0); } }
OS_TMR *OSTmrCreate (INT32U dly, INT32U period, INT8U opt, OS_TMR_CALLBACK callback, void *callback_arg, INT8U *pname, INT8U *perr) { OS_TMR *ptmr; #if OS_TMR_CFG_NAME_SIZE > 0 INT8U len; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate arguments */ return ((OS_TMR *)0); } switch (opt) { case OS_TMR_OPT_PERIODIC: if (period == 0) { *perr = OS_ERR_TMR_INVALID_PERIOD; return ((OS_TMR *)0); } break; case OS_TMR_OPT_ONE_SHOT: if (dly == 0) { *perr = OS_ERR_TMR_INVALID_DLY; return ((OS_TMR *)0); } break; default: *perr = OS_ERR_TMR_INVALID_OPT; return ((OS_TMR *)0); } #endif if (OSIntNesting > 0) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return ((OS_TMR *)0); } OSTmr_Lock(); ptmr = OSTmr_Alloc(); /* Obtain a timer from the free pool */ if (ptmr == (OS_TMR *)0) { OSTmr_Unlock(); *perr = OS_ERR_TMR_NON_AVAIL; return ((OS_TMR *)0); } ptmr->OSTmrState = OS_TMR_STATE_STOPPED; /* Indicate that timer is not running yet */ ptmr->OSTmrDly = dly; ptmr->OSTmrPeriod = period; ptmr->OSTmrOpt = opt; ptmr->OSTmrCallback = callback; ptmr->OSTmrCallbackArg = callback_arg; #if OS_TMR_CFG_NAME_SIZE > 0 if (pname !=(INT8U *)0) { len = OS_StrLen(pname); /* Copy timer name */ if (len < OS_TMR_CFG_NAME_SIZE) { (void)OS_StrCopy(ptmr->OSTmrName, pname); } else { #if OS_TMR_CFG_NAME_SIZE > 1 ptmr->OSTmrName[0] = '#'; /* Invalid size specified */ ptmr->OSTmrName[1] = OS_ASCII_NUL; #endif *perr = OS_ERR_TMR_NAME_TOO_LONG; OSTmr_Unlock(); return (ptmr); } } #endif OSTmr_Unlock(); *perr = OS_ERR_NONE; return (ptmr); }