新聞中心

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

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

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

原因掛起了。[見4.07節(jié),掛起一個(gè)任務(wù),OSTaskSuspend(),和4.08節(jié),恢復(fù)一個(gè)任務(wù),

OSTaskResume()]。

另外,.OSEventTaskRdy()函數(shù)要在中斷禁止的情況下調(diào)用。

程序清單L6.6使一個(gè)任務(wù)進(jìn)入就緒狀態(tài)

voidOSEventTaskRdy(OS_EVENT*pevent,void*msg,INT8Umsk)

{

OS_TCB*ptcb;

INT8Ux;

INT8Uy;

INT8Ubitx;

INT8Ubity;

INT8Uprio;

y=OSUnMapTbl[pevent->OSEventGrp];(1)

bity=OSMapTbl[y];(2)

x=OSUnMapTbl[pevent->OSEventTbl[y]];(3)

bitx=OSMapTbl[x];(4)

prio=(INT8U)((y3)+x);(5)

if((pevent->OSEventTbl[y]=~bitx)==0){(6)

pevent->OSEventGrp=~bity;

}

ptcb=OSTCBPrioTbl[prio];(7)

ptcb->OSTCBDly=0;(8)

ptcb->OSTCBEventPtr=(OS_EVENT*)0;(9)

#if(OS_Q_EN(OS_MAX_QS>=2))||OS_MBOX_EN

ptcb->OSTCBMsg=msg;(10)

#else

msg=msg;

#endif

ptcb->OSTCBStat=~msk;(11)

if(ptcb->OSTCBStat==OS_STAT_RDY){(12)

OSRdyGrp|=bity;(13)

OSRdyTbl[y]|=bitx;

}

}

圖F6.4使一個(gè)任務(wù)進(jìn)入就緒狀態(tài)——Figure6.4

6.4 使一個(gè)任務(wù)進(jìn)入等待某事件發(fā)生狀態(tài),OSEventTaskWait()

程序清單L6.7是OSEventTaskWait()函數(shù)的源代碼。當(dāng)某個(gè)任務(wù)要等待一個(gè)事件的發(fā)生時(shí),相應(yīng)事件的OSSemPend(),OSMboxPend()或者OSQPend()函數(shù)會(huì)調(diào)用該函數(shù)將當(dāng)前任務(wù)從就緒任務(wù)表中刪除,并放到相應(yīng)事件的事件控制塊的等待任務(wù)表中。

程序清單L6.7使一個(gè)任務(wù)進(jìn)入等待狀態(tài)

voidOSEventTaskWait(OS_EVENT*pevent)

{

OSTCBCur->OSTCBEventPtr=pevent;(1)

if((OSRdyTbl[OSTCBCur->OSTCBY]=~OSTCBCur->OSTCBBitX)==0){(2)

OSRdyGrp=~OSTCBCur->OSTCBBitY;

}

pevent->OSEventTbl[OSTCBCur->OSTCBY]|=OSTCBCur->OSTCBBitX;(3)

pevent->OSEventGrp|=OSTCBCur->OSTCBBitY;

}

在該函數(shù)中,首先將指向事件控制塊的指針放到任務(wù)的任務(wù)控制塊中[L6.7(1)],接著將任務(wù)從就緒任務(wù)表中刪除[L6.7(2)],并把該任務(wù)放到事件控制塊的等待任務(wù)表中[L6.7(3)]。

6.5 由于等待超時(shí)而將任務(wù)置為就緒態(tài),OSEventTO()

程序清單L6.8是OSEventTO()函數(shù)的源代碼。當(dāng)在預(yù)先指定的時(shí)間內(nèi)任務(wù)等待的事件沒有發(fā)生時(shí),OSTimeTick()函數(shù)會(huì)因?yàn)榈却瑫r(shí)而將任務(wù)的狀態(tài)置為就緒。在這種情況下,事件的OSSemPend(),OSMboxPend()或者OSQPend()函數(shù)會(huì)調(diào)用OSEventTO()來完成這項(xiàng)工作。該函數(shù)負(fù)責(zé)從事件控制塊中的等待任務(wù)列表里將任務(wù)刪除[L6.8(1)],并把它置成就緒狀態(tài)[L6.8(2)]。最后,從任務(wù)控制塊中將指向事件控制塊的指針刪除[L6.8(3)]。用戶應(yīng)當(dāng)注意,調(diào)用OSEventTO()也應(yīng)當(dāng)先關(guān)中斷。

程序清單L6.8因?yàn)榈却瑫r(shí)將任務(wù)置為就緒狀態(tài)

voidOSEventTO(OS_EVENT*pevent)

{

if((pevent->OSEventTbl[OSTCBCur->OSTCBY]=~OSTCBCur->OSTCBBitX) ==0)

{ (1)

pevent->OSEventGrp=~OSTCBCur->OSTCBBitY;

}

OSTCBCur->OSTCBStat=OS_STAT_RDY;(2)

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

}

