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; p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */ for (;;) { /* 等待OSTmrSignal()发送的定时器更新的信号,在OSTimeTickHook()中调用,发送频率100HZ */ OSSemPend(OSTmrSemSignal, 0u, &err); /* Wait for signal indicating time to update timers */ /* 关调度 */ OSSchedLock(); OSTmrTime++; /* Increment the current time */ /* 获得当前要处理的分组编号 */ spoke = (INT16U)(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 = (OS_TMR *)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 */ /* 把定时器从当前分组移除,并设置定时器状态为OS_TMR_STATE_STOPPED * 虽然定时器已经不在该定时器分组中了,但是该定时器仍然有效,可以通过定时器控制块访问 */ 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 */ } /* 调用定时器到时回调函数 */ pfnct = ptmr->OSTmrCallback; /* Execute callback function if available */ if (pfnct != (OS_TMR_CALLBACK)0) { (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); } } /* 处理该分组中的下一个元素 */ ptmr = ptmr_next; } /* 允许调度 */ OSSchedUnlock(); } }
BOOLEAN OSTmrStart (OS_TMR *ptmr, INT8U *perr) { #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (OS_FALSE); } #endif #if OS_ARG_CHK_EN > 0u 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 > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } OSSchedLock(); 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 */ OSSchedUnlock(); *perr = OS_ERR_NONE; 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 */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (OS_TRUE); case OS_TMR_STATE_UNUSED: /* Timer not created */ OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSSchedUnlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (OS_FALSE); } }
BOOLEAN OSTmrDel (OS_TMR *ptmr, INT8U *perr) { #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (OS_FALSE); } #endif #if OS_ARG_CHK_EN > 0u 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 > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } OSSchedLock(); 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 */ OSSchedUnlock(); *perr = OS_ERR_NONE; 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 */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (OS_TRUE); case OS_TMR_STATE_UNUSED: /* Already deleted */ OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSSchedUnlock(); *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( ); } }
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); } }
BOOLEAN OSTmrStop (OS_TMR *ptmr, INT8U opt, void *callback_arg, INT8U *perr) { OS_TMR_CALLBACK pfnct; #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (OS_FALSE); } #endif #if OS_ARG_CHK_EN > 0u 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 > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } /* 调度器加锁 */ OSSchedLock(); 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; } OSSchedUnlock(); 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. */ OSSchedUnlock(); *perr = OS_ERR_TMR_STOPPED; return (OS_TRUE); /* 如果定时器是未使用状态,则返回错误信息 */ case OS_TMR_STATE_UNUSED: /* Timer was not created */ OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSSchedUnlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (OS_FALSE); } }
BOOLEAN OSTmrStart (OS_TMR *ptmr, INT8U *perr) { #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (OS_FALSE); } #endif #if OS_ARG_CHK_EN > 0u 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 > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } /* 调度器加锁 */ OSSchedLock(); switch (ptmr->OSTmrState) { /* 如果当前定时器是正在运行状态,则把定时器从当前分组移除 * 更新定时器到时时间后,把定时器重新链接到新的分组,并设置为第一次开始计时 */ case OS_TMR_STATE_RUNNING: /* Restart the timer */ OSTmr_Unlink(ptmr); /* ... Stop the timer */ /* 使用OS_TMR_LINK_DLY选项把定时器链接进新的分组 * 会按照第一次插入定时器,设置Dly或者Period */ OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (OS_TRUE); /* 如果定时器是Stop状态或者单次定时器的COMPLETED状态 * 则按照第一次插入定时器,设置Dly或者Period */ 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 */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (OS_TRUE); /* 如果定时器是未使用状态,返回错误信息 */ case OS_TMR_STATE_UNUSED: /* Timer not created */ OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSSchedUnlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (OS_FALSE); } }
BOOLEAN OSTmrDel (OS_TMR *ptmr, INT8U *perr) { #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (OS_FALSE); } #endif #if OS_ARG_CHK_EN > 0u 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 > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } /* 关调度 */ OSSchedLock(); /* 根据定时器的当前状态,使用不同的删除步骤 */ 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 */ /* 允许调度 */ OSSchedUnlock(); *perr = OS_ERR_NONE; 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 */ /* 允许调度 */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (OS_TRUE); /* 如果定时器控制块是未使用状态,则返回错误信息 */ case OS_TMR_STATE_UNUSED: /* Already deleted */ OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSSchedUnlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (OS_FALSE); } }