新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > μC/OS-II的任務(wù)之間的通訊與同步

μC/OS-II的任務(wù)之間的通訊與同步

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

OSMboxCreate()函數(shù)的返回值是一個指向事件控制塊的指針[L6.14(3)]。這個指針在調(diào)用函數(shù)OSMboxPend(),OSMboxPost(),OSMboxAccept()和OSMboxQuery()時使用。因此,該指針可以看作是對應(yīng)郵箱的句柄。值得注意的是,如果系統(tǒng)中已經(jīng)沒有事件控制塊可用,函數(shù)OSMboxCreate()將返回一個NULL指針。

郵箱一旦建立,是不能被刪除的。比如,如果有任務(wù)正在等待一個郵箱的信息,這時刪除該郵箱,將有可能產(chǎn)生災(zāi)難性的后果。

程序清單L6.14建立一個郵箱

OS_EVENT*OSMboxCreate(void*msg)

{

OS_EVENT*pevent;

OS_ENTER_CRITICAL();

pevent=OSEventFreeList;

if(OSEventFreeList!=(OS_EVENT*)0){

OSEventFreeList=(OS_EVENT*)OSEventFreeList->OSEventPtr;

}

OS_EXIT_CRITICAL();

if(pevent!=(OS_EVENT*)0){

pevent->OSEventType=OS_EVENT_TYPE_MBOX;(1)

pevent->OSEventPtr=msg;(2)

OSEventWaitListInit(pevent);

}

return(pevent);(3)

}

6.7.2 等待一個郵箱中的消息,OSMboxPend()

程序清單L6.15是OSMboxPend()函數(shù)的源代碼。 同樣, 它和OSSemPend()也很相似,因此,在這里只講述其中的不同之處。OSMboxPend()首先檢查該事件控制塊是由 OSMboxCreate()函數(shù)建立的[L6.15(1)]。當(dāng).OSEventPtr域是一個非NULL的指針時,說明該郵箱中有可用的消息[L6.15(2)]。這種情況下,OSMboxPend()函數(shù)將該域的值復(fù)制到局部變量msg中,然后將.OSEventPtr置為NULL[L6.15(3)]。這正是我們所期望的,也是執(zhí)行 OSMboxPend()函數(shù)最快的路徑。

如果此時郵箱中沒有消息是可用的(.OSEventPtr域是NULL指針),OSMboxPend()函數(shù)檢查它的調(diào)用者是否是中斷服務(wù)子程序[L6.15(4)]。象OSSemPend()函數(shù)一樣,不能在中斷服務(wù)子程序中調(diào)用OSMboxPend(),因為中斷服務(wù)子程序是不能等待的。這里的代碼同樣是為了以防萬一。但是,如果郵箱中有可用的消息,即使從中斷服務(wù)子程序中調(diào)用OSMboxPend()函數(shù),也一樣是成功的。

如果郵箱中沒有可用的消息,OSMboxPend()的調(diào)用任務(wù)就被掛起,直到郵箱中有了消息或者等待超時[L6.15(5)]。當(dāng)有其它的任務(wù)向該郵箱發(fā)送了消息后(或者等待時間超時),這時,該任務(wù)再一次成為最高優(yōu)先級任務(wù),OSSched()返回。這時,OSMboxPend()函數(shù)要檢查是否有消息被放到該任務(wù)的任務(wù)控制塊中[L6.15(6)]。如果有,那么該次函數(shù)調(diào)用成功,對應(yīng)的消息被返回到調(diào)用函數(shù)。

程序清單L6.15等待一個郵箱中的消息

void*OSMboxPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err)

