新聞中心

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

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

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

程序清單L6.11發(fā)出一個(gè)信號(hào)量

INT8UOSSemPost(OS_EVENT*pevent)

{

OS_ENTER_CRITICAL();

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

OS_EXIT_CRITICAL();

return(OS_ERR_EVENT_TYPE);

}

if(pevent->OSEventGrp){(2)

OSEventTaskRdy(pevent,(void*)0,OS_STAT_SEM);(3)

OS_EXIT_CRITICAL();

OSSched();(4)

return(OS_NO_ERR);

}else{

if(pevent->OSEventCnt65535){

pevent->OSEventCnt++;(5)

OS_EXIT_CRITICAL();

return(OS_NO_ERR);

}else{

OS_EXIT_CRITICAL();

return(OS_SEM_OVF);

}

}

}

6.6.4 無(wú)等待地請(qǐng)求一個(gè)信號(hào)量,OSSemAccept()

當(dāng)一個(gè)任務(wù)請(qǐng)求一個(gè)信號(hào)量時(shí),如果該信號(hào)量暫時(shí)無(wú)效,也可以讓該任務(wù)簡(jiǎn)單地返回,而不是進(jìn)入睡眠等待狀態(tài)。這種情況下的操作是由OSSemAccept()函數(shù)完成的,其源代碼見(jiàn)程序清單L6.12。該函數(shù)在最開(kāi)始也是檢查參數(shù)指針pevent指向的事件控制塊是否是由OSSemCreate()函數(shù)建立的[L6.12(1)],接著從該信號(hào)量的事件控制塊中取出當(dāng)前計(jì)數(shù)值[L6.12(2)],并檢查該信號(hào)量是否有效(計(jì)數(shù)值是否為非0值)[L6.12(3)]。如果有效,則將信號(hào)量的計(jì)數(shù)值減1[L6.12(4)],然后將信號(hào)量的原有計(jì)數(shù)值返回給調(diào)用函數(shù)[L6.12(5)]。調(diào)用函數(shù)需要對(duì)該返回值進(jìn)行檢查。如果該值是0,說(shuō)明該信號(hào)量無(wú)效。如果該值大于0,說(shuō)明該信號(hào)量有效,同時(shí)該值也暗示著該信號(hào)量當(dāng)前可用的資源數(shù)。應(yīng)該注意的是,這些可用資源中,已經(jīng)被該調(diào)用函數(shù)自身占用了一個(gè)(該計(jì)數(shù)值已經(jīng)被減1)。中斷服務(wù)子程序要請(qǐng)求信號(hào)量時(shí),只能用OSSemAccept()而不能用OSSemPend(),因?yàn)橹袛喾?wù)子程序是不允許等待的。

程序清單L6.12無(wú)等待地請(qǐng)求一個(gè)信號(hào)量

INT16UOSSemAccept(OS_EVENT*pevent)

{

INT16Ucnt;

OS_ENTER_CRITICAL();

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

OS_EXIT_CRITICAL();

return(0);

}

cnt=pevent->OSEventCnt;(2)

if(cnt>0){(3)

pevent->OSEventCnt--;(4)

}

OS_EXIT_CRITICAL();

return(cnt);(5)

}

6.6.5 查詢一個(gè)信號(hào)量的當(dāng)前狀態(tài),OSSemQuery()

在應(yīng)用程序中,用戶隨時(shí)可以調(diào)用函數(shù)OSSemQuery()[程序清單L6.13]來(lái)查詢一個(gè)信號(hào)量的當(dāng)前狀態(tài)。該函數(shù)有兩個(gè)參數(shù):一個(gè)是指向信號(hào)量對(duì)應(yīng)事件控制塊的指針pevent。該指針是在生產(chǎn)信號(hào)量時(shí),由OSSemCreate()函數(shù)返回的;另一個(gè)是指向用于記錄信號(hào)量信息的數(shù)據(jù)結(jié)構(gòu)OS_SEM_DATA(見(jiàn)uCOS_II.H)的指針pdata。因此,調(diào)用該函數(shù)前,用戶必須先定義該結(jié)構(gòu)變量,用于存儲(chǔ)信號(hào)量的有關(guān)信息。在這里,之所以使用一個(gè)新的數(shù)據(jù)結(jié)構(gòu)的原因在于,調(diào)用函數(shù)應(yīng)該只關(guān)心那些和特定信號(hào)量有關(guān)的信息, 而不是象OS_EVENT數(shù)據(jù)結(jié)構(gòu)包含的很全面的信息。

