新聞中心

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

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

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

另外,消息隊(duì)列一旦建立就不能再刪除了。試想,如果有任務(wù)正在等待某個(gè)消息隊(duì)列中的消息,而此時(shí)又刪除該消息隊(duì)列,將是很危險(xiǎn)的。

程序清單L6.21建立一個(gè)消息隊(duì)列

OS_EVENT*OSQCreate(void**start,INT16Usize)

{

OS_EVENT*pevent;

OS_Q*pq;

OS_ENTER_CRITICAL();

pevent=OSEventFreeList;(1)

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

OSEventFreeList=(OS_EVENT*)OSEventFreeList->OSEventPtr;(2)

}

OS_EXIT_CRITICAL();

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

OS_ENTER_CRITICAL();

pq=OSQFreeList;(3)

if(OSQFreeList!=(OS_Q*)0){

OSQFreeList=OSQFreeList->OSQPtr;

}

OS_EXIT_CRITICAL();

if(pq!=(OS_Q*)0){

pq->OSQStart=start;(4)

pq->OSQEnd=start[size];

pq->OSQIn=start;

pq->OSQOut=start;

pq->OSQSize=size;

pq->OSQEntries=0;

pevent->OSEventType=OS_EVENT_TYPE_Q;(5)

pevent->OSEventPtr=pq;(6)

OSEventWaitListInit(pevent);(7)

}else{

OS_ENTER_CRITICAL();

pevent->OSEventPtr=(void*)OSEventFreeList;(8)

OSEventFreeList=pevent;

OS_EXIT_CRITICAL();

pevent=(OS_EVENT*)0;

}

}

return(pevent);(9)

}

6.8.2 等待一個(gè)消息隊(duì)列中的消息,OSQPend()

程序清單L6.22是OSQPend()函數(shù)的源代碼。OSQPend()函數(shù)首先檢查事件控制塊是否是由OSQCreate()函數(shù)建立的[L6.22(1)],接著,該函數(shù)檢查消息隊(duì)列中是否有消息可用(即.OSQEntries是否大于0) [L6.22(2)]。 如果有, OSQPend()函數(shù)將指向消息的指針復(fù)制到msg變量中, 并讓.OSQOut指針指向隊(duì)列中的下一個(gè)單元[L6.22(3)],然后將隊(duì)列中的有效消息數(shù)減1[L6.22(4)]。因?yàn)橄㈥?duì)列是一個(gè)循環(huán)的緩沖區(qū),OSQPend()函數(shù)需要檢查.OSQOut是否超過了

隊(duì)列中的最后一個(gè)單元[L6.22(5)]。當(dāng)發(fā)生這種越界時(shí),就要將.OSQOut重新調(diào)整到指向隊(duì)列的起始單元[L6.22(6)]。這是我們調(diào)用OSQPend()函數(shù)時(shí)所期望的,也是執(zhí)行OSQPend()函數(shù)最快的路徑。

程序清單L6.22在一個(gè)消息隊(duì)列中等待一條消息

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

{

void*msg;

OS_Q*pq;

OS_ENTER_CRITICAL();

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

OS_EXIT_CRITICAL();

*err=OS_ERR_EVENT_TYPE;

return((void*)0);

}

pq=pevent->OSEventPtr;

if(pq->OSQEntries!=0){(2)

msg=*pq->OSQOut++;(3)

pq->OSQEntries--;(4)

if(pq->OSQOut==pq->OSQEnd){(5)

pq->OSQOut=pq->OSQStart;(6)

}

OS_EXIT_CRITICAL();

*err=OS_NO_ERR;

}elseif(OSIntNesting>0){(7)

OS_EXIT_CRITICAL();

*err=OS_ERR_PEND_ISR;

}else{

OSTCBCur->OSTCBStat|=OS_STAT_Q;(8)

OSTCBCur->OSTCBDly=timeout;

OSEventTaskWait(pevent);

OS_EXIT_CRITICAL();

OSSched();(9)

OS_ENTER_CRITICAL();

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

OSTCBCur->OSTCBMsg=(void*)0;

OSTCBCur->OSTCBStat=OS_STAT_RDY;

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

OS_EXIT_CRITICAL();

*err=OS_NO_ERR;

}elseif(OSTCBCur->OSTCBStatOS_STAT_Q){(12)

OSEventTO(pevent);(13)

OS_EXIT_CRITICAL();

msg=(void*)0;(14)

*err=OS_TIMEOUT;

}else{

msg=*pq->OSQOut++;(15)

pq->OSQEntries--;

if(pq->OSQOut==pq->OSQEnd){

pq->OSQOut=pq->OSQStart;

}

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

OS_EXIT_CRITICAL();

*err=OS_NO_ERR;

}

}

return(msg);(17)

}

如果這時(shí)消息隊(duì)列中沒有消息(.OSEventEntries是0),OSQPend()函數(shù)檢查它的調(diào)用者是否是中斷服務(wù)子程序[L6.22(7)]。象OSSemPend()和OSMboxPend()函數(shù)一樣,不能在中斷服務(wù)子程序中調(diào)用OSQPend(), 因?yàn)橹袛喾?wù)子程序是不能等待的。 但是, 如果消息隊(duì)列中有消息,即使從中斷服務(wù)子程序中調(diào)用OSQPend()函數(shù),也一樣是成功的。

如果消息隊(duì)列中沒有消息,調(diào)用OSQPend()函數(shù)的任務(wù)被掛起[L6.22(8)]。當(dāng)有其它的任

務(wù)向該消息隊(duì)列發(fā)送了消息或者等待時(shí)間超時(shí),并且該任務(wù)成為最高優(yōu)先級(jí)任務(wù)時(shí),OSSched()

返回[L6.22(9)]。這時(shí),OSQPend()要檢查是否有消息被放到該任務(wù)的任務(wù)控制塊中[L6.22(10)]。如果有,那么該次函數(shù)調(diào)用成功,把任務(wù)的任務(wù)控制塊中指向消息隊(duì)列的指針刪除[L6.22(17)],并將對(duì)應(yīng)的消息被返回到調(diào)用函數(shù)[L6.22(17)]。

在OSQPend()函數(shù)中,通過檢查任務(wù)的任務(wù)控制塊中的.OSTCBStat域,可以知道是否等到時(shí)間超時(shí)。如果其對(duì)應(yīng)的OS_STAT_Q位被置1,說明任務(wù)等待已經(jīng)超時(shí)[L6.22(12)]。這時(shí),通過調(diào)用函數(shù)OSEventTo()可以將任務(wù)從消息隊(duì)列的等待任務(wù)列表中刪除[L6.22(13)]。這時(shí),因?yàn)橄㈥?duì)列中沒有消息,所以返回的指針是NULL[L6.22(14)]。

如果任務(wù)控制塊標(biāo)志位中的OS_STAT_Q位沒有被置1,說明有任務(wù)發(fā)出了一條消息。

OSQPend()函數(shù)從隊(duì)列中取出該消息[L6.22(15)]。然后,將任務(wù)的任務(wù)控制中指向事件控制塊的指針刪除[L6.22(16)]。

6.8.3 向消息隊(duì)列發(fā)送一個(gè)消息(FIFO),OSQPost()

程序清單L6.23是OSQPost()函數(shù)的源代碼。在確認(rèn)事件控制塊是消息隊(duì)列后

[L6.23(1)],OSQPost()函數(shù)檢查是否有任務(wù)在等待該消息隊(duì)列中的消息[L6.23(2)]。當(dāng)事件控



關(guān)鍵詞:

評(píng)論


相關(guān)推薦

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

關(guān)閉