os系统
任務(wù)延時(shí)函數(shù)OSTimeDly
功能:調(diào)用該函數(shù)的任務(wù)將自己延時(shí)一段時(shí)間并執(zhí)行一次任務(wù)調(diào)度,一旦規(guī)定的延時(shí)時(shí)間完成或有其它的任務(wù)通過調(diào)用OSTimeDlyResume()取消了延時(shí),調(diào)用OSTimeDly()函數(shù)的任務(wù)馬上進(jìn)入就緒狀態(tài)(前提是先將任務(wù)調(diào)度后執(zhí)行的任務(wù)執(zhí)行到程序尾,且調(diào)用OSTimeDly的任務(wù)此時(shí)優(yōu)先級最高)。
3.2.3 任務(wù)延時(shí)函數(shù)OSTimeDly
任務(wù)延時(shí)函數(shù)OSTimeDly用于阻塞任務(wù)一定時(shí)間,這個(gè)時(shí)間以參數(shù)的形式給出。如果這個(gè)參數(shù)的值是N,那么在N個(gè)時(shí)間片(時(shí)鐘滴答)之后,任務(wù)才能回到就緒態(tài)獲得繼續(xù)運(yùn)行的機(jī)會。如果參數(shù)的值是0,就不會阻塞任務(wù)。任務(wù)延時(shí)函數(shù)OSTimeDly的代碼分析如程序3.4所示。
程序3.4 任務(wù)延時(shí)函數(shù)OSTimeDly代碼分析
voidOSTimeDly(INT32Uticks)
{
INT8Uy;
if(OSIntNesting>0u){/*中斷服務(wù)程序不能延時(shí)*/
return;
}
if(OSLockNesting>0u){/*如果調(diào)度器被上鎖不能延時(shí),因?yàn)檠訒r(shí)后就要進(jìn)行調(diào)度*/
return;
}
if(ticks>0u){/*如果延時(shí)時(shí)間大于0才會進(jìn)行延時(shí)*/
OS_ENTER_CRITICAL();
/*在就緒表和就緒組中取消當(dāng)前任務(wù)的就緒標(biāo)志*/
y=OSTCBCur->OSTCBY;
OSRdyTbl[y]&=(OS_PRIO)~OSTCBCur->OSTCBBitX;
if(OSRdyTbl[y]==0u){
OSRdyGrp&=(OS_PRIO)~OSTCBCur->OSTCBBitY;
}
/*給任務(wù)塊的OSTCBDly項(xiàng)賦值延時(shí)時(shí)間*/
OSTCBCur->OSTCBDly=ticks;/*向任務(wù)控制塊TCB裝載延時(shí)時(shí)間*/
OS_EXIT_CRITICAL();
OS_Sched();/*進(jìn)行一次任務(wù)調(diào)度*/
}
}
本段代碼層次清晰且比較簡單。OSLockNesting是調(diào)度鎖,也就是說,如果OSLockNesting>0,那么不允許進(jìn)行任務(wù)調(diào)度。因?yàn)槿蝿?wù)延時(shí)的時(shí)候要中止當(dāng)前任務(wù)的執(zhí)行,所以要進(jìn)行調(diào)度,因此在調(diào)度鎖有效的情況下是不能執(zhí)行任務(wù)延時(shí)的。如果延時(shí)時(shí)間大于0,那么就要進(jìn)行一次任務(wù)調(diào)度,將當(dāng)前的任務(wù)的就緒標(biāo)志取消,也就是對就緒表和就緒組的相關(guān)操作。之后將延時(shí)時(shí)間給任務(wù)塊的OSTCBDly項(xiàng)以對延時(shí)進(jìn)行計(jì)數(shù)。操作系統(tǒng)在每個(gè)時(shí)鐘中斷都要對每個(gè)OSTCBDly大于0的任務(wù)塊的OSTCBDly進(jìn)行減1操作和進(jìn)行調(diào)度,那么當(dāng)任務(wù)的延遲時(shí)間到了的時(shí)候(OSTCBDly為0)就可以恢復(fù)到就緒態(tài)。
需要注意的是,如果將任務(wù)延時(shí)1個(gè)時(shí)間片,調(diào)用OSTimeDly(1),會不會產(chǎn)生正確的結(jié)果呢?回答是否定的。這是因?yàn)槿蝿?wù)在調(diào)用時(shí)間延時(shí)函數(shù)的時(shí)候可能已經(jīng)馬上就要發(fā)生時(shí)鐘中斷了,那么設(shè)置OSTCBDly的值為1,想延時(shí)10ms,然后系統(tǒng)切換到一個(gè)新的任務(wù)運(yùn)行。在可能極短的時(shí)間,如0.5ms的時(shí)間后就進(jìn)入時(shí)鐘中斷服務(wù)程序,立刻將OSTCBDly的值減到0了。調(diào)度器在調(diào)度的時(shí)候就會恢復(fù)這個(gè)才延時(shí)了0.5ms的任務(wù)執(zhí)行。可見,OSTimeDly的誤差最大應(yīng)該就是1個(gè)時(shí)間片的長度,OSTCBDly(1)不會剛好延時(shí)10ms,如果真的需要延時(shí)1個(gè)時(shí)間片,最好調(diào)用OSTCBDly(2)。
任務(wù)延時(shí)函數(shù)OSTimeDly的流程如圖3.3所示。
總結(jié)
- 上一篇: 辉煌水龙头价目表
- 下一篇: 互联网毒瘤——内容农场