該數(shù)據(jù)結(jié)構(gòu)只包含信號(hào)量計(jì)數(shù)值.OSCnt和等待任務(wù)列表.OSEventTbl[]、.OSEventGrp,而OS_EVENT中還包含了另外的兩個(gè)域.OSEventType和.OSEventPtr。

和其它與信號(hào)量有關(guān)的函數(shù)一樣,OSSemQuery()也是先檢查pevent指向的事件控制塊是否是OSSemCreate()產(chǎn)生的[L6.13(1)],然后將等待任務(wù)列表[L6.13(2)]和計(jì)數(shù)值[L6.13(3)]

從OS_EVENT結(jié)構(gòu)拷貝到OS_SEM_DATA結(jié)構(gòu)變量中去。

程序清單L6.13查詢一個(gè)信號(hào)量的狀態(tài)

INT8UOSSemQuery(OS_EVENT*pevent,OS_SEM_DATA*pdata)

{

INT8Ui;

INT8U*psrc;

INT8U*pdest;

OS_ENTER_CRITICAL();

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

OS_EXIT_CRITICAL();

return(OS_ERR_EVENT_TYPE);

}

pdata->OSEventGrp=pevent->OSEventGrp;(2)

psrc=pevent->OSEventTbl[0];

pdest=pdata->OSEventTbl[0];

for(i=0;i

*pdest++=*psrc++;

}

pdata->OSCnt=pevent->OSEventCnt;(3)

OS_EXIT_CRITICAL();

return(OS_NO_ERR);

}

6.7 郵箱

郵箱是μC/OS-II中另一種通訊機(jī)制, 它可以使一個(gè)任務(wù)或者中斷服務(wù)子程序向另一個(gè)任務(wù)發(fā)送一個(gè)指針型的變量。該指針指向一個(gè)包含了特定“消息”的數(shù)據(jù)結(jié)構(gòu)。為了在μC/OS-II中使用郵箱,必須將OS_CFG.H中的OS_MBOX_EN常數(shù)置為1。

使用郵箱之前,必須先建立該郵箱。該操作可以通過(guò)調(diào)用OSMboxCreate()函數(shù)來(lái)完成(見(jiàn)下節(jié)),并且要指定指針的初始值。一般情況下,這個(gè)初始值是NULL,但也可以初始化一個(gè)郵

箱,使其在最開(kāi)始就包含一條消息。如果使用郵箱的目的是用來(lái)通知一個(gè)事件的發(fā)生(發(fā)送一

條消息),那么就要初始化該郵箱為NULL,因?yàn)樵陂_(kāi)始時(shí),事件還沒(méi)有發(fā)生。如果用戶用郵箱

來(lái)共享某些資源,那么就要初始化該郵箱為一個(gè)非NULL的指針。在這種情況下,郵箱被當(dāng)成一

個(gè)二值信號(hào)量使用。

μC/OS-II提供了5種對(duì)郵箱的操作:OSMboxCreate(),OSMboxPend(),OSMboxPost(),

OSMboxAccept()和 OSMboxQuery()函數(shù)。圖F6.6描述了任務(wù)、中斷服務(wù)子程序和郵箱之間的關(guān)

系,這里用符號(hào)“I”表示郵箱。郵箱包含的內(nèi)容是一個(gè)指向一條消息的指針。一個(gè)郵箱只能包

含一個(gè)這樣的指針(郵箱為滿時(shí)),或者一個(gè)指向NULL的指針(郵箱為空時(shí))。從圖F6.6可以看出,任務(wù)或者中斷服務(wù)子程序可以調(diào)用函數(shù)OSMboxPost(),但是只有任務(wù)可以調(diào)用函數(shù)OSMboxPend()和OSMboxQuery()。

圖F6.6任務(wù)、中斷服務(wù)子程序和郵箱之間的關(guān)系

6.7.1 建立一個(gè)郵箱,OSMboxCreate()

程序清單L6.14是OSMboxCreate()函數(shù)的源代碼,基本上和函數(shù)OSSemCreate()相似。不同之處在于事件控制塊的類型被設(shè)置成OS_EVENT_TYPE_MBOX[L6.14(1)], 以及使用.OSEventPtr域來(lái)容納消息指針,而不是使用.OSEventCnt域[L6.14(2)]。



關(guān)鍵詞:

評(píng)論


相關(guān)推薦

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

關(guān)閉