新聞中心

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

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

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

        在μC/OS-II中,有多種方法可以保護(hù)任務(wù)之間的共享數(shù)據(jù)和提供任務(wù)之間的通訊。在前面的章節(jié)中,已經(jīng)講到了其中的兩種:

        本文引用地址:http://www.104case.com/article/201610/305741.htm

        一是利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()來關(guān)閉中斷和打開中斷。當(dāng)兩個(gè)任務(wù)或者一個(gè)任務(wù)和一個(gè)中斷服務(wù)子程序共享某些數(shù)據(jù)時(shí),可以采用這種方法,詳見3.00節(jié)臨界段、8.03.02節(jié) OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL()及9.03.02節(jié)臨界段,OS_CPU.H;

        二是利用函數(shù)OSSchedLock()和OSSchekUnlock()對μC/OS-II中的任務(wù)調(diào)度函數(shù)上鎖和開鎖。用這種方法也可以實(shí)現(xiàn)數(shù)據(jù)的共享,詳見3.06節(jié) 給調(diào)度器上鎖和開鎖。

        本章將介紹另外三種用于數(shù)據(jù)共享和任務(wù)通訊的方法:信號量、郵箱和消息隊(duì)列。

        圖F6.1介紹了任務(wù)和中斷服務(wù)子程序之間是如何進(jìn)行通訊的。

        一個(gè)任務(wù)或者中斷服務(wù)子程序可以通過事件控制塊ECB(EventCONtrolBlocks)來向另外的任務(wù)發(fā)信號[F6.1A(1)]。這里,所有的信號都被看成是事件(Event)。這也說明為什么上面把用于通訊的數(shù)據(jù)結(jié)構(gòu)叫做事件控制塊。一個(gè)任務(wù)還可以等待另一個(gè)任務(wù)或中斷服務(wù)子程序給它發(fā)送信號[F6.1A(2)]。這里要注意的是,只有任務(wù)可以等待事件發(fā)生,中斷服務(wù)子程序是不能這樣做的。對于處于等待狀態(tài)的任務(wù),還可以給它指定一個(gè)最長等待時(shí)間,以此來防止因?yàn)榈却氖录]有發(fā)生而無限期地等下去。

        多個(gè)任務(wù)可以同時(shí)等待同一個(gè)事件的發(fā)生[F6.1B]。在這種情況下,當(dāng)該事件發(fā)生后,所有等待該事件的任務(wù)中,優(yōu)先級最高的任務(wù)得到了該事件并進(jìn)入就緒狀態(tài),準(zhǔn)備執(zhí)行。上面講到的事件,可以是信號量、郵箱或者消息隊(duì)列等。當(dāng)事件控制塊是一個(gè)信號量時(shí),任務(wù)可以等待它,也可以給它發(fā)送消息。

        圖6.1事件控制塊的使用

        6.1 事件控制塊ECB

        μC/OS-II通過uCOS_II.H中定義的OS_EVENT數(shù)據(jù)結(jié)構(gòu)來維護(hù)一個(gè)事件控制塊的所有信息[程序清單L6.1],也就是本章開篇講到的事件控制塊ECB。該結(jié)構(gòu)中除了包含了事件本身的定義,如用于信號量的計(jì)數(shù)器,用于指向郵箱的指針,以及指向消息隊(duì)列的指針數(shù)組等,還定義了等待該事件的所有任務(wù)的列表。程序清單L6.1是該數(shù)據(jù)結(jié)構(gòu)的定義。

        程序清單L6.1ECB數(shù)據(jù)結(jié)構(gòu)

        typedefSTruct{

        void*OSEventPtr;/*指向消息或者消息隊(duì)列的指針*/

        INT8UOSEventTbl[OS_EVENT_TBL_SIZE];/*等待任務(wù)列表*/

        INT16UOSEventCnt;/*計(jì)數(shù)器(當(dāng)事件是信號量時(shí))*/

        INT8UOSEventType;/*時(shí)間類型*/

        INT8UOSEventGrp;/*等待任務(wù)所在的組*/

        }OS_EVENT;

        .OSEventPtr指針,只有在所定義的事件是郵箱或者消息隊(duì)列時(shí)才使用。 當(dāng)所定義的事件是郵箱時(shí),它指向一個(gè)消息,而當(dāng)所定義的事件是消息隊(duì)列時(shí),它指向一個(gè)數(shù)據(jù)結(jié)構(gòu),詳見6.06節(jié)消息郵箱和6.07節(jié)消息隊(duì)列。

        .OSEventTbl[] 和 .OSEventGrp 很像前面講到的OSRdyTbl[]和OSRdyGrp,只不過前兩者包含的是等待某事件的任務(wù),而后兩者包含的是系統(tǒng)中處于就緒狀態(tài)的任務(wù)。(見3.04節(jié)就緒表)

        .OSEventCnt 當(dāng)事件是一個(gè)信號量時(shí),.OSEventCnt是用于信號量的計(jì)數(shù)器,(見6.05節(jié)信號量)。

        .OSEventType 定義了事件的具體類型。它可以是信號量(OS_EVENT_SEM)、郵箱

        (OS_EVENT_TYPE_MBOX)或消息隊(duì)列(OS_EVENT_TYPE_Q)中的一種。用戶要根據(jù)該域的具體值

        來調(diào)用相應(yīng)的系統(tǒng)函數(shù),以保證對其進(jìn)行的操作的正確性。

        每個(gè)等待事件發(fā)生的任務(wù)都被加入到該事件事件控制塊中的等待任務(wù)列表中,該列表包括.OSEventGrp和.OSEventTbl[]兩個(gè)域。變量前面的[.]說明該變量是數(shù)據(jù)結(jié)構(gòu)的一個(gè)域。在這

        里,所有的任務(wù)的優(yōu)先級被分成8組(每組8個(gè)優(yōu)先級),分別對應(yīng).OSEventGrp中的8位。當(dāng)

        某組中有任務(wù)處于等待該事件的狀態(tài)時(shí),.OSEventGrp中對應(yīng)的位就被置位。相應(yīng)地,該任務(wù)

        在.OSEventTbl[]中的對應(yīng)位也被置位。.OSEventTbl[]數(shù)組的大小由系統(tǒng)中任務(wù)的最低優(yōu)先級

        決定,這個(gè)值由uCOS_II.H中的OS_LOWEST_PRIO常數(shù)定義。這樣,在任務(wù)優(yōu)先級比較少的情況

        下,減少μC/OS-II對系統(tǒng)RAM的占用量。

        當(dāng)一個(gè)事件發(fā)生后,該事件的等待事件列表中優(yōu)先級最高的任務(wù),也即在.OSEventTbl[]中,所有被置1的位中,優(yōu)先級代碼最小的任務(wù)得到該事件。圖F6.2給出

        了.OSEventGrp和.OSEventTbl[]之間的對應(yīng)關(guān)系。該關(guān)系可以描述為:

        當(dāng).OSEventTbl[0]中的任何一位為1時(shí),.OSEventGrp中的第0位為1。

        當(dāng).OSEventTbl[1]中的任何一位為1時(shí),.OSEventGrp中的第1位為1。

        當(dāng).OSEventTbl[2]中的任何一位為1時(shí),.OSEventGrp中的第2位為1。

        當(dāng).OSEventTbl[3]中的任何一位為1時(shí),.OSEventGrp中的第3位為1。

        當(dāng).OSEventTbl[4]中的任何一位為1時(shí),.OSEventGrp中的第4位為1。

        當(dāng).OSEventTbl[5]中的任何一位為1時(shí),.OSEventGrp中的第5位為1。

        當(dāng).OSEventTbl[6]中的任何一位為1時(shí),.OSEventGrp中的第6位為1。

        當(dāng).OSEventTbl[7]中的任何一位為1時(shí),.OSEventGrp中的第7位為1。

        圖F6.2事件的等待任務(wù)列表

        下面的代碼將一個(gè)任務(wù)放到事件的等待任務(wù)列表中。

        程序清單L6.2——將一個(gè)任務(wù)插入到事件的等待任務(wù)列表中

        pevent->OSEventGrp|=OSMapTbl[prio>>3];

        pevent->OSEventTbl[prio>>3]|=OSMapTbl[prio0x07];

        其中,prio是任務(wù)的優(yōu)先級,pevent是指向事件控制塊的指針。

        從程序清單L6.2可以看出,插入一個(gè)任務(wù)到等待任務(wù)列表中所花的時(shí)間是相同的,和表中現(xiàn)有多少個(gè)任務(wù)無關(guān)。從圖F6.2中可以看出該算法的原理:任務(wù)優(yōu)先級的最低3位決定了該任務(wù)在相應(yīng)的.OSEventTbl[]中的位置,緊接著的3位則決定了該任務(wù)優(yōu)先級在.OSEventTbl[]中的字節(jié)索引。該算法中用到的查找表OSMapTbl[](定義在OS_CORE.C中)一般在ROM中實(shí)現(xiàn)。


        上一頁 1 2 3 4 5 6 7 8 9 10 11 下一頁

        關(guān)鍵詞:

        評論


        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 罗江县| 富裕县| 镇坪县| 确山县| 禹州市| 扬州市| 鹤庆县| 安远县| 香港| 霞浦县| 东源县| 新野县| 兴宁市| 枣阳市| 镇雄县| 南岸区| 华池县| 双峰县| 灵台县| 那曲县| 辰溪县| 岱山县| 山东| 乡城县| 泰兴市| 南投市| 博爱县| 大同县| 成都市| 卢龙县| 阳山县| 宁河县| 德兴市| 客服| 东阿县| 渝中区| 三河市| 云梦县| 马山县| 宝兴县| 阳春市|