當(dāng)有定時器定時完成,把定時器優(yōu)先級寫入軟件定時器就緒表中,并根據(jù)就緒表前后的值判斷時候發(fā)送信號量OSTmrSemSignal,以激活回調(diào)函數(shù)任務(wù)。任務(wù)OSTmr_Task的流程如圖1所示。
?
圖1 OSTmr_Task的流程
把定時器優(yōu)先級寫入定時器就緒表的代碼如下所示:
if (OSTmrTime == ptmr?>OSTmrMatch) {
prio = ptmr?>OSTmrPrio;
pfnct =OSTmrCall[prio].OSTmrCallback;
if (pfnct != (OS_TMR_CALLBACK)0) { /*加入定時器回調(diào)函數(shù)就緒表*/
OSTmrRdyGrp|= (INT8U)(1 《 (INT8U)(prio 》 0x03));
OSTmrRdyTbl[prio >> 0x03]|= (INT8U)(1 《 (INT8U)(prio & 0x07));
}
}
2.2.3 對定時器停止函數(shù)OSTmrStop()的修改
函數(shù)OSTmrStop只需修改與回調(diào)函數(shù)執(zhí)行相關(guān)的部分即可,例如,case OS_TMR_OPT_CALLBACK_ARG: 部分的代碼如下:
case OS_TMR_OPT_CALLBACK_ARG:
prio = ptmr?>OSTmrPrio;
pfnct = OSTmrCall[prio].OSTmrCallback;
if (pfnct != (OS_TMR_CALLBACK)0) {
……/*prio加入定時器就緒表*/
OSTmrCall[prio].OSTmrCallbackArg =(void *)callback_arg;
OSSemPost(OSTmrSemCallback); /*發(fā)送回調(diào)函數(shù)執(zhí)行信號量*/
}else {
*perr = OS_ERR_TMR_NO_CALLBACK;
}
而case OS_TMR_OPT_CALLBACK:部分的代碼同上,只是回調(diào)函數(shù)的參數(shù)不需要重新賦值。
2.2.4 回調(diào)函數(shù)任務(wù)OSTmr_TaskCallback()
在源文件tmr.c中加入回調(diào)函數(shù)任務(wù)OSTmr_TaskCallback(),根據(jù)定時器就緒表中的優(yōu)先級執(zhí)行相應(yīng)回調(diào)函數(shù),回調(diào)函數(shù)任務(wù)的結(jié)構(gòu)如下所示:
static voidOSTmr_TaskCallback(void *p_arg) {……/*變量定義*/
for (;;){//請求信號量OSTmrSemCallback
OSSemPend(OSTmrSemCallback, 0, &err);
OSTmr_Lock();/*定時器上鎖*/
while (OSTmrRdyGrp) {
……/*從定時器就緒表中得到最高優(yōu)先級的定時器回調(diào)函數(shù)*/
……/*刪除就緒表中的占有位*/
OSTmr_Unlock(); /*定時器上鎖*/
pfnct = OSTmrCall[prio].OSTmrCallback;
(*pfnct)((void *)(OSTmrCall[prio].OSTmr),OSTmrCall[prio].OSTmrCallbackArg); /*執(zhí)行回調(diào)函數(shù)*/
OSTmr_Lock(); /*定時器上鎖*/
}
OSTmr_Unlock();/*定時器解鎖*/
}
}
由以上代碼可知,訪問就緒表時定時器上鎖,而執(zhí)行回調(diào)函數(shù)時處于定時器解鎖狀態(tài)。如果回調(diào)函數(shù)執(zhí)行時間較長,在下一個軟件定時器節(jié)拍到來時,定時器掃描任務(wù)可以得到及時的執(zhí)行,當(dāng)前回調(diào)函數(shù)執(zhí)行完成后,可以及時得執(zhí)行就緒表中最高優(yōu)先級定時器的回調(diào)函數(shù)。由此可以看出,高優(yōu)先級定時器的回調(diào)函數(shù)得到及時執(zhí)行,系統(tǒng)的實時性提高。
實驗測試發(fā)現(xiàn),在回調(diào)函數(shù)任務(wù)OSTmr_TaskCallback中,使用任務(wù)調(diào)度上鎖與解鎖比使用定時器上鎖與解鎖(即信號量的請求)執(zhí)行速度快一些。畢竟回調(diào)函數(shù)任務(wù)的優(yōu)先級很高(一般僅次于定時器掃描任務(wù)OSTmr_Task的優(yōu)先級),所以使用任務(wù)調(diào)度鎖定比定時器鎖定要好一些。當(dāng)然,還可以使用開關(guān)中斷的方式對就緒表進行訪問,可以根據(jù)實際情況選擇使用哪種方式。
電子發(fā)燒友App


























評論