專利名稱:一種嵌入式系統(tǒng)定時器的管理方法
技術(shù)領(lǐng)域:
本發(fā)明屬于嵌入式系統(tǒng)定時器管理技術(shù)領(lǐng)域,尤其涉及一種嵌入式系統(tǒng) 定時器的管理方法。
背景技術(shù):
實(shí)時操作系統(tǒng)由于對時限的要求非常嚴(yán)格,而實(shí)時操作系統(tǒng)對時序的偏差 依賴性很強(qiáng),因此作為實(shí)時嵌入式系統(tǒng)軟件時間管理的核心模塊一定時器模塊 的設(shè)計實(shí)現(xiàn)就顯得非常重要。
目前,嵌入式系統(tǒng)軟件的通用定時器的通常設(shè)計主要有以下幾種
(1) 簡單計時輪詢法
當(dāng)每個計時周期到達(dá)時,先將所有定時器的計時數(shù)減1,然后判斷結(jié)果是 否為0,如果為0,則表示計時時間已到并進(jìn)行到時處理,否則繼續(xù)進(jìn)行計時 操作,這種方法稱為簡單計時輪詢法。
(2) 多隊列計時法
多隊列計時法首先根據(jù)系統(tǒng)定時應(yīng)用特點(diǎn),將定時器劃分成不同時長的隊 列,目的在于減少每次參與計數(shù)的定時器個數(shù)(設(shè)定定時器時就將計時時長分 解為毫秒位、個位、十位、百位、千位等幾個部分);再把定時器插入到最大 不為0的位所在的隊列,計時就從該隊列開始,完成后逐一計以下位,直至計 時到毫秒位隊列;在該隊列計時完成后定時器總計時完畢。由于各隊列除頭定 時器外計算的均是相對于上個定時器的時間相對值,計時的時候只需對隊列頭 部時間做減運(yùn)算便可確定是否有定時器在本次計時到期。
(3)單循環(huán)隊列定時器算法
單循環(huán)隊列計時原理假定所需的最大定時器數(shù)目為M個,則設(shè)置M個定 時器描述數(shù)組。再構(gòu)造一個循環(huán)計時隊列緩沖(長度為U,其元素指示定時器
鏈表隊列頭標(biāo)識ID和尾ID,通過該ID與定時器緩沖中的相應(yīng)元素構(gòu)成虛擬雙 向鏈表。每個時鐘Tick(Tick的時長由BSP決定,BSP: Board Support Package, 它是板級支持包,介于主板硬件和操作系統(tǒng)之間的一層,主要目的是為了支持 操作系統(tǒng),使之能夠更好的運(yùn)行于硬件主板)到來時,循環(huán)計時隊列頭向后走 一位,查找該位所指示的隊列中是否存在時間已到定時器,如存在,則取出做 相應(yīng)報時操作和定時器時長與L取余的余數(shù)位隊列插入操作。對于超過L長度 的定時器,因已計算出定時器時長與L相除所得的倍數(shù),每次循環(huán)計時隊列頭 經(jīng)過時,該倍數(shù)值得減去1,直至倍數(shù)值被減為0,之后的檢查就可報時并進(jìn) 行插入操作。新定時器的插入位置等于當(dāng)前循環(huán)計時隊列頭位置加新定時器時 長與循環(huán)隊列長度相除的余數(shù)再與循環(huán)計時隊列長度相除取余,并在循環(huán)隊列 所在節(jié)點(diǎn)對定時器進(jìn)行排序操作。
簡單計時輪詢法固然方法簡單,實(shí)現(xiàn)容易,但當(dāng)定時器數(shù)目很多(10000 個)時,每次計數(shù)需所有定時器做減法,每秒需做10萬次減法(每個Tick為 10ms)。而嵌入式系統(tǒng)的CPU資源相當(dāng)有限,定時器本身的任務(wù)不能占用太多 的資源,所以如果采用這種方法,就會占用較多的CPU資源。
多隊列計時法相對簡單,計時法更高效,在每次計時周期到來時,只需做 與隊列次數(shù)相同的判斷和減法以及可能的報時操作就能基本滿足嵌入式系統(tǒng) 的定時需求。但該方法也存在很多冗余操作,如空負(fù)載時檢查所有隊列,滿負(fù) 載時要對所有隊列做2倍于空負(fù)載檢査時的加減法操作,真正有效操作只占少 部分,而且在隊列處理中存在耗費(fèi)計算資源的排序操作。
單循環(huán)隊列定時器算法相對前兩種效率要高很多,但也存在自己的弱點(diǎn), 循環(huán)隊列由長度為L的數(shù)組和循環(huán)指針變量組成,循環(huán)隊列的長度為L,如
果L太小容易造成倍數(shù)值的減操作過多,效率得不到提高;L太大則浪費(fèi)存
儲空間。
發(fā)明內(nèi)容
本發(fā)明的目的在于,提供一種嵌入式系統(tǒng)定時器的管理方法,通過此方法, 可以解決目前使用的定時器管理方法中,占用系統(tǒng)資源過多的問題。
本發(fā)明的技術(shù)方案是 一種嵌入式系統(tǒng)定時器的管理方法,其特征是所述 方法包括下列步驟
步驟l:創(chuàng)建一個管理定時器的雙向鏈表;在雙向鏈表中,定時器的管理 方式包括在鏈表中注冊定時器、在鏈表中注銷定時器和在鏈表中修改定時器; 定時器的最小粒度為1個TICK;
步驟2:當(dāng)使用模塊需要定時器時,在鏈表中注冊一個定時器;
步驟3:在一個TICK到時的時候,從鏈表的頭部開始檢查定時器的超時情 況,直到第一個未超時的定時器;
步驟4:將所有超時的定時器從雙向鏈表中注銷,加入到超時隊列中;
步驟5:對超時隊列中的定時器進(jìn)行處理,根據(jù)定時器的注冊狀態(tài),分別 向注冊模塊發(fā)送消息或進(jìn)行函數(shù)回調(diào);
步驟6:對于周期性定時器,超時后自動再注冊到鏈表中,否則釋放定時 器;然后回到步驟3,在下一個Tick重復(fù)步驟3至步驟6。
所述在鏈表中注冊定時器的方法,是按照定時器超時的先后順序,向鏈表 中插入定時器;其具體步驟包括
步驟ll:調(diào)用注冊定時器模塊;
步驟12:申請一個新的定時器結(jié)構(gòu)節(jié)點(diǎn)空間;
步驟13:査看定時器鏈表;
步驟14:判斷鏈表是否為空,如果為空,則執(zhí)行步驟15;否則,執(zhí)行步 驟16;
步驟15:把當(dāng)前定時器插入鏈表,并修改相應(yīng)的前后向指針、定時器個數(shù) 和定時器間隔值,然后返回調(diào)用模塊;
步驟16:從定時器鏈表中查找第一個比要注冊的定時器更晚超時的定時
器;
步驟17:如果查到,則執(zhí)行步驟18;否則,執(zhí)行步驟19;
步驟18:把要注冊的定時器插入到查到的定時器前面,并修改相應(yīng)的前后 向指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊;
步驟19:把要注冊的定時器插入到鏈表尾部,并修改相應(yīng)的前后向指針、 定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。
所述在鏈表中注銷定時器的方法,包括下列步驟
步驟21:調(diào)用注銷定時器模塊;
步驟22:在鏈表中查找要注銷的定時器;
步驟23:判斷是否查到要注銷的定時器,如果查到,則執(zhí)行步驟24;否 則,返回調(diào)用模塊;
步驟24:將要注銷的定時器從鏈表中刪除,并修改要注銷的定時器的前向 節(jié)點(diǎn)的后向指針,以及后向節(jié)點(diǎn)的前向指針,重新計算后一個定時器的間隔值 和定時器的數(shù)目;而后返回調(diào)用模塊。
所述在鏈表中修改定時器的方法,包括下列步驟
步驟31:調(diào)用修改定時器模塊;
步驟32:在鏈表中査找要修改的定時器;
步驟33:判斷是否査到要修改的定時器,如果查到,則執(zhí)行步驟34;否 則,返回調(diào)用模塊;
步驟34:先將査到的要修改的定時器注銷;方法是將要修改的定時器從鏈
表中刪除,并修改該定時器的前向節(jié)點(diǎn)的后向指針,以及后向節(jié)點(diǎn)的前向指針, 重新計算后一個定時器的間隔值和定時器的數(shù)目;
步驟35:再將查到的要修改的定時器注冊到鏈表中,方法是在定時器鏈表 中查找第一個比要修改的定時器更晚超時的定時器;
步驟36:判斷是否査到符合要求的定時器,如果査到,則執(zhí)行步驟37; 否則執(zhí)行步驟38;
步驟37:把要修改的定時器插入到查到的定時器前面,并修改相應(yīng)的前后 向指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊;
步驟38:把要修改的定時器插入到鏈表尾部,并修改相應(yīng)的前后向指針、
定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。
所述從鏈表的頭部開始檢查定時器的超時情況,直到第一個未超時的定時
器,其方法是,將鏈表中的第一個定時器的時間差值減1,如果結(jié)果不等于o 說明無超時定時器;如果結(jié)果等于0,則繼續(xù)查找下一個時間差值為0的定時 器,直到最后一個不為0的定時器。
本發(fā)明通過雙向鏈表實(shí)現(xiàn)對定時器的管理,當(dāng)定時器數(shù)目非常多的時候, 此種設(shè)計只需要進(jìn)行少量的計算,就可以實(shí)現(xiàn)對所有定時器的控制。由于采用 雙向鏈表進(jìn)行管理,定時器在注冊時申請內(nèi)存,刪除時釋放內(nèi)存,內(nèi)存開銷由 當(dāng)前的定時器數(shù)目來決定,因此有效節(jié)約了系統(tǒng)資源。
圖1是本發(fā)明實(shí)現(xiàn)的定時器管理流程示意圖。 圖2是本發(fā)明實(shí)現(xiàn)的定時器注冊流程示意圖。 圖3是本發(fā)明實(shí)現(xiàn)的定時器注銷流程示意圖。 圖4是本發(fā)明實(shí)現(xiàn)的定時器修改流程示意圖。
具體實(shí)施例方式
下面是C語言實(shí)現(xiàn)的本發(fā)明的數(shù)據(jù)結(jié)構(gòu),主要包括: 1)管理定時器的雙向鏈表結(jié)構(gòu)
typedef struct tagTimer
struct tagTimer struct tagTimer ULONG VOID VOID
*pstNext; *pstPrev;
msgQId;
(*pfFu nc)(VOID *pAr g;
TIMER TYPE EN enType;
LONG LONG ULONG
} Timer—S;
2)鏈表頭結(jié)構(gòu) typedef struct
Timer一S ULONG
} TimerListHeader—S;
ITick;
ITickGap;
ulModuleld;
〃后向指針 〃前向指針 〃定時器消息隊列ID 0;〃超時回調(diào)函數(shù) 〃回調(diào)函數(shù)的參數(shù) 〃定時器類型(一次性定時器或 周期性定時器) 〃定時器時間長度 〃和前一個定時器的時間差 〃注冊定時器的模塊號
*hea d; ulCount;
〃第一個定時器結(jié)構(gòu)指針 //定時器結(jié)構(gòu)數(shù)量
用C語言實(shí)現(xiàn)本發(fā)明的主要接口函數(shù)包括
1) TimerModulelnitO,定時器模塊初始化,創(chuàng)建定時器任務(wù)( 調(diào)用方式LONG TimerModulelnit();
返回值成功或失敗。
2) TimerCreate(),創(chuàng)建定時器 LONG TimerCreate(ULONG ulModuleld,
ULONG msgQId,
LONG腿lSec,
VOID (承pfTimerFunc)(VOID *),
VOID *pArg,
TIMER—TYPE—EN enType)
輸入?yún)?shù)
ULONGulModuleld 〃創(chuàng)建定時器的模塊ID
ULONG msgQId 〃發(fā)送定時器超時消息的隊列ID
LONG 1MillSec 〃時間值
VOID (*pfTimerFunc)(VOID *) 〃回調(diào)函數(shù)
VOID *pArg 〃回調(diào)函數(shù)參數(shù)
返回值成功時,定時器的ID(控制塊指針),否則返回失敗
3) TimerChange(),改變定時器時間 LONG TimerChange(ULONG ulModuleld,
ULONG ulTimerld, LONG MllSec)
輸入?yún)?shù)
ulModuleld〃模塊Id, ulTimerld 〃定時器Id IMillSec 〃定時器的時間
返回值成功或失敗。
4) TimerDelete(),注銷定時器 LONG TimerDelete(ULONG ulModuleld,
ULONG ulTimerld)
輸入?yún)?shù)
ulTimerID 〃定時器Id
返回值成功或失敗。
下面結(jié)合附圖,對本發(fā)明的實(shí)施方式進(jìn)行詳細(xì)介紹。
圖l是本發(fā)明實(shí)現(xiàn)的定時器管理流程示意圖。圖中,步驟101首先通過
TimerModulelnit()創(chuàng)建的定時器任務(wù),創(chuàng)建一個管理定時器的雙向鏈表,定時 器的最小粒度為l個TICK。
步驟102向鏈表中注冊定時器。定時器分兩種類型 一次性定時器和周期 性定時器。定時器使用模塊調(diào)用TimerCreate()函數(shù)創(chuàng)建一個定時器,定時器注 冊的原則是所有定時器按超時的先后順序插入到鏈表中。圖2是本發(fā)明實(shí)現(xiàn)的 定時器注冊流程示意圖。圖2中,步驟201在注冊定時器時,調(diào)用注冊定時器模 塊。步驟202,申請一個新的定時器結(jié)構(gòu)節(jié)點(diǎn)空間。步驟203,查看定時器鏈表。
步驟204,判斷鏈表是否為空?如果為空,則執(zhí)行步驟205;如果不為空,則執(zhí) 行步驟206。步驟205,把當(dāng)前定時器插入鏈表,并修改相應(yīng)的前后向指針、定 時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。步驟206,從定時器鏈表中査 找第一個比要注冊的定時器更晚超時的定時器。步驟207,判斷是否査到符合 要求的定時器,如果查到,則執(zhí)行步驟208;否則,執(zhí)行步驟209。步驟208, 把要注冊的定時器插入到査到的定時器前面,并修改相應(yīng)的前后向指針、定時 器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。步驟209,把要注冊的定時器插 入到鏈表尾部,并修改相應(yīng)的前后向指針、定時器個數(shù)和定時器間隔值,然后 返回調(diào)用模塊。
步驟103在每一個TICK到時的時候,從鏈表的頭部開始檢查定時器的到時 情況,直到第一個未到時的定時器。査找的方法是,將鏈表中的第一個定時器 的時間差值減l,如果結(jié)果不等于O說明無超時定時器;如果結(jié)果等于O,則繼 續(xù)査找下一個時間差值為O的定時器,直到最后一個不為O的定時器。
步驟104將所有超時的定時器從雙向鏈表中注銷,加入到超時隊列中。注 銷定時器通過TimerDdete()函數(shù)實(shí)現(xiàn)。圖3是本發(fā)明實(shí)現(xiàn)的定時器注銷流程示 意圖。圖3中,步驟301首先調(diào)用注銷定時器模塊。步驟302在鏈表中査找要 注銷的定時器。步驟303判斷是否查到要注銷的定時器,如果查到,則執(zhí)行歩 驟304;否則,返回調(diào)用函數(shù)。步驟304將要注銷的定時器從鏈表中刪除,并 修改要注銷的定時器的前向節(jié)點(diǎn)的后向指針,以及后向節(jié)點(diǎn)的前向指針,重新 計算后一個定時器的間隔值和定時器的數(shù)目;而后返回調(diào)用模塊。
步驟105對超時隊列中的定時器進(jìn)行處理,根據(jù)定時器的注冊狀態(tài),分別 向注冊模塊發(fā)送消息或進(jìn)行函數(shù)回調(diào)。
步驟106對于周期性定時器,超時后自動再注冊到鏈表中,否則釋放定時 器;然后回到步驟103,在下一個Tick重復(fù)步驟103至步驟106。
在定時器管理過程中,還會涉及定時器的修改操作。圖4是本發(fā)明實(shí)現(xiàn)的
定時器修改流程示意圖。圖4中,步驟401首先調(diào)用修改定時器模塊。步驟402 在鏈表中査找要修改的定時器。步驟403判斷是否查到要修改的定時器,如果 査到,則執(zhí)行步驟404;否則,返回調(diào)用模塊。步驟404先將査到的要修改的 定時器注銷;注銷的方法如圖3所示的定時器注銷流程,即將要修改的定時器 從鏈表中刪除,并修改該定時器的前向節(jié)點(diǎn)的后向指針,以及后向節(jié)點(diǎn)的前向 指針,重新計算后一個定時器的間隔值和定時器的數(shù)目。步驟405再將查到的 要修改的定時器注冊到鏈表中,注冊的方法如圖2所示的定時器注冊流程,即 在定時器鏈表中查找第一個比要修改的定時器更晚超時的定時器。然后執(zhí)行步 驟406判斷是否查到符合要求的定時器,如果查到,則執(zhí)行步驟407;否則執(zhí) 行歩驟408。步驟407把要修改的定時器插入到査到的定時器前面,并修改相 應(yīng)的前后向指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。步驟408 在沒査到符合要求的定時器時,把要修改的定時器插入到鏈表尾部,并修改相 應(yīng)的前后向指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。
以上所述,僅為本發(fā)明較佳的具體實(shí)施方式
,但本發(fā)明的保護(hù)范圍并不 局限于此,任何熟悉本技術(shù)領(lǐng)域的技術(shù)人員在本發(fā)明揭露的技術(shù)范圍內(nèi),可 輕易想到的變化或替換,都應(yīng)涵蓋在本發(fā)明的保護(hù)范圍之內(nèi)。因此,本發(fā)明 的保護(hù)范圍應(yīng)該以權(quán)利要求的保護(hù)范圍為準(zhǔn)。
權(quán)利要求
1、一種嵌入式系統(tǒng)定時器的管理方法,其特征是所述方法包括下列步驟步驟1創(chuàng)建一個管理定時器的雙向鏈表;在雙向鏈表中,定時器的管理方式包括在鏈表中注冊定時器、在鏈表中注銷定時器和在鏈表中修改定時器;定時器的最小粒度為1個TICK;步驟2當(dāng)使用模塊需要定時器時,在鏈表中注冊一個定時器;步驟3在一個TICK到時的時候,從鏈表的頭部開始檢查定時器的超時情況,直到第一個未超時的定時器;步驟4將所有超時的定時器從雙向鏈表中注銷,加入到超時隊列中;步驟5對超時隊列中的定時器進(jìn)行處理,根據(jù)定時器的注冊狀態(tài),分別向注冊模塊發(fā)送消息或進(jìn)行函數(shù)回調(diào);步驟6對于周期性定時器,超時后自動再注冊到鏈表中,否則釋放定時器;然后回到步驟3,在下一個Tick重復(fù)步驟3至步驟6。
2、 根據(jù)權(quán)利要求1所述的一種嵌入式系統(tǒng)定時器的管理方法,其特征是所述在鏈表中注冊定時器的方法,是按照定時器超時的先后順序,向鏈表中插入定時器;其具體步驟包括步驟ll:調(diào)用注冊定時器模塊;步驟12:申請一個新的定時器結(jié)構(gòu)節(jié)點(diǎn)空間;步驟13:査看定時器鏈表;步驟14:判斷鏈表是否為空,如果為空,則執(zhí)行步驟15;否則,執(zhí)行步驟16;步驟15:把當(dāng)前定時器插入鏈表,并修改相應(yīng)的前后向指針、定時器個數(shù)和 定時器間隔值,然后返回調(diào)用模塊; 步驟16:從定時器鏈表中査找第一個比要注冊的定時器更晚超時的定時器; 步驟17:如果查到,則執(zhí)行步驟18;否則,執(zhí)行步驟19;步驟18:把要注冊的定時器插入到查到的定時器前面,并修改相應(yīng)的前后向 指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊;步驟19:把要注冊的定時器插入到鏈表尾部,并修改相應(yīng)的前后向指針、定 時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。
3、 根據(jù)權(quán)利要求1所述的一種嵌入式系統(tǒng)定時器的管理方法,其特征是所 述在鏈表中注銷定時器的方法,包括下列步驟步驟21:調(diào)用注銷定時器模塊; 步驟22:在鏈表中查找要注銷的定時器;步驟23:判斷是否查到要注銷的定時器,如果查到,則執(zhí)行步驟24;否則, 返回調(diào)用模塊;步驟24:將要注銷的定時器從鏈表中刪除,并修改要注銷的定吋器的前向節(jié)點(diǎn)的后向指針,以及后向節(jié)點(diǎn)的前向指針,重新計算后一個定時器的間隔值和定時器的數(shù)目;而后返回調(diào)用模塊。
4、 根據(jù)權(quán)利要求1所述的一種嵌入式系統(tǒng)定時器的管理方法,其特征是所 述在鏈表中修改定時器的方法,包括下列步驟步驟31:調(diào)用修改定時器模塊; 步驟32:在鏈表中査找要修改的定時器;步驟33:判斷是否査到要修改的定時器,如果査到,則執(zhí)行步驟34;否則, 返回調(diào)用模塊;步驟34:先將查到的要修改的定時器注銷;方法是將要修改的定時器從鏈表 中刪除,并修改該定時器的前向節(jié)點(diǎn)的后向指針,以及后向節(jié)點(diǎn)的前向指針,重 新計算后一個定時器的間隔值和定時器的數(shù)目;步驟35:再將查到的要修改的定時器注冊到鏈表中,方法是在定時器鏈表中 查找第一個比要修改的定時器更晚超時的定時器;步驟36:判斷是否查到符合要求的定時器,如果査到,則執(zhí)行步驟37;否 則執(zhí)行步驟38;步驟37:把要修改的定時器插入到査到的定時器前面,并修改相應(yīng)的前后向 指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊;步驟38:把要修改的定時器插入到鏈表尾部,并修改相應(yīng)的前后向指針、定時器個數(shù)和定時器間隔值,然后返回調(diào)用模塊。
5、根據(jù)權(quán)利要求1所述的一種嵌入式系統(tǒng)定時器的管理方法,其特征是所述從鏈表的頭部開始檢査定時器的超時情況,直到第一個未超時的定時器,其方法是,將鏈表中的第一個定時器的時間差值減i,如果結(jié)果不等于o說明無超時定時器;如果結(jié)果等于0,則繼續(xù)查找下一個時間差值為0的定時器,直到最后 一個不為0的定時器。
全文摘要
本發(fā)明公開了嵌入式系統(tǒng)定時器管理技術(shù)領(lǐng)域中的一種嵌入式系統(tǒng)定時器的管理方法。其技術(shù)方案是,創(chuàng)建一個管理定時器的雙向鏈表;定時器的最小粒度為1個TICK;在鏈表中注冊定時器;在每一個TICK到時的時候,從鏈表的頭部開始檢查定時器的超時情況,直到第一個未超時的定時器;將所有超時的定時器從雙向鏈表中注銷;對于注銷的定時器,根據(jù)其注冊狀態(tài),分別向注冊模塊發(fā)送消息或進(jìn)行函數(shù)回調(diào);對于周期性定時器,超時后自動再注冊到鏈表中,否則釋放定時器。由于采用雙向鏈表進(jìn)行管理,定時器在注冊時申請內(nèi)存,注銷時釋放內(nèi)存,內(nèi)存開銷由當(dāng)前的定時器數(shù)目來決定,有效節(jié)約了系統(tǒng)內(nèi)存。
文檔編號G06F9/46GK101359294SQ200810223929
公開日2009年2月4日 申請日期2008年10月9日 優(yōu)先權(quán)日2008年10月9日
發(fā)明者單洪政, 隋平禮 申請人:北京佳訊飛鴻電氣股份有限公司