void OS_TmrTask (void *p_arg) { OS_ERR err; OS_TMR_CALLBACK_PTR p_fnct; OS_TMR *p_tmr; OS_TMR *p_tmr_next; CPU_TS ts; CPU_TS ts_start; CPU_TS ts_delta; (void)&p_arg; /* Not using 'p_arg', prevent compiler warning */ while (DEF_ON) { (void)OSTaskSemPend((OS_TICK )0, /* Wait for signal indicating time to update tmrs */ (OS_OPT )OS_OPT_PEND_BLOCKING, (CPU_TS *)&ts, (OS_ERR *)&err); OS_TmrLock(); ts_start = OS_TS_GET(); OSTmrTickCtr++; /* Increment the current time */ p_tmr = OSTmrListPtr; while (p_tmr != (OS_TMR *)0) { /* Update all the timers in the list */ OSSchedLock(&err); (void)&err; p_tmr_next = p_tmr->NextPtr; p_tmr->Remain--; if (p_tmr->Remain == 0) { if (p_tmr->Opt == OS_OPT_TMR_PERIODIC) { p_tmr->Remain = p_tmr->Period; /* Reload the time remaining */ } else { OS_TmrUnlink(p_tmr); /* Remove from list */ p_tmr->State = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */ } p_fnct = p_tmr->CallbackPtr; /* Execute callback function if available */ if (p_fnct != (OS_TMR_CALLBACK_PTR)0) { (*p_fnct)((void *)p_tmr, p_tmr->CallbackPtrArg); } } p_tmr = p_tmr_next; OSSchedUnlock(&err); (void)&err; } ts_delta = OS_TS_GET() - ts_start; /* Measure execution time of timer task */ if (OSTmrTaskTimeMax < ts_delta) { OSTmrTaskTimeMax = ts_delta; } OS_TmrUnlock(); } }
CPU_BOOLEAN OSTmrStop (OS_TMR *p_tmr, OS_OPT opt, void *p_callback_arg, OS_ERR *p_err) { OS_TMR_CALLBACK_PTR p_fnct; OS_ERR err; #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (DEF_FALSE); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to call from an ISR */ *p_err = OS_ERR_TMR_ISR; return (DEF_FALSE); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_tmr == (OS_TMR *)0) { *p_err = OS_ERR_TMR_INVALID; return (DEF_FALSE); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_tmr->Type != OS_OBJ_TYPE_TMR) { /* Make sure timer was created */ *p_err = OS_ERR_OBJ_TYPE; return (DEF_FALSE); } #endif OSSchedLock(&err); switch (p_tmr->State) { case OS_TMR_STATE_RUNNING: OS_TmrUnlink(p_tmr); /* Remove from current wheel spoke */ *p_err = OS_ERR_NONE; switch (opt) { case OS_OPT_TMR_CALLBACK: p_fnct = p_tmr->CallbackPtr; /* Execute callback function ... */ if (p_fnct != (OS_TMR_CALLBACK_PTR)0) { /* ... if available */ (*p_fnct)((void *)p_tmr, p_tmr->CallbackPtrArg); /* Use callback arg when timer was created */ } else { *p_err = OS_ERR_TMR_NO_CALLBACK; } break; case OS_OPT_TMR_CALLBACK_ARG: p_fnct = p_tmr->CallbackPtr; /* Execute callback function if available ... */ if (p_fnct != (OS_TMR_CALLBACK_PTR)0) { (*p_fnct)((void *)p_tmr, p_callback_arg); /* .. using the 'callback_arg' provided in call */ } else { *p_err = OS_ERR_TMR_NO_CALLBACK; } break; case OS_OPT_TMR_NONE: break; default: OSSchedUnlock(&err); *p_err = OS_ERR_OPT_INVALID; return (DEF_FALSE); } OSSchedUnlock(&err); return (DEF_TRUE); case OS_TMR_STATE_COMPLETED: /* Timer has already completed the ONE-SHOT or */ case OS_TMR_STATE_STOPPED: /* ... timer has not started yet. */ OSSchedUnlock(&err); *p_err = OS_ERR_TMR_STOPPED; return (DEF_TRUE); case OS_TMR_STATE_UNUSED: /* Timer was not created */ OSSchedUnlock(&err); *p_err = OS_ERR_TMR_INACTIVE; return (DEF_FALSE); default: OSSchedUnlock(&err); *p_err = OS_ERR_TMR_INVALID_STATE; return (DEF_FALSE); } }
CPU_BOOLEAN OSTmrStart (OS_TMR *p_tmr, OS_ERR *p_err) { OS_ERR err; #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (DEF_FALSE); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to call from an ISR */ *p_err = OS_ERR_TMR_ISR; return (DEF_FALSE); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_tmr == (OS_TMR *)0) { *p_err = OS_ERR_TMR_INVALID; return (DEF_FALSE); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_tmr->Type != OS_OBJ_TYPE_TMR) { /* Make sure timer was created */ *p_err = OS_ERR_OBJ_TYPE; return (DEF_FALSE); } #endif OSSchedLock(&err); switch (p_tmr->State) { case OS_TMR_STATE_RUNNING: /* Restart the timer */ OS_TmrUnlink(p_tmr); /* ... Stop the timer */ OS_TmrLink(p_tmr, OS_OPT_LINK_DLY); /* ... Link timer to timer wheel (see Note #1). */ OSSchedUnlock(&err); *p_err = OS_ERR_NONE; return (DEF_TRUE); case OS_TMR_STATE_STOPPED: /* Start the timer */ case OS_TMR_STATE_COMPLETED: OS_TmrLink(p_tmr, OS_OPT_LINK_DLY); /* ... Link timer to timer wheel (see Note #1). */ OSSchedUnlock(&err); *p_err = OS_ERR_NONE; return (DEF_TRUE); case OS_TMR_STATE_UNUSED: /* Timer not created */ OSSchedUnlock(&err); *p_err = OS_ERR_TMR_INACTIVE; return (DEF_FALSE); default: OSSchedUnlock(&err); *p_err = OS_ERR_TMR_INVALID_STATE; return (DEF_FALSE); } }
CPU_BOOLEAN OSTmrDel (OS_TMR *p_tmr, OS_ERR *p_err) { OS_ERR err; #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (DEF_FALSE); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to call from an ISR */ *p_err = OS_ERR_TMR_ISR; return (DEF_FALSE); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_tmr == (OS_TMR *)0) { *p_err = OS_ERR_TMR_INVALID; return (DEF_FALSE); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_tmr->Type != OS_OBJ_TYPE_TMR) { /* Make sure timer was created */ *p_err = OS_ERR_OBJ_TYPE; return (DEF_FALSE); } #endif OSSchedLock(&err); #if OS_CFG_DBG_EN > 0u OS_TmrDbgListRemove(p_tmr); #endif OSTmrQty--; /* One less timer */ switch (p_tmr->State) { case OS_TMR_STATE_RUNNING: OS_TmrUnlink(p_tmr); /* Remove from current wheel spoke */ OS_TmrClr(p_tmr); OSSchedUnlock(&err); *p_err = OS_ERR_NONE; return (DEF_TRUE); case OS_TMR_STATE_STOPPED: /* Timer has not started or ... */ case OS_TMR_STATE_COMPLETED: /* ... timer has completed the ONE-SHOT time */ OS_TmrClr(p_tmr); /* Clear timer fields */ OSSchedUnlock(&err); *p_err = OS_ERR_NONE; return (DEF_TRUE); case OS_TMR_STATE_UNUSED: /* Already deleted */ OSSchedUnlock(&err); *p_err = OS_ERR_TMR_INACTIVE; return (DEF_FALSE); default: OSSchedUnlock(&err); *p_err = OS_ERR_TMR_INVALID_STATE; return (DEF_FALSE); } }
void OS_TmrTask (void *p_arg) { CPU_BOOLEAN done; OS_ERR err; OS_TMR_CALLBACK_PTR p_fnct; OS_TMR_SPOKE *p_spoke; OS_TMR *p_tmr; OS_TMR *p_tmr_next; OS_TMR_SPOKE_IX spoke; CPU_TS ts; CPU_TS ts_start; CPU_TS ts_end; p_arg = p_arg; /* Not using 'p_arg', prevent compiler warning */ while (DEF_ON) { (void)OSTaskSemPend((OS_TICK )0, /* Wait for signal indicating time to update tmrs */ (OS_OPT )OS_OPT_PEND_BLOCKING, (CPU_TS *)&ts, (OS_ERR *)&err); OSSchedLock(&err); ts_start = OS_TS_GET(); OSTmrTickCtr++; /* Increment the current time */ spoke = (OS_TMR_SPOKE_IX)(OSTmrTickCtr % OSCfg_TmrWheelSize); p_spoke = &OSCfg_TmrWheel[spoke]; p_tmr = p_spoke->FirstPtr; done = DEF_FALSE; while (done == DEF_FALSE) { if (p_tmr != (OS_TMR *)0) { p_tmr_next = (OS_TMR *)p_tmr->NextPtr; /* Point to next tmr to update because current ... */ /* ... timer could get unlinked from the wheel. */ if (OSTmrTickCtr == p_tmr->Match) { /* Process each timer that expires */ OS_TmrUnlink(p_tmr); /* Remove from current wheel spoke */ if (p_tmr->Opt == OS_OPT_TMR_PERIODIC) { OS_TmrLink(p_tmr, OS_OPT_LINK_PERIODIC); /* Recalculate new position of timer in wheel */ } else { p_tmr->State = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */ } p_fnct = p_tmr->CallbackPtr; /* Execute callback function if available */ if (p_fnct != (OS_TMR_CALLBACK_PTR)0) { (*p_fnct)((void *)p_tmr, p_tmr->CallbackPtrArg); } p_tmr = p_tmr_next; /* See if next timer matches */ } else { done = DEF_TRUE; } } else { done = DEF_TRUE; } } ts_end = OS_TS_GET() - ts_start; /* Measure execution time of timer task */ OSSchedUnlock(&err); if (OSTmrTaskTimeMax < ts_end) { OSTmrTaskTimeMax = ts_end; } } }