6.6 信號(hào)量

μC/OS-II中的信號(hào)量由兩部分組成:一個(gè)是信號(hào)量的計(jì)數(shù)值,它是一個(gè)16位的無符號(hào)整數(shù) (0到65,535之間) ; 另一個(gè)是由等待該信號(hào)量的任務(wù)組成的等待任務(wù)表。 用戶要在OS_CFG.H中將OS_SEM_EN開關(guān)量常數(shù)置成1,這樣μC/OS-II才能支持信號(hào)量。

在使用一個(gè)信號(hào)量之前, 首先要建立該信號(hào)量, 也即調(diào)用OSSemCreate()函數(shù)(見下一節(jié)) ,

對(duì)信號(hào)量的初始計(jì)數(shù)值賦值。該初始值為0到65,535之間的一個(gè)數(shù)。如果信號(hào)量是用來表示一個(gè)或者多個(gè)事件的發(fā)生, 那么該信號(hào)量的初始值應(yīng)設(shè)為0。 如果信號(hào)量是用于對(duì)共享資源的訪問,那么該信號(hào)量的初始值應(yīng)設(shè)為1(例如,把它當(dāng)作二值信號(hào)量使用)。最后,如果該信號(hào)量是用來表示允許任務(wù)訪問n個(gè)相同的資源,那么該初始值顯然應(yīng)該是n,并把該信號(hào)量作為一個(gè)可計(jì)數(shù)的信號(hào)量使用。

μC/OS-II提供了5個(gè)對(duì)信號(hào)量進(jìn)行操作的函數(shù)。它們是:OSSemCreate(),OSSemPend(),

OSSemPost(),OSSemAccept()和OSSemQuery()函數(shù)。圖F6.5說明了任務(wù)、中斷服務(wù)子程序和

信號(hào)量之間的關(guān)系。圖中用鑰匙或者旗幟的符號(hào)來表示信號(hào)量:如果信號(hào)量用于對(duì)共享資源的

訪問,那么信號(hào)量就用鑰匙符號(hào)。符號(hào)旁邊的數(shù)字N代表可用資源數(shù)。對(duì)于二值信號(hào)量,該值

就是1;如果信號(hào)量用于表示某事件的發(fā)生,那么就用旗幟符號(hào)。這時(shí)的數(shù)字N代表事件已經(jīng)發(fā)

生的次數(shù)。從圖F6.5中可以看出OSSemPost()函數(shù)可以由任務(wù)或者中斷服務(wù)子程序調(diào)用,而

OSSemPend()和OSSemQuery()函數(shù)只能有任務(wù)程序調(diào)用。

圖F6.5任務(wù)、中斷服務(wù)子程序和信號(hào)量之間的關(guān)系——Figure6.5

6.6.1 建立一個(gè)信號(hào)量,OSSemCreate()

程序清單L6.9是OSSemCreate()函數(shù)的源代碼。首先,它從空閑任務(wù)控制塊鏈表中得到一個(gè)事件控制塊[L6.9(1)],并對(duì)空閑事件控制鏈表的指針進(jìn)行適當(dāng)?shù)恼{(diào)整,使它指向下一個(gè)空閑的事件控制塊[L6.9(2)]。如果這時(shí)有任務(wù)控制塊可用[L6.9(3)],就將該任務(wù)控制塊的事件類型設(shè)置成信號(hào)量OS_EVENT_TYPE_SEM[L6.9(4)]。其它的信號(hào)量操作函數(shù)OSSem???()通過檢查該域來保證所操作的任務(wù)控制塊類型的正確。例如,這可以防止調(diào)用OSSemPost()函數(shù)對(duì)一個(gè)用作郵箱的任務(wù)控制塊進(jìn)行操作[6.06節(jié),郵箱]。接著,用信號(hào)量的初始值對(duì)任務(wù)控制塊進(jìn)行初始化[L6.9(5)],并調(diào)用 OSEventWaitListInit()函數(shù)對(duì)事件控制任務(wù)控制塊的等待任務(wù)列表進(jìn)行初始化[見6.01節(jié),初始化一個(gè)任務(wù)控制塊,OSEventWaitListInit()][L6.9(6)]。因?yàn)樾盘?hào)量正在被初始化,所以這時(shí)沒有任何任務(wù)等待該信號(hào)量。最后,OSSemCreate()返回給調(diào)用函數(shù)一個(gè)指向任務(wù)控制塊的指針。以后對(duì)信號(hào)量的所有操作,如OSSemPend(),OSSemPost(),OSSemAccept()和OSSemQuery()都是通過該指針完成的。因此,這個(gè)指針實(shí)際上就是該信號(hào)量的句柄。如果系統(tǒng)中沒有可用的任務(wù)控制塊,OSSemCreate()將返回一個(gè)NULL指針。



關(guān)鍵詞:

評(píng)論


相關(guān)推薦

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

關(guān)閉