WSF操作系统抽象层学习笔记(四)---定时器
定時(shí)器
定時(shí)器的實(shí)現(xiàn)方式:
使用OS自帶的定時(shí)器模塊,建立一個(gè)定時(shí)器,定時(shí)間隔為自定義TICKS,定時(shí)器的回調(diào)函數(shù)中設(shè)置定時(shí)器到時(shí)的事件。
定時(shí)器模塊定義了一個(gè)定時(shí)器的鏈表,用于定時(shí)器的管理。
操作定時(shí)器管理鏈表的過(guò)程需要關(guān)閉任務(wù)調(diào)度。
注意:OS本身定時(shí)器存在一定的誤差,通過(guò)OS來(lái)實(shí)現(xiàn)的定時(shí)器也是有誤差的。誤差的大小跟WSF自定義的ticks大小有關(guān)。
定時(shí)器的管理結(jié)構(gòu)
//定時(shí)器對(duì)象管理結(jié)構(gòu) typedef struct wsfTimer_tag {struct wsfTimer_tag *pNext;???????????? //指向隊(duì)列中下一個(gè)定時(shí)器節(jié)點(diǎn)wsfTimerTicks_t???? ticks;???????? ?????//定時(shí)器超時(shí)tickswsfHandlerId_t????? handlerId;???????? //定時(shí)器超時(shí),處理函數(shù)句柄bool_t????????????? isStarted;???????? //定時(shí)器是否啟動(dòng)wsfMsgHdr_t???????? msg;??????? ?? ?? //應(yīng)用定義的定時(shí)器參數(shù) } wsfTimer_t;定時(shí)器的初始化
定時(shí)器的啟動(dòng)
? ? ? ?計(jì)算出定時(shí)器到時(shí)的ticks count,并將定時(shí)器根據(jù)到時(shí)的時(shí)間插入到管理鏈表中。
/* 啟動(dòng)MS級(jí)別的定時(shí)器 */ void WsfTimerStartMs(wsfTimer_t *pTimer, wsfTimerTicks_t ms) {WSF_TRACE_INFO2("WsfTimerStartMs pTimer:0x%x ticks:%u", (uint32_t)pTimer, WSF_TIMER_MS_TO_TICKS(ms));/* 計(jì)算時(shí)間為WSF的tick值,并根據(jù)大小插入到定時(shí)器鏈表中 */wsfTimerInsert(pTimer, WSF_TIMER_MS_TO_TICKS(ms)); }定時(shí)器的停止
? ? ? ?找到定時(shí)器在鏈表中的位置,并將定時(shí)器從鏈表中移除,設(shè)置定時(shí)器的狀態(tài)為,未啟動(dòng)狀態(tài)。
//定時(shí)器停止函數(shù) void WsfTimerStop(wsfTimer_t *pTimer) {WSF_TRACE_INFO1("WsfTimerStop pTimer:0x%x", pTimer);/* task schedule lock */WsfTaskLock();//將定時(shí)器從管理鏈表移除,設(shè)置定時(shí)器運(yùn)行狀態(tài)為falsewsfTimerRemove(pTimer);/* task schedule unlock */WsfTaskUnlock(); }定時(shí)器更新函數(shù)
? ? ? ?輪詢(xún)定時(shí)器管理鏈表中的每個(gè)定時(shí)器,減去已經(jīng)過(guò)去的ticks時(shí)間,判斷每個(gè)定時(shí)器是否到時(shí),若定時(shí)器到時(shí)則發(fā)送時(shí)間給對(duì)應(yīng)的處理函數(shù)。
void WsfTimerUpdate(wsfTimerTicks_t ticks) {wsfTimer_t *pElem;/* 關(guān)任務(wù)調(diào)度 */WsfTaskLock();pElem = (wsfTimer_t *) wsfTimerTimerQueue.pHead;/* 輪詢(xún)鏈表上所有的定時(shí)器 */while (pElem != NULL){/* 減去已經(jīng)獲取的始終ticks */if (pElem->ticks > ticks){pElem->ticks -= ticks;}else{pElem->ticks = 0;/* 定時(shí)器到期,通知對(duì)應(yīng)的事件處理函數(shù) */WsfTaskSetReady(pElem->handlerId, WSF_TIMER_EVENT);}pElem = pElem->pNext;}/* 是能任務(wù)調(diào)度 */WsfTaskUnlock(); }獲取當(dāng)前系統(tǒng)ticks,并更新所有定時(shí)器,并根據(jù)下一個(gè)到期Timer的時(shí)間,重新設(shè)置系統(tǒng)定時(shí)器的超時(shí)時(shí)間。
//根據(jù)實(shí)際的OS僅從此函數(shù)的移植,這個(gè)函數(shù)在相關(guān)的TASK中應(yīng)該一直被調(diào)用 void WsfTimerUpdateTicks(void) {uint32_t ui32CurrentTime, ui32ElapsedTime;bool_t bTimerRunning;wsfTimerTicks_t xNextExpiration;/* 讀取OS的時(shí)間值 */ui32CurrentTime = xTaskGetTickCount();/* 計(jì)算上次到這次計(jì)算之間的間隔 */ui32ElapsedTime = ui32CurrentTime - g_ui32LastTime;/* 計(jì)算是否達(dá)到了WSF的自定義tick值 */if ( (ui32ElapsedTime / CLK_TICKS_PER_WSF_TICKS) > 0 ){/* 更新所有定時(shí)器 */WsfTimerUpdate(ui32ElapsedTime / CLK_TICKS_PER_WSF_TICKS);g_ui32LastTime = ui32CurrentTime;}/* 檢查是否有定時(shí)器在運(yùn)行,并獲取剩余的ticks */xNextExpiration = WsfTimerNextExpiration(&bTimerRunning);/* 根據(jù)下一個(gè)到時(shí)時(shí)間,重新設(shè)置OS定時(shí)器的周期 */if ( xNextExpiration ){configASSERT(pdPASS == xTimerChangePeriod( xWsfTimer,pdMS_TO_TICKS(xNextExpiration*CLK_TICKS_PER_WSF_TICKS), 100)) ;} }?
總結(jié)
以上是生活随笔為你收集整理的WSF操作系统抽象层学习笔记(四)---定时器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 全球矢量任意下载 路网、水系、建筑..
- 下一篇: 手机软件