新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32 uCOS_II 實踐 之 消息對列

        STM32 uCOS_II 實踐 之 消息對列

        作者: 時間:2016-12-03 來源:網絡 收藏
        首先消息隊列類似與計數信號量,可以對異步事件進行保存,但是計數信號量保存的是狀態量,他只是在一個變量里進行狀態觸發數目的累加,而消息隊列可以把發送來的數據進行保存,同時消息隊列同消息郵箱有相同的屬性,它本身并不傳送數據,只是傳遞內存中已有數據的地址值即數據指針,這就帶來了一個關鍵特性就是被傳遞的每一個數據都是要有獨立地址的,不然沒有被處理的數據就會被新數據給覆蓋掉,造成了數據的丟失。

        對于消息隊列,需要創建一個隊列,這個隊列有先入先出的特性即FIFO,所以一旦數據被使用在隊列里這個數據就不再出現了,他最終會被新的數據覆蓋掉。

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

        如上面介紹,消息隊列里所有的數據都以數據指針的形式在一個列表里排隊,這個指針的形式可以是多樣的,可以是一個變量的指針,也可以是一個結構類型的指針等等。所以隊列的個數是有限的,在設計過程中要保證其大小合適不然很容易隊列溢出,造成數據丟失。同時消息隊列傳輸的數據是無限制的,只要保證消耗數據與發送數據的吞吐量保證合適就不會造成隊列溢出。

        使用消息隊列有5個步驟:

        步驟1:聲明一個指針變量,這個指針的作用和消息郵箱一樣,為了保存對應事件控制塊的指針。

        void *MboxQ_Task_LED1;

        步驟2:聲明一個指針數組,這個數組就是用來排隊的隊列。

        void *MboxQ_Table[10];

        步驟3:對消息隊列初始化,初始化函數有兩個參數,第一個參數為隊列的頭指針,指明由哪里開始排隊,第二個參數是隊列的數目,即隊列的深度。該函數也是對事件控制塊進行初始化,并且把其指針賦值給步驟1聲明的指針變量。

        MboxQ_Task_LED1 = OSQCreate(&MboxQ_Table[0],10);

        步驟4:在任務中設置消息等待函數,此處和消息郵箱一致。參數有3個,第一個參數指等待的是哪個消息隊列,第二個參數是指等待時間,單位為系統心跳,0為始終等待無時間限制,第三個參數指函數的返回結果。

        num = *(unsigned char *)OSQPend(MboxQ_Task_LED1,0,&err);

        步驟5:在任務里設置消息發送函數,此處和消息郵箱一致。參數有2個,第一個參數為發送大哪個消息隊列里,第二個參數是指具體的數據地址發送出去。

        OSQPost(MboxQ_Task_LED1,(void *)&DataTable[cc++]);

        下面是具體的代碼:
        步驟3和步驟4:

        void Task_LED1(void* p_arg)
        {
        unsigned char num ;
        static unsigned char pp ;
        (void) p_arg ;

        MboxQ_Task_LED1 = OSQCreate(&MboxQ_Table[0],10); // 創建消息隊列,棧數目為10
        while(1)
        {
        num = *(unsigned char *)OSQPend(MboxQ_Task_LED1,0,&err); // 等待郵箱的消息
        pp = num ;

        if(pp == 1)
        { LED1_HIGH; }
        if(pp == 2)
        { LED2_HIGH; }
        if(pp == 3)
        { LED3_HIGH; }
        if(pp == 4)
        { LED1_HIGH;LED2_HIGH; }
        if(pp == 5)
        { LED1_HIGH;LED3_HIGH; }

        OSTimeDlyHMSM(0,0,5,0);
        LED1_LOW;LED2_LOW;LED3_LOW;
        }
        }


        步驟5:

        void Interrupt_Handle_KEY3(void)
        {
        OSIntEnter();

        // 在中斷服務函數里如果調用ucos系統函數的話就必須加上進中斷系統函數出去的時候要加上出中斷系統函數

        OSQPost(MboxQ_Task_LED1,(void *)&DataTable[cc++]);

        // 發送郵箱消息,這個函數并不會引起系統調度,所以中斷服務函數一定要簡潔。
        EXTI_ClearITPendingBit(EXTI_Line3); // 清除標志位

        OSIntExit();
        }

        對于數據在發送的時候轉換成無定義變量的指針,在接受的時候轉換成它本來的數據類型,這點和消息郵箱是相同的。
        值得注意的是在ucos里有自己的內存管理函數,如果你不用那個的話就只能自己建立一個數據,并且保證每個發送出去的數據都有他的地址。
        如果需要代碼請留下郵箱,有不對的地方請大家批評指正,轉載請注明出處。


        關鍵詞: STM32uCOSII消息對

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 会昌县| 北流市| 济源市| 凤台县| 行唐县| 溆浦县| 苏尼特右旗| 临泉县| 酉阳| 长阳| 保定市| 邢台县| 突泉县| 汾西县| 平定县| 香格里拉县| 交城县| 库尔勒市| 凤凰县| 滕州市| 潜山县| 饶河县| 甘谷县| 信宜市| 无锡市| 南岸区| 兴化市| 大方县| 德惠市| 那曲县| 黄浦区| 阜康市| 翁源县| 南木林县| 松溪县| 老河口市| 镇坪县| 湘西| 临漳县| 吕梁市| 峨山|