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

          新聞中心

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

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

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

          制塊的.OSEventGrp域?yàn)榉?值時(shí),說(shuō)明該消息隊(duì)列的等待任務(wù)列表中有任務(wù)。這時(shí),調(diào)用

          OSEventTaskRdy()函數(shù)[見(jiàn)6.02節(jié),使一個(gè)任務(wù)進(jìn)入就緒狀態(tài),OSEventTaskRdy()]從列表中取出最高優(yōu)先級(jí)的任務(wù)[L6.23(3)], 并將它置于就緒狀態(tài)。 然后調(diào)用函數(shù)OSSched()[L6.23(4)]進(jìn)行任務(wù)的調(diào)度。如果上面取出的任務(wù)的優(yōu)先級(jí)在整個(gè)系統(tǒng)就緒的任務(wù)里也是最高的,而且OSQPost()函數(shù)不是中斷服務(wù)子程序調(diào)用的,就執(zhí)行任務(wù)切換,該最高優(yōu)先級(jí)任務(wù)被執(zhí)行。否則的話,OSSched()函數(shù)直接返回,調(diào)用 OSQPost()函數(shù)的任務(wù)繼續(xù)執(zhí)行。

          程序清單L6.23向消息隊(duì)列發(fā)送一條消息

          INT8UOSQPost(OS_EVENT*pevent,void*msg)

          {

          OS_Q*pq;

          OS_ENTER_CRITICAL();

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

          OS_EXIT_CRITICAL();

          return(OS_ERR_EVENT_TYPE);

          }

          if(pevent->OSEventGrp){(2)

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

          OS_EXIT_CRITICAL();

          OSSched();

          (4)

          return(OS_NO_ERR);

          }else{

          pq=pevent->OSEventPtr;

          if(pq->OSQEntries>=pq->OSQSize){(5)

          OS_EXIT_CRITICAL();

          return(OS_Q_FULL);

          }else{

          *pq->OSQIn++=msg;(6)

          pq->OSQEntries++;

          if(pq->OSQIn==pq->OSQEnd){

          pq->OSQIn=pq->OSQStart;

          }

          OS_EXIT_CRITICAL();

          }

          return(OS_NO_ERR);

          }

          }

          如果沒(méi)有任務(wù)等待該消息隊(duì)列中的消息,而且此時(shí)消息隊(duì)列未滿[L6.23(5)],指向該消息的指針被插入到消息隊(duì)列中[L6.23(6)]。這樣,下一個(gè)調(diào)用OSQPend()函數(shù)的任務(wù)就可以馬上得到該消息。注意,如果此時(shí)消息隊(duì)列已滿,那么該消息將由于不能插入到消息隊(duì)列中而丟失。

          此外,如果OSQPost()函數(shù)是由中斷服務(wù)子程序調(diào)用的,那么即使產(chǎn)生了更高優(yōu)先級(jí)的任務(wù),也不會(huì)在調(diào)用OSSched()函數(shù)時(shí)發(fā)生任務(wù)切換。這個(gè)動(dòng)作一直要等到中斷嵌套的最外層中斷服務(wù)子程序調(diào)用OSIntExit()函數(shù)時(shí)才能進(jìn)行(見(jiàn)3.09節(jié),μC/OS-II中的中斷)。

          6.8.4 向消息隊(duì)列發(fā)送一個(gè)消息(后進(jìn)先出LIFO),OSQPostFront()

          OSQPostFront()函數(shù)和OSQPost()基本上是一樣的, 只是在插入新的消息到消息隊(duì)列中時(shí),使用.OSQOut作為指向下一個(gè)插入消息的單元的指針,而不是.OSQIn。程序清單L6.24是它的源代碼。值得注意的是,.OSQOut指針指向的是已經(jīng)插入了消息指針的單元,所以再插入新的消

          息指針前,必須先將.OSQOut指針在消息隊(duì)列中前移一個(gè)單元。如果.OSQOut指針指向的當(dāng)前單

          元是隊(duì)列中的第一個(gè)單元[L6.24(1)],這時(shí)再前移就會(huì)發(fā)生越界,需要特別地將該指針指向隊(duì)

          列的末尾[L6.24(2)]。由于.OSQEnd指向的是消息隊(duì)列中最后一個(gè)單元的下一個(gè)單元,因此.OSQOut必須被調(diào)整到指向隊(duì)列的有效范圍內(nèi)[L6.24(3)]。因?yàn)镼SQPend()函數(shù)取出的消息是

          由OSQPend()函數(shù)剛剛插入的,因此OSQPostFront()函數(shù)實(shí)現(xiàn)了一個(gè)LIFO隊(duì)列。

          程序清單L6.24向消息隊(duì)列發(fā)送一條消息(LIFO)

          INT8UOSQPostFront(OS_EVENT*pevent,void*msg)

          {

          OS_Q*pq;

          OS_ENTER_CRITICAL();

          if(pevent->OSEventType!=OS_EVENT_TYPE_Q){

          OS_EXIT_CRITICAL();

          return(OS_ERR_EVENT_TYPE);

          }

          if(pevent->OSEventGrp){

          OSEventTaskRdy(pevent,msg,OS_STAT_Q);

          OS_EXIT_CRITICAL();

          OSSched();

          return(OS_NO_ERR);

          }else{

          pq=pevent->OSEventPtr;

          if(pq->OSQEntries>=pq->OSQSize){

          OS_EXIT_CRITICAL();

          return(OS_Q_FULL);

          }else{

          if(pq->OSQOut==pq->OSQStart){(1)

          pq->OSQOut=pq->OSQEnd;(2)

          }

          pq->OSQOut--;(3)

          *pq->OSQOut=msg;

          pq->OSQEntries++;

          OS_EXIT_CRITICAL();

          }

          return(OS_NO_ERR);

          }

          }

          6.8.5 無(wú)等待地從一個(gè)消息隊(duì)列中取得消息,OSQAccept()

          如果試圖從消息隊(duì)列中取出一條消息,而此時(shí)消息隊(duì)列又為空時(shí),也可以不讓調(diào)用任務(wù)等待而直接返回調(diào)用函數(shù)。這個(gè)操作可以調(diào)用OSQAccept()函數(shù)來(lái)完成。程序清單L6.25是該函數(shù)的源代碼。 OSQAccept()函數(shù)首先查看pevent指向的事件控制塊是否是由OSQCreate()函數(shù)建立的[L6.25(1)],然后它檢查當(dāng)前消息隊(duì)列中是否有消息[L6.25(2)]。如果消息隊(duì)列中有至少一條消息,那么就從.OSQOut指向的單元中取出消息[L6.25(3)]。OSQAccept()函數(shù)的調(diào)用函數(shù)需要對(duì)OSQAccept()返回的指針進(jìn)行檢查。如果該指針是NULL值,說(shuō)明消息隊(duì)列是空的,其中沒(méi)有消息可以[L6.25(4)]。否則的話,說(shuō)明已經(jīng)從消息隊(duì)列中成功地取得了一條消息。當(dāng)中斷服務(wù)子程序要從消息隊(duì)列中取消息時(shí), 必須使用OSQAccept()函數(shù), 而不能使用OSQPend()函數(shù)。

          程序清單L6.25無(wú)等待地從消息隊(duì)列中取一條消息

          void*OSQAccept(OS_EVENT*pevent)

          {

          void*msg;

          OS_Q*pq;

          OS_ENTER_CRITICAL();

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

          OS_EXIT_CRITICAL();

          return((void*)0);

          }

          pq=pevent->OSEventPtr;

          if(pq->OSQEntries!=0){(2)

          msg=*pq->OSQOut++;(3)

          pq->OSQEntries--;

          if(pq->OSQOut==pq->OSQEnd){

          pq->OSQOut=pq->OSQStart;

          }

          }else{

          msg=(void*)0;(4)

          }

          OS_EXIT_CRITICAL();

          return(msg);

          }

          6.8.6 清空一個(gè)消息隊(duì)列,OSQFlush()

          OSQFlush()函數(shù)允許用戶刪除一個(gè)消息隊(duì)列中的所有消息,重新開(kāi)始使用。程序清單L6.26是該函數(shù)的源代碼。和前面的其它函數(shù)一樣,該函數(shù)首先檢查pevent指針是否是執(zhí)行一個(gè)消息隊(duì)列[L6.26(1)],然后將隊(duì)列的插入指針和取出指針復(fù)位,使它們都指向隊(duì)列起始單元,同時(shí),將隊(duì)列中的消息數(shù)設(shè)為0[L6.26(2)]。這里,沒(méi)有檢查該消息隊(duì)列的等待任務(wù)列表是否為空,因?yàn)橹灰摰却蝿?wù)列表不空,.OSQEntries就一定是0。唯一不同的是,指針.OSQIn和.OSQOut此時(shí)可以指向消息隊(duì)列中的任何單元,不一定是起始單元。



          關(guān)鍵詞:

          評(píng)論


          相關(guān)推薦

          技術(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); })();