#include "stdio.h" #include "HIDO_Timer.h" #include "HIDO_Debug.h" #include "HIDO_Lock.h" #include "FreeRTOS.h" #include "task.h" typedef enum { TIMER_STATE_IDLE = 0, TIMER_STATE_STOPPED, TIMER_STATE_STARTED, TIMER_STATE_TIMEUP, } HIDO_TimerStateEnum; // volatile HIDO_UINT32 g_u32TimerTick = 0; volatile HIDO_UINT64 g_u64TimerTick = 0; HIDO_TimerStruct l_stTimerList[HIDO_TIMER_ID_MAX_CNT]; HIDO_INT32 HIDO_TimerCreate(HIDO_UINT32 *_pu32TimerID) { HIDO_UINT32 u32NewTimerID = 0; if (HIDO_NULL == _pu32TimerID) { return HIDO_ERR; } for (u32NewTimerID = 0; u32NewTimerID < HIDO_TIMER_ID_MAX_CNT; u32NewTimerID++) { if (TIMER_STATE_IDLE == l_stTimerList[u32NewTimerID].m_u32State) { l_stTimerList[u32NewTimerID].m_u32State = TIMER_STATE_STOPPED; break; } } if (HIDO_TIMER_ID_MAX_CNT == u32NewTimerID) { HIDO_Debug("timer ID is full\r\n"); return HIDO_ERR; } *_pu32TimerID = u32NewTimerID; return HIDO_OK; } HIDO_INT32 HIDO_TimerDestroy(HIDO_UINT32 _u32TimerID) { if (_u32TimerID >= HIDO_TIMER_ID_MAX_CNT) { return HIDO_ERR; } l_stTimerList[_u32TimerID].m_u32State = TIMER_STATE_IDLE; return HIDO_OK; } HIDO_INT32 HIDO_TimerStart(HIDO_UINT32 _u32TimerID, HIDO_UINT8 _u8Type, HIDO_UINT32 u32Tick, HIDO_TimerFunc _fnTimerProc, HIDO_VOID *_pPrivateData) { if (_u32TimerID >= HIDO_TIMER_ID_MAX_CNT) { return HIDO_ERR; } l_stTimerList[_u32TimerID].m_u32State = TIMER_STATE_STARTED; l_stTimerList[_u32TimerID].m_u8Type = _u8Type; l_stTimerList[_u32TimerID].m_u32Tick = xTaskGetTickCount(); l_stTimerList[_u32TimerID].m_u32TickBack = u32Tick; l_stTimerList[_u32TimerID].m_fnTimerProc = _fnTimerProc; l_stTimerList[_u32TimerID].m_pPrivateData = _pPrivateData; return HIDO_OK; } HIDO_INT32 HIDO_TimerCancel(HIDO_UINT32 _u32TimerID) { if (_u32TimerID >= HIDO_TIMER_ID_MAX_CNT) { return HIDO_ERR; } l_stTimerList[_u32TimerID].m_u32State = TIMER_STATE_STOPPED; l_stTimerList[_u32TimerID].m_u32Tick = 0; return HIDO_OK; } HIDO_VOID HIDO_TimerTick(void) { //g_u32TimerTick++; g_u64TimerTick++; } HIDO_UINT32 HIDO_TimerGetTick(void) { return xTaskGetTickCount(); } HIDO_UINT64 HIDO_TimerGetTick64(void) { HIDO_UINT64 u64Tick; HIDO_Lock(); u64Tick = g_u64TimerTick; HIDO_UnLock(); return u64Tick; } HIDO_VOID HIDO_TimerSetTick64(HIDO_UINT64 _u64Tick) { HIDO_Lock(); g_u64TimerTick = _u64Tick; HIDO_UnLock(); } HIDO_VOID HIDO_TimerPoll(void) { HIDO_UINT32 i = 0; HIDO_UINT32 u32Tick = xTaskGetTickCount(); for (i = 0; i < HIDO_TIMER_ID_MAX_CNT; i++) { if (TIMER_STATE_STARTED == l_stTimerList[i].m_u32State) { if ((u32Tick - l_stTimerList[i].m_u32Tick) > l_stTimerList[i].m_u32TickBack) { if (NULL != l_stTimerList[i].m_fnTimerProc) { if (HIDO_TIMER_TYPE_ONCE == l_stTimerList[i].m_u8Type) { l_stTimerList[i].m_u32State = TIMER_STATE_STOPPED; } else { l_stTimerList[i].m_u32State = TIMER_STATE_STARTED; l_stTimerList[i].m_u32Tick = u32Tick; } l_stTimerList[i].m_fnTimerProc(l_stTimerList[i].m_pPrivateData); } else { l_stTimerList[i].m_u32State = TIMER_STATE_STOPPED; } } } } } HIDO_VOID HIDO_TimerPollByID(HIDO_UINT32 _u32TimerID) { HIDO_UINT32 u32Tick = xTaskGetTickCount(); if (_u32TimerID < HIDO_TIMER_ID_MAX_CNT) { if (TIMER_STATE_STARTED == l_stTimerList[_u32TimerID].m_u32State) { if ((u32Tick - l_stTimerList[_u32TimerID].m_u32Tick) > l_stTimerList[_u32TimerID].m_u32TickBack) { if (NULL != l_stTimerList[_u32TimerID].m_fnTimerProc) { if (HIDO_TIMER_TYPE_ONCE == l_stTimerList[_u32TimerID].m_u8Type) { l_stTimerList[_u32TimerID].m_u32State = TIMER_STATE_STOPPED; } else { l_stTimerList[_u32TimerID].m_u32State = TIMER_STATE_STARTED; l_stTimerList[_u32TimerID].m_u32Tick = u32Tick; } l_stTimerList[_u32TimerID].m_fnTimerProc(l_stTimerList[_u32TimerID].m_pPrivateData); } else { l_stTimerList[_u32TimerID].m_u32State = TIMER_STATE_STOPPED; } } } } } /** * @brief »ñÈ¡×î½ü¼´½«³¬Ê±µÄ¶¨Ê±Æ÷µÄÊ£ÓàºÁÃëÊý * @param _u32DefaultMs ĬÈÏÖµ£¬µ±Ã»ÓлîÔ¾¶¨Ê±Æ÷ʱ·µ»Ø´ËÖµ * @return ×î½ü³¬Ê±µÄºÁÃëÊý£¬Èç¹ûûÓж¨Ê±Æ÷Ôò·µ»ØÄ¬ÈÏÖµ */ HIDO_UINT32 HIDO_TimerGetNearestTimeout(HIDO_UINT32 _u32DefaultMs) { HIDO_UINT32 i = 0; HIDO_UINT32 u32NearestTimeout = 0xFFFFFFFF; // ³õʼ»¯Îª×î´óÖµ HIDO_UINT32 u32CurrentTick = xTaskGetTickCount(); HIDO_UINT32 u32Elapsed = 0; HIDO_UINT32 u32Remaining = 0; HIDO_BOOL bHasActiveTimer = HIDO_FALSE; // ±éÀúËùÓж¨Ê±Æ÷ for (i = 0; i < HIDO_TIMER_ID_MAX_CNT; i++) { // Ö»´¦Àí´¦ÓÚSTARTED״̬µÄ¶¨Ê±Æ÷ if (TIMER_STATE_STARTED == l_stTimerList[i].m_u32State) { bHasActiveTimer = HIDO_TRUE; // ¼ÆËãÒѾ­¾­¹ýµÄtickÊý u32Elapsed = u32CurrentTick - l_stTimerList[i].m_u32Tick; // Èç¹ûÒѾ­³¬Ê±£¬Á¢¼´·µ»Ø0 if (u32Elapsed >= l_stTimerList[i].m_u32TickBack) { return 0; } // ¼ÆËãÊ£ÓàtickÊý u32Remaining = l_stTimerList[i].m_u32TickBack - u32Elapsed; // ¸üÐÂ×îСʣÓàʱ¼ä if (u32Remaining < u32NearestTimeout) { u32NearestTimeout = u32Remaining; } } } // Èç¹ûûÓлîÔ¾µÄ¶¨Ê±Æ÷£¬·µ»ØÄ¬ÈÏÖµ if (!bHasActiveTimer) { return _u32DefaultMs; } // ½«tickÊýת»»ÎªºÁÃëÊý // ×¢Ò⣺ÕâÀï¼ÙÉè1 tick = 1ms£¬Èç¹ûʵ¼Ê²»ÊÇ£¬ÐèÒª¸ù¾Ýʵ¼ÊÇé¿öµ÷Õû return u32NearestTimeout; }