新聞中心

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

        STM32 uCOS_II 實踐 之 消息郵箱

        作者: 時間:2016-12-03 來源:網絡 收藏
        所謂的消息郵箱并不是把數據進行傳輸,而是在合適的時間告訴任務去使用哪些變量或者當一些特殊的變量變化后可以及時并準確的使用變量,消息郵箱傳遞的是這些變量的指針,而這些變量本身就已經存在與內存中了,他們多以全局變量或者靜態變量的形式存在。

        首先介紹消息郵箱的一種使用方式,就是只傳遞一個非空指針,告訴等待消息的任務他等待的時間到了,但是這個指針里并沒有有用的數據,而任務中也不應該對這個地址指向的變量進行任何的讀取和寫入操作,讀寫操作都是無意義的,從另外一個角度來看,雖然借用了別人的地址但是本身并沒有對地址里的數據進行操作,所以地址里的數據也是安全的,說白了就是消息郵箱版信號量(非計數)。它的好處就是可以在系統里把信號量有關的代碼給裁剪掉,但缺點是他并無法達到信號量的全部功能,這種用法無法進行計數,只是單純的傳遞一次狀態。如果把消息隊列改造成計數信號量,個人覺得很沒必要,除非你選的MCU非常的尷尬。權且就讓這種方式作為初步了解消息郵箱的一個引子吧。

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

        使用消息郵箱可以分為4個步驟:

        步驟1:聲明一個指針變量,這個指針變量在初始化消息郵箱的時候會把這個消息郵箱對應的事件控制塊的指針存放進去。

        void *Mbox_Task_LED1;

        步驟2:對消息郵箱進行初始化,也就是初始化對應的事件控制塊,并且會把這個事件控制塊的指針作為返回值賦值給第一步聲明的指針變量。消息郵箱初始化函數有一個參數,應該設置為空指針,表示消息郵箱為空。

        Mbox_Task_LED1 = OSMboxCreate((void *)0);

        步驟3:在任務里設置等待消息函數,當這個任務執行到這句話的時候,系統會把這個任務掛起,等待有消息的發送。這個函數里有3個變量,第一個參數是指等待的是哪個消息郵箱,第二個參數是指等待時間單位為系統心跳,0指無時間期限的等待,第三個參數為返回的錯誤類型。

        OSMboxPend(Mbox_Task_LED1,0,&err);

        步驟4:在其他的任務里或者中斷服務程序里設置發送消息函數,需要注意的是,這個函數并不會引起系統調度,所以如果把它放在中斷服務函數里的話就要去中斷里的內容盡量簡短,以保證消息發送出去后,能進來快的進行系統調度讓消息接受函數相應。在這個函數里有2個參數,第一個參數為要發送給哪個消息郵箱,第二個參數為發送的數據的地址。在這里其實并沒有真實的數據,只是把發送的地址用了一個非空地址,這個地址及其指向的數據都沒有任何意義,也不需要進行任何的讀寫操作,只是傳遞一個消息到相應的等待函數,以解除對應任務的掛起狀態。

        OSMboxPost(Mbox_Task_LED1,(void *)1);

        下面看下具體的代碼:
        步驟2和步驟3:

        void Task_LED1(void* p_arg)
        {
        (void) p_arg ;

        Mbox_Task_LED1 = OSMboxCreate((void *)0); // 創建消息郵箱,初值為空指針
        while(1)
        {
        OSMboxPend(Mbox_Task_LED1,0,&err); // 等待郵箱的消息

        LED1_HIGH;
        OSTimeDlyHMSM(0,0,1,0);
        LED1_LOW;
        OSTimeDlyHMSM(0,0,1,0); // 延時,用來給其他任務留有運行的時間
        }
        }

        步驟4:

        void Interrupt_Handle_KEY3(void)
        {
        OSIntEnter();

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

        OSMboxPost(Mbox_Task_LED1,(void *)1);

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

        OSIntExit();
        }

        =======================================================================================================
        下面說下傳遞一個真實的變量,步驟和上面是一樣的,只不過在步驟3和步驟4的地方會有對變量的轉換。代碼如下:
        步驟2和步驟3:

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

        Mbox_Task_LED1 = OSMboxCreate((void *)0); // 創建消息郵箱,初值為空指針
        while(1)
        {
        num = *(unsigned char *)OSMboxPend(Mbox_Task_LED1,0,&err); // 等待郵箱的消息
        pp = num; // 這個變量用于仿真時數據監測
        while(pp--)
        {
        LED1_HIGH;
        OSTimeDlyHMSM(0,0,0,200);
        LED1_LOW;
        OSTimeDlyHMSM(0,0,0,200);
        }
        }
        }

        步驟4:

        void Interrupt_Handle_KEY3(void)
        {
        OSIntEnter();

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

        OSMboxPost(Mbox_Task_LED1,(void *)&Num);

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

        OSIntExit();
        }

        如步驟4紅色注釋部分,在發送的時候把一個具體的變量取地址,并且強制轉換為一個無定義變量的指針;在步驟3紅色注釋部分,在等待函數外部首先進行的時候變量類型的轉換,轉換成一個無符號字符型變量的指針,然后在進行間指操作,把地址里的數據取出來,最后賦值給函數的臨時變量進行使用。				   


        關鍵詞: STM32uCOSII消息郵

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 科尔| 宜良县| 阿鲁科尔沁旗| 巴楚县| 双流县| 海南省| 疏附县| 望奎县| 若羌县| 河津市| 扎兰屯市| 西平县| 景泰县| 香河县| 普兰店市| 米脂县| 威远县| 陆河县| 阆中市| 徐闻县| 西峡县| 鸡西市| 榆社县| 汽车| 大英县| 京山县| 临安市| 峨山| 南乐县| 裕民县| 南平市| 西藏| 宿迁市| 乡城县| 塘沽区| 梨树县| 新乡县| 噶尔县| 桓仁| 石景山区| 婺源县|