#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;
|
}
|