定時器代碼

/*************************************************************************** 文件:HHTimer.c 作者:譚宜平 日期:2008-09-22 版本:1.0 描述:封裝系統對定時器的操作 其他: ****************************************************************************/ #include "HHHeader.h" #define MAX_FILENAME_LENGTH 15 /* 最大的文件名長度 */ #define MAX_TIMER_NUM 256 /* 最大的定時器個數 */ #define DEFAULT_TIMER_RESOLUTION 1 /* ms */ /************************************************************************** 類型:結構體名稱:TimerInfoDef 作用:定時器的相關信息 ***************************************************************************/ typedef struct tagTimerInfo { HhBool blIsUsed; /* 是否正在使用 */ pfTimerCBDef pfTimerCB; /* 定時器觸發時的回調函數 */ HhBool blIsPeriodic; /* 是否週期性定時器 */ HhVoid *pAppContext; /* 應用程序上下文 */ HhInt iCounterLen; /* 定時器觸發週期,ms */ HhInt iCounter; /* 定時器觸發剩餘時間 */ HhInt iTimerID; /* 定時器序號 */ HhChar szFile[MAX_FILENAME_LENGTH]; /* 文件名 */ HhInt iLineNo; /* 行號 */ }TimerInfoDef, *LPTimerInfoDef; /************************************************************************** 類型:全局變量名稱:g_TimerTable 作用:定時器資源 ***************************************************************************/ static TimerInfoDef g_TimerTable[MAX_TIMER_NUM] = {0}; /************************************************************************** 類型:全局變量名稱: 作用:10毫秒定時器 ***************************************************************************/ static HhULong g_ul10MSTimerID = 0; static HhInt g_iResolution = 0; /************************************************************************** 類型:全局變量名稱:g_TableLock 作用:鎖 ***************************************************************************/ static HhLockDef g_TableLock; /************************************************************************** 原型:LPTimerInfoDef AllocIdleTimer() 輸入: 無輸出: 無返回: 成功返回定時器資源,失敗返回NULL 作用: 申請定時器資源 ***************************************************************************/ static LPTimerInfoDef AllocIdleTimer() { /* 從上次分配處往後分配 */ static HhInt s_iNextPos = 0; LPTimerInfoDef pTimerInfo; HhInt iCount = 0; /* 查找空閒的空間 */ while (HH_TRUE == g_TimerTable[s_iNextPos].blIsUsed) { s_iNextPos++; if (s_iNextPos >= MAX_TIMER_NUM) { s_iNextPos = 0; } iCount++; if (iCount >= MAX_TIMER_NUM) { break; } } if (iCount >= MAX_TIMER_NUM) { return NULL; } pTimerInfo = &(g_TimerTable[s_iNextPos]); pTimerInfo->blIsUsed = HH_TRUE; pTimerInfo->iTimerID = s_iNextPos + 1; s_iNextPos++; if (s_iNextPos >= MAX_TIMER_NUM) { s_iNextPos = 0; } return pTimerInfo; } /************************************************************************** 原型:HhInt FreeTimer(IN HhInt iTimerID) 輸入: iTimerID : 定時器編號(HhTimerStart生成) 輸出: 無返回: 成功返回HH_SUCCESS,失敗返回HH_FAIL 作用: 釋放定時器資源 ***************************************************************************/ static HhInt FreeTimer(IN HhInt iTimerID) { if (HH_FALSE == g_TimerTable[iTimerID - 1].blIsUsed) { ldOutput(EN_ET_DEBUG, "[%s:%d]FreeTimer():輸入的Timer沒被使用, %s : %d", __FILE__, __LINE__, "TimerID", iTimerID); return HH_FAIL; } memset(&(g_TimerTable[iTimerID - 1]), 0, sizeof(TimerInfoDef)); return HH_SUCCESS; } /************************************************************************** 原型: void CALLBACK On10MSTimer(UINT gwTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) 輸入: UINT gwTimerID : 定時器ID UINT msg : 消息 DWORD dwUser : DWORD dw1 : 參數1 DWORD dw2 : 參數2 輸出: 無返回: 0 成功,其他值失敗作用: 10毫秒定時器回調函數 ***************************************************************************/ static void CALLBACK On10MSTimer(UINT gwTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) { HhInt i; LPTimerInfoDef pTimer; HhLockGet(&g_TableLock); for (i = 0; i < MAX_TIMER_NUM; i++) { if (g_TimerTable[i].blIsUsed) { pTimer = &(g_TimerTable[i]); pTimer->iCounter--; if (pTimer->iCounter <= 0) { if (NULL != pTimer->pfTimerCB) { /* 定時器到時的回調函數 */ (pTimer->pfTimerCB)(pTimer->iTimerID, (HhULong)pTimer->pAppContext); } /* 週期性定時器 */ if (pTimer->blIsPeriodic) { pTimer->iCounter = pTimer->iCounterLen; } else { FreeTimer(pTimer->iTimerID); } } } } HhLockRelease(&g_TableLock); return; } /************************************************************************** 原型:HhInt Start10MStimer() 輸入: 無輸出: 無返回: 0 成功,其他值失敗作用: 啓動10毫秒定時器 ***************************************************************************/ static HhInt Start10MStimer() { TIMECAPS tc; LARGE_INTEGER i64Freq = { 0 }; if (g_ul10MSTimerID != 0) { ldOutput(EN_ET_DEBUG, "[%s:%d]重複創建定時器!", __FILE__, __LINE__); return HH_FAIL; } if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { ldOutput(EN_ET_DEBUG, "[%s:%d]獲取定時器能力失敗!", __FILE__, __LINE__); return HH_FAIL; } QueryPerformanceFrequency(&i64Freq); g_iResolution = __min(tc.wPeriodMax, __max(tc.wPeriodMin, DEFAULT_TIMER_RESOLUTION)); timeBeginPeriod(g_iResolution); g_ul10MSTimerID = timeSetEvent (10, /* delay */ g_iResolution, On10MSTimer, /* callback function */ (DWORD)NULL, /* user data */ TIME_PERIODIC); /* single timer event */ if (g_ul10MSTimerID == 0) { ldOutput(EN_ET_DEBUG, "[%s:%d]創建多媒體定時器失敗", __FILE__, __LINE__); return HH_FAIL; } return HH_SUCCESS; } /************************************************************************** 原型:HhInt Stop10MSTimer() 輸入: 無輸出: 無返回: 0 成功,其他值失敗作用: 停止10毫秒定時器 ***************************************************************************/ static HhInt Stop10MSTimer() { if (g_iResolution != 0) { timeEndPeriod(g_iResolution); g_iResolution = 0; } if (0 != g_ul10MSTimerID) { timeKillEvent(g_ul10MSTimerID); g_ul10MSTimerID = 0; } return HH_SUCCESS; } /************************************************************************** 原型:HhInt HhTimerStart(IN pfTimerCBDef pfTimerCB, IN HhULong ulTimerIndex, IN HhBool blIsPeriodic, IN HhVoid *pAppContext) 輸入: pfTimerCBDef pfTimerCB : 定時器回調函數 ulTimerLength : 定時器時長,以ms爲單位 blIsPeriodic : 是否週期性 pAppContext : 應用程序上下文(用於傳遞應用層信息,會附在定時器消息中) 輸出: 無返回: <0 : 失敗 >=0 : 成功,表示定時器編號(系統自動生成,用於STOP及區分序號相同的不同定時器) 作用: 啓動定時器 ***************************************************************************/ HhInt HhTimerStartEx(IN pfTimerCBDef pfTimerCB, IN HhULong ulTimerLength, IN HhBool blIsPeriodic, IN HhVoid *pAppContext, IN HhChar* pszFile, IN HhInt iLineNo) { LPTimerInfoDef pTimerInfo = NULL; HhInt iLength, iStart; CHECK_PTR(pfTimerCB, HH_FAIL, "HHOS->HhTimerStartEx():NULL == pfTimerCB"); HhLockGet(&g_TableLock); pTimerInfo = AllocIdleTimer(); if (NULL == pTimerInfo) { HhLockRelease(&g_TableLock); return HH_FAIL; } pTimerInfo->blIsPeriodic = blIsPeriodic; pTimerInfo->iLineNo = iLineNo; pTimerInfo->pAppContext = pAppContext; pTimerInfo->pfTimerCB = pfTimerCB; pTimerInfo->iCounterLen = ulTimerLength / 10; pTimerInfo->iCounter = pTimerInfo->iCounterLen; iLength = strlen(pszFile); iStart = iLength - MIN(iLength, MAX_FILENAME_LENGTH); memcpy(pTimerInfo->szFile, pszFile + iStart, MAX_FILENAME_LENGTH); ldOutput(EN_ET_DEBUG, "[%s:%d]HhTimerStart();%d, File: %s, line: %d/n", / __FILE__, __LINE__, pTimerInfo->iTimerID, pszFile, iLineNo); HhLockRelease(&g_TableLock); return pTimerInfo->iTimerID; } /************************************************************************** 原型:HhInt HhTimerStop(IN HhInt iTimerID) 輸入: iTimerID : 定時器編號(HhTimerStart生成) 返回: 0 成功,其他值失敗作用: 停止指定定時器 ***************************************************************************/ HhInt HhTimerStopEx(IN HhInt iTimerID, IN HhChar* pszFile, IN HhInt iLineNo) { if ((iTimerID < 0) || (iTimerID > MAX_TIMER_NUM)) { ldOutput(EN_ET_DEBUG, "[%s:%d]HHOS->HhTimerStopEx();輸入TimerID非法%d, File: %s, line: %d/n", / __FILE__, __LINE__, iTimerID, pszFile, iLineNo); return HH_FAIL; } HhLockGet(&g_TableLock); FreeTimer(iTimerID); HhLockRelease(&g_TableLock); ldOutput(EN_ET_DEBUG, "[%s:%d]HHOS->HhTimerStop();%d, File: %s, line: %d/n", / __FILE__, __LINE__, iTimerID, pszFile, iLineNo); return HH_FAIL; } /************************************************************************** 原型:HhInt HhTimerReset(IN HhInt iTimerID) 輸入: iTimerID : 定時器編號(HhTimerStart生成) 輸出: 無返回: 0 成功,其他值失敗作用: 重啓定時器 ***************************************************************************/ HhInt HhTimerReset(IN HhInt iTimerID) { LPTimerInfoDef pTimerInfo; HhInt iRet; if ((iTimerID < 0) || (iTimerID > MAX_TIMER_NUM)) { ldOutput(EN_ET_DEBUG, "[%s:%d]HhTimerReset();輸入TimerID非法%d/n", __FILE__, __LINE__, iTimerID); return HH_FAIL; } HhLockGet(&g_TableLock); pTimerInfo = &(g_TimerTable[iTimerID]); if (pTimerInfo->blIsUsed) { pTimerInfo->iCounter = pTimerInfo->iCounterLen; iRet = HH_SUCCESS; } else { ldOutput(EN_ET_DEBUG, "[%s:%d]HhTimerReset():輸入的TimerID沒有使用, TimerID : %d", __FILE__, __LINE__, iTimerID); iRet = HH_FAIL; } HhLockRelease(&g_TableLock); return iRet; } /************************************************************************** 原型:HhInt HhTimerInit() 輸入: 無輸出: 無返回: 0 成功,其他值失敗作用: 初始化定時器模塊 ***************************************************************************/ HhInt HhTimerInit() { HhLockConstruct(&g_TableLock); if (HH_FAIL == Start10MStimer()) { ldOutput(EN_ET_DEBUG, "[%s:%d]HhTimerInit():打開10ms定時器失敗", __FILE__, __LINE__); return HH_FAIL; } return HH_SUCCESS; } /************************************************************************** 原型:HhInt HhTimerUnInit() 輸入: 無輸出: 無返回: 0 成功,其他值失敗作用: 反初始化定時器模塊 ***************************************************************************/ HhInt HhTimerUnInit() { Stop10MSTimer(); HhLockDestruct(&g_TableLock); return HH_SUCCESS; }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章