新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II的任務之間的通訊與同步

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

        作者: 時間:2016-10-08 來源:網絡 收藏

        程序清單L6.16向郵箱中發送一條消息

        INT8UOSMboxPost(OS_EVENT*pevent,void*msg)

        {

        OS_ENTER_CRITICAL();

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

        OS_EXIT_CRITICAL();

        return(OS_ERR_EVENT_TYPE);

        }

        if(pevent->OSEventGrp){(2)

        OSEventTaskRdy(pevent,msg,OS_STAT_MBOX);(3)

        OS_EXIT_CRITICAL();

        OSSched();(4)

        return(OS_NO_ERR);

        }else{

        if(pevent->OSEventPtr!=(void*)0){(5)

        OS_EXIT_CRITICAL();

        return(OS_MBOX_FULL);

        }else{

        pevent->OSEventPtr=msg;(6)

        OS_EXIT_CRITICAL();

        return(OS_NO_ERR);

        }

        }

        }

        6.7.4 無等待地從郵箱中得到一個消息,OSMboxAccept()

        應用程序也可以以無等待的方式從郵箱中得到消息。這可以通過程序清單L6.17中的OSMboxAccept()函數來實現。OSMboxAccept()函數開始也是檢查事件控制塊是否是由OSMboxCreate()函數建立的 [L6.17(1)]。接著,它得到郵箱中的當前內容[L6.17(2)],并判斷是否有消息是可用的[L6.17(3)]。如果郵箱中有消息,就把郵箱清空[L6.17(4)],而郵箱中原來指向消息的指針被返回給OSMboxAccept()的調用函數[L6.17(5)]。OSMboxAccept()函數的調用函數必須檢查該返回值是否為NULL。如果該值是NULL,說明郵箱是空的,沒有可用的消息。

        如果該值是非NULL值,說明郵箱中有消息可用,而且該調用函數已經得到了該消息。中斷服務子程序在試圖得到一個消息時, 應該使用OSMboxAccept()函數, 而不能使用OSMboxPend()函數。

        OSMboxAccept()函數的另一個用途是,用戶可以用它來清空一個郵箱中現有的內容。

        程序清單L6.17無等待地從郵箱中得到消息

        void*OSMboxAccept(OS_EVENT*pevent)

        {

        void*msg;

        OS_ENTER_CRITICAL();

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

        OS_EXIT_CRITICAL();

        return((void*)0);

        }

        msg=pevent->OSEventPtr;(2)

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

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

        }

        OS_EXIT_CRITICAL();

        return(msg);(5)

        }

        6.7.5 查詢一個郵箱的狀態,OSMboxQuery()

        OSMboxQuery()函數使應用程序可以隨時查詢一個郵箱的當前狀態。程序清單L6.18是該函數的源代碼。它需要兩個參數:一個是指向郵箱的指針pevent。該指針是在建立該郵箱時,由OSMboxCreate()函數返回的;另一個是指向用來保存有關郵箱的信息的OS_MBOX_DATA(見

        uCOS_II.H)數據結構的指針pdata。在調用OSMboxCreate()函數之前,必須先定義該結構變量,

        用來保存有關郵箱的信息。之所以定義一個新的數據結構,是因為這里關心的只是和特定郵箱

        有關的內容,而非整個OS_EVENT數據結構的內容。后者還包含了另外兩個域

        (.OSEventCnt和.OSEventType),而OS_MBOX_DATA只包含郵箱中的消息指針(.OSMsg)和該郵箱現有的等待任務列表(.OSEventTbl[]和.OSEventGrp)。

        和前面的所以函數一樣,該函數也是先檢查事件控制是否是郵箱[L6.18(1)]。然后,將郵箱中的等待任務列表[L6.18(2)]和郵箱中的消息[L6.18(3)]從OS_EVENT數據結構復制到OS_MBOX_DATA數據結構。

        程序清單L6.18查詢郵箱的狀態

        INT8UOSMboxQuery(OS_EVENT*pevent,OS_MBOX_DATA*pdata)

        {

        INT8Ui;

        INT8U*psrc;

        INT8U*pdest;

        OS_ENTER_CRITICAL();

        if(pevent->OSEventType!=OS_EVENT_TYPE_MBOX){(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->OSMsg=pevent->OSEventPtr;(3)

        OS_EXIT_CRITICAL();

        return(OS_NO_ERR);

        }

        6.7.6 用郵箱作二值信號量

        一個郵箱可以被用作二值的信號量。 首先, 在初始化時, 將郵箱設置為一個非零的指針(如

        void*1)。這樣,一個任務可以調用OSMboxPend()函數來請求一個信號量,然后通過調用

        OSMboxPost()函數來釋放一個信號量。程序清單L6.19說明了這個過程是如何工作的。如果用

        戶只需要二值信號量和郵箱,這樣做可以節省代碼空間。這時可以將OS_SEM_EN設置為0,只使

        用郵箱就可以了。

        程序清單L6.19使用郵箱作為二值信號量

        OS_EVENT*MboxSem;

        voIDTask1(void*pdata)

        {

        INT8Uerr;

        for(;;){

        OSMboxPend(MboxSem,0,err);/*獲得對資源的訪問權*/

        .

        ./*任務獲得信號量,對資源進行訪問*/

        .

        OSMboxPost(MboxSem,(void*)1);/*釋放對資源的訪問權*/

        }

        }

        6.7.7 用郵箱實現延時,而不使用OSTimeDly()

        郵箱的等待超時功能可以被用來模仿OSTimeDly()函數的延時,如程序清單L6.20所示。

        如果在指定的時間段TIMEOUT內,沒有消息到來,Task1()函數將繼續執行。這和OSTimeDly(TIMEOUT)功能很相似。但是,如果Task2()在指定的時間結束之前,向該郵箱發送了一個“啞”消息,Task1()就會提前開始繼續執行。這和調用OSTimeDlyResume()函數的功能是一樣的。注意,這里忽略了對返回的消息的檢查,因為此時關心的不是得到了什么樣的消息。

        程序清單L6.20使用郵箱實現延時

        OS_EVENT*MboxTimeDly;

        voidTask1(void*pdata)

        {

        INT8Uerr;

        for(;;){

        OSMboxPend(MboxTimeDly, TIMEOUT,err);/*延時該任務*/

        .

        ./*延時結束后執行的代碼*/

        .

        }

        }

        voidTask2(void*pdata)



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 台中县| 岳西县| 沽源县| 六枝特区| 弋阳县| 沛县| 铜川市| 吉安县| 和顺县| 安塞县| 五大连池市| 抚顺市| 砚山县| 乌拉特后旗| 和静县| 霍林郭勒市| 玉林市| 隆子县| 大姚县| 陇南市| 元谋县| 武鸣县| 黄龙县| 岳阳县| 保康县| 灵山县| 庆元县| 浮梁县| 五原县| 印江| 甘洛县| 义马市| 平泉县| 营山县| 万载县| 绵阳市| 芷江| 饶河县| 武夷山市| 吐鲁番市| 北票市|