{

void*msg;

OS_ENTER_CRITICAL();

if(pevent->OSEventType!=OS_EVENT_TYPE_MBOX){(1)

OS_EXIT_CRITICAL();

*err=OS_ERR_EVENT_TYPE;

return((void*)0);

}

msg=pevent->OSEventPtr;

if(msg!=(void*)0){(2)

pevent->OSEventPtr=(void*)0;(3)

OS_EXIT_CRITICAL();

*err=OS_NO_ERR;

}elseif(OSIntNesting>0){(4)

OS_EXIT_CRITICAL();

*err=OS_ERR_PEND_ISR;

}else{

OSTCBCur->OSTCBStat|=OS_STAT_MBOX;(5)

OSTCBCur->OSTCBDly=timeout;

OSEventTaskWait(pevent);

OS_EXIT_CRITICAL();

OSSched();

OS_ENTER_CRITICAL();

if((msg=OSTCBCur->OSTCBMsg)!=(void*)0){(6)

OSTCBCur->OSTCBMsg=(void*)0;

OSTCBCur->OSTCBStat=OS_STAT_RDY;

OSTCBCur->OSTCBEventPtr=(OS_EVENT*)0;

OS_EXIT_CRITICAL();

*err=OS_NO_ERR;

}elseif(OSTCBCur->OSTCBStatOS_STAT_MBOX){(7)

OSEventTO(pevent);(8)

OS_EXIT_CRITICAL();

msg=(void*)0;(9)

*err=OS_TIMEOUT;

}else{

msg=pevent->OSEventPtr;(10)

pevent->OSEventPtr=(void*)0;

(11)

OSTCBCur->OSTCBEventPtr=(OS_EVENT*)0;(12)

OS_EXIT_CRITICAL();

*err=OS_NO_ERR;

}

}

return(msg);

}

在OSMboxPend()函數(shù)中,通過檢查任務(wù)控制塊中的.OSTCBStat域中的OS_STAT_MBOX位,可以知道是否等待超時。如果該域被置1,說明任務(wù)等待已經(jīng)超時[L6.15(7)]。這時,通過調(diào)用函數(shù)OSEventTo()可以將任務(wù)從郵箱的等待列表中刪除[L6.15(8)]。因為此時郵箱中沒有消息,所以返回的指針是NULL[L6.15(9)]。如果OS_STAT_MBOX位沒有被置1,說明所等待的消息已經(jīng)被發(fā)出。OSMboxPend()的調(diào)用函數(shù)得到指向消息的指針[L6.15(10)]。此后,OSMboxPend()函數(shù)通過將郵箱事件控制塊的.OSEventPtr域置為NULL清空該郵箱,并且要將任務(wù)任務(wù)控制塊中指向郵箱事件控制塊的指針刪除[L6.15(12)]。

6.7.3 發(fā)送一個消息到郵箱中,OSMboxPost()

程序清單L6.16是OSMboxPost()函數(shù)的源代碼。檢查了事件控制塊是否是一個郵箱后[L6.16(1)],OSMboxPost()函數(shù)還要檢查是否有任務(wù)在等待該郵箱中的消息[L6.16(2)]。如果事件控制塊中的OSEventGrp域包含非零值,就暗示著有任務(wù)在等待該消息。這時,調(diào)用OSEventTaskRdy()將其中的最高優(yōu)先級任務(wù)從等待列表中刪除[見6.02節(jié),使一個任務(wù)進入就緒狀態(tài),OSEventTaskRdy()][L6.16(3)],加入系統(tǒng)的就緒任務(wù)列表中,準備運行。然后,調(diào)用OSSched()函數(shù)[L6.16(4)],檢查該任務(wù)是否是系統(tǒng)中最高優(yōu)先級的就緒任務(wù)。如果是,執(zhí)行任

務(wù)切換[僅當(dāng)OSMboxPost()函數(shù)是由任務(wù)調(diào)用時],該任務(wù)得以執(zhí)行。如果該任務(wù)不是最高優(yōu)先

級的任務(wù),OSSched()返回,OSMboxPost()的調(diào)用函數(shù)繼續(xù)執(zhí)行。如果沒有任何任務(wù)等待該消息,

指向消息的指針就被保存到郵箱中[L6.16(6)](假設(shè)此時郵箱中的指針不是非NULL的[L6.16(5)])。這樣,下一個調(diào)用OSMboxPend()函數(shù)的任務(wù)就可以立刻得到該消息了。

注意,如果OSMboxPost()函數(shù)是從中斷服務(wù)子程序中調(diào)用的,那么,這時并不發(fā)生上下文的切換。如果需要,中斷服務(wù)子程序引起的上下文切換只發(fā)生在中斷嵌套的最外層中斷服務(wù)子程序?qū)SIntExit()函數(shù)的調(diào)用時(見3.09節(jié),μC/OS-II中的中斷)。



關(guān)鍵詞:

評論


相關(guān)推薦

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

關(guān)閉