引 言
定時器是通信協(xié)議正常運行的基本要素之一,,主要用于各種定時和幀重傳的任務(wù)。通信協(xié)議在單片機系統(tǒng)上實現(xiàn)所使用的定時器,,定時精度要求不高,,但數(shù)量要求比較大。由于硬件資源有限,,不可能為每一個單獨任務(wù)分配一個硬件定時器,,只能通過單個硬件定時器模擬多個軟件定時器的方法,來滿足協(xié)議中的定時應(yīng)用需要,。
用一定的數(shù)據(jù)結(jié)構(gòu)將這些軟件定時器組織起來,,并提供統(tǒng)一的調(diào)用接口,稱為“定時器管理”,。目前定時器管理主要有2種實現(xiàn)方法:
①靜態(tài)數(shù)組法,。將定時器節(jié)點存儲在數(shù)組中。優(yōu)點是邏輯簡單,占用ROM較少,。但這種方案有明顯的缺點:當(dāng)硬件定時器中斷發(fā)生時,,要對所有定時器節(jié)點進行減法操作,時間開銷很大,,且時延不確定(與定時器數(shù)目相關(guān)),。
②delta鏈表法。按照定時器的定時值升序排列,,形成鏈表,。后一個定時器的定時值是前面所有定時器的值加上本節(jié)點的值。這樣,,在每次的時鐘中斷處理中,,只需對第1個定時器節(jié)點進行減法操作,大大減少了時間開銷,。但是,,該方案邏輯復(fù)雜,ROM用量大,,需要頻繁分配回收內(nèi)存,,容易形成內(nèi)存碎片。
1 定時器管理模塊的設(shè)計
定時器管理模塊的設(shè)計基于靜態(tài)數(shù)組法,。使用一個定時器節(jié)點數(shù)組來保存所有的定時請求,,數(shù)組的每一項代表一個可用的定時器節(jié)點。每一個定時器節(jié)點都有一個狀態(tài)項,,表示該定時器正處于空閑,、使用或溢出狀態(tài)。定時器的定時值和定時器超時后要發(fā)送的消息也存儲在定時器節(jié)點中,,從而實現(xiàn)用一個硬件定時器為用戶提供多個軟件定時器,。
為了解決中斷處理時間開銷大的問題,在模塊中引入一個輔助定時器,,輔助定時器的值總是等于所有定時器節(jié)點中的最小定時值,。在硬件定時器中斷處理中,僅對輔助定時器進行減法操作,,從而大大縮短了中斷處理的時間,。設(shè)計原理如圖1所示。
2定時器管理模塊的實現(xiàn)
2.1 數(shù)據(jù)結(jié)構(gòu)和函數(shù)接口
定時器管理模塊使用的相關(guān)數(shù)據(jù)結(jié)構(gòu)定義如下:
字段state保存了定時器節(jié)點的狀態(tài),,可能取值為空閑(T_FREE),、使用(T_INUSE)或溢出(T_OVERFLOW)。
字段count保存了定時器節(jié)點的定時值,,最大取值為65 535,。如果設(shè)置硬件定時器中斷為10 ms,,則軟件定時器最大定時約為655 s,,可以滿足大多數(shù)應(yīng)用需要,。
字段msg指向定時器的用戶消息。在啟動定時器時,,指向消息的指針被保存在此字段,。當(dāng)定時時間結(jié)束后,中斷處理函數(shù)會自動發(fā)出這個消息以通知用戶任務(wù),。
由于數(shù)組的下標(biāo)是唯一的,,可作為識別節(jié)點的唯一ID號。下文中提到的節(jié)點ID號均表示節(jié)點在數(shù)組中的下標(biāo),。
MAX_TIMER_NUM表示系統(tǒng)允許的最大定時器數(shù),,其值取決于具體應(yīng)用需要。
本模塊提供的關(guān)鍵接口函數(shù)如下:
2.2定時器的初始化
使用定時器管理模塊前,,需要進行定時器的初始化,。主要是初始化定時器節(jié)點數(shù)組,將每一個定時器節(jié)點設(shè)置為空閑狀態(tài),,同時將輔助定時器置零,,輔助ID指向0xFF(表示空)。
2.3定時器的啟動
啟動一個定時器,,主要是將節(jié)點數(shù)組中一個空閑狀態(tài)的節(jié)點置為使用狀態(tài),。如果這個新啟用的定時器,是所有定時器中定時值最小的,,還要更新輔助定時器,。函數(shù)以指向定時器消息的指針和定時值為參數(shù),啟動定時器流程如圖2所示,。成功啟動定時器后,,返回該定時器節(jié)點的ID號。
2.4定時器的刪除
在目標(biāo)定時器到期之前,,由于某種原因用戶可能會要求取消定時器,。如重發(fā)定時器,用戶在發(fā)送數(shù)據(jù)幀后啟動該定時器,,并等待對方返回響應(yīng)幀,。如果在定時時間結(jié)束時沒有收到響應(yīng)幀,用戶就需要重發(fā)原數(shù)據(jù)幀,;如果在定時時間結(jié)束之前收到響應(yīng)幀,,用戶就需要馬上取消該定時器,然后進行下一次通信過程,。
刪除定時器函數(shù)以定時器節(jié)點ID號作為輸入?yún)?shù),,將定時器節(jié)點設(shè)為空閑狀態(tài),,并根據(jù)需要更新輔助定時器,流程如圖3所示,。
2.5定時器的驅(qū)動
軟件定時器的驅(qū)動由硬件定時器提供,。在硬件定時器中斷中,首先將輔助定時器的值減1,。如果輔助定時器值為0,,則表示定時值最小的定時器已經(jīng)超時,應(yīng)將對應(yīng)的消息發(fā)送給用戶任務(wù),,將節(jié)點置為空閑狀態(tài),,并重新計算其他節(jié)點的定時值,同時查找定時值最小的節(jié)點,,更新輔助定時器,。驅(qū)動流程如圖4所示。
關(guān)鍵代碼如下:
結(jié) 語
本文設(shè)計的定時器管理器模塊,,具有邏輯簡單,、效率高的特點,在實驗室自主研發(fā)的無線傳感器網(wǎng)絡(luò)中得到應(yīng)用,。在共包含30個節(jié)點的溫,、濕、光信息采集系統(tǒng)中,,使用該定時器管理模塊的無線傳感器網(wǎng)絡(luò)協(xié)議運行高效,、穩(wěn)定。