<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > STM32 uCOS_II 實踐 之 消息對列

          STM32 uCOS_II 實踐 之 消息對列

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

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

          本文引用地址:http://www.ex-cimer.com/article/201612/325155.htm

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

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

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

          void *MboxQ_Task_LED1;

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

          void *MboxQ_Table[10];

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

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

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

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

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

          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); // 創(chuàng)建消息隊列,棧數(shù)目為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();

          // 在中斷服務(wù)函數(shù)里如果調(diào)用ucos系統(tǒng)函數(shù)的話就必須加上進中斷系統(tǒng)函數(shù)出去的時候要加上出中斷系統(tǒng)函數(shù)

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

          // 發(fā)送郵箱消息,這個函數(shù)并不會引起系統(tǒng)調(diào)度,所以中斷服務(wù)函數(shù)一定要簡潔。
          EXTI_ClearITPendingBit(EXTI_Line3); // 清除標志位

          OSIntExit();
          }

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


          關(guān)鍵詞: STM32uCOSII消息對

          評論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();