新聞中心

μC/OS-II的時間管理

作者: 時間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

程序清單 L5.2 OSTimeDlyHMSM().

INT8UOSTimeDlyHMSM(INT8Uhours,INT8Uminutes,INT8Useconds,INT16U

milli)

{

INT32Uticks;

INT16Uloops;

if(hours>0|| minutes>0|| seconds>0|| milli>0){(1)

if(minutes>59){

return(OS_TIME_INVALID_MINUTES);

}

if(seconds>59){

return(OS_TIME_INVALID_SECONDS);

}

If(milli>999){

return(OS_TIME_INVALID_MILLI);

}

ticks=(INT32U)hours*3600L*OS_TICKS_PER_SEC(2)

+(INT32U)minutes*60L*OS_TICKS_PER_SEC

+(INT32U)seconds*OS_TICKS_PER_SEC

+OS_TICKS_PER_SEC*((INT32U)milli

+500L/OS_TICKS_PER_SEC)/1000L;(3)

loops=ticks/65536L;(4)

ticks=ticks%65536L;(5)

OSTimeDly(ticks);(6)

while(loops>0){(7)

OSTimeDly(32768);(8)

OSTimeDly(32768);

loops--;

}

return(OS_NO_ERR);

}else{

return(OS_TIME_ZERO_DLY);(9)

}

}

由于OSTimeDlyHMSM()的具體實(shí)現(xiàn)方法,用戶不能結(jié)束延時調(diào)用OSTimeDlyHMSM()要求延時超過65535個節(jié)拍的任務(wù)。換句話說,如果時鐘節(jié)拍的頻率是100Hz,用戶不能讓調(diào)用OSTimeDlyHMSM(0,10,55,350)或更長延遲時間的任務(wù)結(jié)束延時。

5.2讓處在延時期的任務(wù)結(jié)束延時,OSTimeDlyResume()

μC/OS-Ⅱ允許用戶結(jié)束延時正處于延時期的任務(wù)。延時的任務(wù)可以不等待延時期滿,而是通過其它任務(wù)取消延時來使自己處于就緒態(tài)。這可以通過調(diào)用OSTimeDlyResume()和指定要恢復(fù)的任務(wù)的優(yōu)先級來完成。實(shí)際上,OSTimeDlyResume()也可以喚醒正在等待事件(參看第六章——任務(wù)間的通訊和同步)的任務(wù),雖然這一點(diǎn)并沒有提到過。在這種情況下,等待事件發(fā)生的任務(wù)會考慮是否終止等待事件。

OSTimeDlyResume()的代碼如程序清單L5.3所示,它首先要確保指定的任務(wù)優(yōu)先級有效[L5.3(1)]。 接著, OSTimeDlyResume()要確認(rèn)要結(jié)束延時的任務(wù)是確實(shí)存在的[L5.3(2)]。

如果任務(wù)存在, OSTimeDlyResume()會檢驗(yàn)任務(wù)是否在等待延時期滿[L5.3(3)]。 只要OS_TCB

域中的OSTCBDly包含非0值就表明任務(wù)正在等待延時期滿,因?yàn)槿蝿?wù)調(diào)用了OSTimeDly(),OSTimeDlyHMSM()或其它在第六章中所描述的PEND函數(shù)。然后延時就可以通過強(qiáng)制命令OSTCBDly為0來取消[L5.3(4)]。延時的任務(wù)有可能已被掛起了,這樣的話,任務(wù)只有在沒有被掛起的情況下才能處于就緒狀態(tài)[L5.3(5)]。當(dāng)上面的條件都滿足后,任務(wù)就會被放在就緒表中[L5.3(6)]。這時,OSTimeDlyResume()會調(diào)用任務(wù)調(diào)度程序來看被恢復(fù)的任務(wù)是否擁有比當(dāng)前任務(wù)更高的優(yōu)先級[L5.3(7)]。這會導(dǎo)致任務(wù)的切換。

程序清單 L5.3 恢復(fù)正在延時的任務(wù)

INT8UOSTimeDlyResume(INT8Uprio)

{

OS_TCB*ptcb;

if(prio>=OS_LOWEST_PRIO){(1)

return(OS_PRIO_INVALID);

}

OS_ENTER_CRITICAL();

ptcb=(OS_TCB*)OSTCBPrioTbl[prio];

if(ptcb!=(OS_TCB*)0){(2)

if(ptcb->OSTCBDly!=0){(3)

ptcb->OSTCBDly=0;(4)

if(!(ptcb->OSTCBStatOS_STAT_SUSPEND)){(5)

OSRdyGrp|=ptcb->OSTCBBitY;(6)

OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;

OS_EXIT_CRITICAL();

OSSched();(7)

}else{

OS_EXIT_CRITICAL();

}

return(OS_NO_ERR);

}else{

OS_EXIT_CRITICAL();

return(OS_TIME_NOT_DLY);

}

}else{

OS_EXIT_CRITICAL();

return(OS_TASK_NOT_EXIST);

}

}

注意,用戶的任務(wù)有可能是通過暫時等待信號量、郵箱或消息隊(duì)列來延時自己的(參看第六章)。可以簡單地通過控制信號量、郵箱或消息隊(duì)列來恢復(fù)這樣的任務(wù)。這種情況存在的唯一問題是它要求用戶分配事件控制塊(參看6.00),因此用戶的應(yīng)用程序會多占用一些RAM。

5.3系統(tǒng)時間,OSTimeGet()和 OSTimeSet()

無論時鐘節(jié)拍何時發(fā)生,μC/OS-Ⅱ都會將一個32位的計(jì)數(shù)器加1。這個計(jì)數(shù)器在用戶調(diào)用OSStart()初始化多任務(wù)和4,294,967,295個節(jié)拍執(zhí)行完一遍的時候從0開始計(jì)數(shù)。在時鐘節(jié)拍的頻率等于100Hz的時候,這個32位的計(jì)數(shù)器每隔497天就重新開始計(jì)數(shù)。用戶可以通過調(diào)用OSTimeGet()來獲得該計(jì)數(shù)器的當(dāng)前值。也可以通過調(diào)用OSTimeSet()來改變該計(jì)數(shù)器的值。OSTimeGet()和OSTimeSet()兩個函數(shù)的代碼如程序清單L5.4所示。注意,

在訪問OSTime的時候中斷是關(guān)掉的。這是因?yàn)樵诖蠖鄶?shù)8位處理器上增加和拷貝一個32位的數(shù)都需要數(shù)條指令,這些指令一般都需要一次執(zhí)行完畢,而不能被中斷等因素打斷。

程序清單 L5.4 得到和改變系統(tǒng)時間

INT32UOSTimeGet(void)

{

INT32Uticks;

OS_ENTER_CRITICAL();

ticks=OSTime;

OS_EXIT_CRITICAL();

return(ticks);

}

voidOSTimeSet(INT32Uticks)

{

OS_ENTER_CRITICAL();

OSTime=ticks;

OS_EXIT_CRITICAL();

}


上一頁 1 2 下一頁

關(guān)鍵詞:

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