μC/OSII中軟件定時器的優(yōu)缺點與改進
μC/OSII具有小巧、性能穩(wěn)定、開源等眾多優(yōu)點,并且μC/OSII大部分用ANSI C語言編寫,系統(tǒng)的移植非常容易。在μC/OSII I2.81及以后的版本中[2],加入了對軟件定時器的支持,使得μC/OSII操作系統(tǒng)更加完善。
本文引用地址:http://m.butianyuan.cn/article/162162.htmμC/OSII是一種基于優(yōu)先級的搶占式操作系統(tǒng),實時性很強。而系統(tǒng)中軟件定時器沒有優(yōu)先級,回調(diào)函數(shù)順序執(zhí)行,這樣就降低了系統(tǒng)的實時性。因此,本文對軟件定時器進行改進,定時器中加入優(yōu)先級,回調(diào)函數(shù)按優(yōu)先級執(zhí)行,從而提高系統(tǒng)的實時性。
1 對軟件定時器的介紹
μC/OSII系統(tǒng)中的時間管理功能包括任務(wù)延時與軟件定時器,而軟件定時器的主要作用是,對函數(shù)周期性或者一次性執(zhí)行的定時,利用軟件定時器控制塊與“定時器輪”管理軟件定時器。定時器控制塊的結(jié)構(gòu)如同任務(wù)控制塊,創(chuàng)建一個定時器時,從空閑定時器控制塊鏈表中得到一個空閑控制塊,并對其賦值。
軟件定時器也需要一個時鐘節(jié)拍驅(qū)動,而這個驅(qū)動一般是硬件實現(xiàn)的,一般使用μC/OSII操作系統(tǒng)中任務(wù)延時的時鐘節(jié)拍來驅(qū)動軟件定時器。每個時鐘節(jié)拍OSTmrCtr(全局變量,初始值為0)增1, 當(dāng)OSTmrCtr的值等于為OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC(此兩者的商決定軟件定時器的頻率)時,調(diào)用函數(shù)OSTmrSignal(),此函數(shù)發(fā)送信號量OSTmrSemSignal(初始值為0,決定軟件定時器掃描任務(wù)OSTmr_Task的運行)。也就是說,對定時器的處理不在時鐘節(jié)拍中斷函數(shù)中進行,而是以發(fā)生信號量的方式激活任務(wù)OSTmr_Task(具有很高的優(yōu)先級)。任務(wù)OSTmr_Task對定時器進行檢測處理,包括定時器定時完成的判斷、回調(diào)函數(shù)的執(zhí)行。
μC/OSII 2.86中與軟件定時器相關(guān)的函數(shù)包括:
?、?軟件定時器內(nèi)部靜態(tài)函數(shù)。獲取與釋放定時器控制塊函數(shù)OSTmr_Alloc()、OSTmr_Free();定時器插入相應(yīng)“時間輪”組函數(shù)OSTmr_Link();從相應(yīng)“時間輪”組中刪除定時器函數(shù)OSTmr_Unlink();軟件定時器任務(wù)初始化函數(shù)OSTmr_InitTask();定時器掃描任務(wù)OSTmr_Task;定時器上鎖與解鎖函數(shù)OSTmr_Lock()與OSTmr_Unlock()(在μC/OSII 2.91中,此兩函數(shù)被任務(wù)調(diào)度鎖定與解鎖函數(shù)代替)。
?、?定時器外部接口函數(shù)。定時器創(chuàng)建與刪除函數(shù)OSTmrCreate()、OSTmrDel();定時器啟動與停止函數(shù)OSTmrStart()、OSTmrStop();定時器剩余時間與當(dāng)前狀態(tài)查詢函數(shù)OSTmrRemainGet()、OSTmrStateGet();軟件定時器的初始化OSTmr_Init();發(fā)送信號量OSTmrSemSignal函數(shù)OSTmrSignal();定時器名稱查詢函數(shù)OSTmrNameGet()。
由于軟件定時器的回調(diào)函數(shù)的執(zhí)行都是在任務(wù)OSTmr_Task中執(zhí)行,如果多個定時器同時定時完成,則在定時器任務(wù)中執(zhí)行多個定時器的回調(diào)函數(shù),因此定時器任務(wù)的執(zhí)行時間不確定。而且定時器回調(diào)函數(shù)是順序執(zhí)行的,如果某個定時器回調(diào)函數(shù)需要盡快執(zhí)行以實現(xiàn)精確定時,就難以實現(xiàn)了。由于各個定時器沒有優(yōu)先級,因此了影響系統(tǒng)的實時性。
2 對軟件定時器的改進
為提高軟件定時器回調(diào)函數(shù)執(zhí)行的實時性,給每個定時器賦予一個優(yōu)先級。當(dāng)定時完成時,并且定時器的回調(diào)函數(shù)不為空,則把定時器的優(yōu)先級寫于軟件定時器就緒表中。任務(wù)OSTmr_Task對相應(yīng)“時間輪”檢查結(jié)束后,如果在掃描各個定時器前軟件定時器就緒表為零而掃描之后不為零,則發(fā)送信號量激活回調(diào)函數(shù)任務(wù)OSTmr_TaskCallback。在此任務(wù)中,回調(diào)函數(shù)根據(jù)軟件定時器就緒表中的優(yōu)先級執(zhí)行相應(yīng)的回調(diào)函數(shù),這樣就提高了系統(tǒng)的實時性。
2.1 對軟件定時器相關(guān)數(shù)據(jù)結(jié)構(gòu)改進
?、?定義結(jié)構(gòu)體OS_TMR_CALL,存儲定時器的回調(diào)函數(shù)、函數(shù)的參數(shù)、定時器指針,形式如下:
typedefstructos_tmr_call {
OS_TMR_CALLBACKOSTmrCallback; /*回調(diào)函數(shù)*/
void *OSTmrCallbackArg;/*回調(diào)函數(shù)指針*/
OS_TMR *OSTmr; /*定時器指針*/
} OS_TMR_CALL;
在頭文件ucos_ii.h中,定義OSTmrCallbackTbl[OS_TMR_CFG_MAX],OS_TMR_CFG_MAX表示系統(tǒng)中配置的軟件定時器數(shù)量。
?、?在軟件定時器控制塊中加入成員變量OSTmrPrio(定時器優(yōu)先級),刪去變量OSTmrCallback(回調(diào)函數(shù))、OSTmrCallbackArg(回調(diào)函數(shù)參數(shù)),為了測試的方便,可暫不刪除這兩個變量。
?、?定義定時器就緒表:
INT8UOSTmrRdyGrp;
INT8UOSTmrRdyTbl[OS_TMR_CFG_MAX/8 + 1];
當(dāng)定時器定時完成時,把定時器優(yōu)先級寫入就緒表,回調(diào)函數(shù)任務(wù)根據(jù)優(yōu)先級執(zhí)行回調(diào)函數(shù)。
?、?定義信號量OSTmrSemCallback(初始值0 ),當(dāng)定時完成后,發(fā)送此信號量,激活回調(diào)函數(shù)任務(wù),以執(zhí)行回調(diào)函數(shù)。
評論