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

          新聞中心

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

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

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

          另外,消息隊列一旦建立就不能再刪除了。試想,如果有任務(wù)正在等待某個消息隊列中的消息,而此時又刪除該消息隊列,將是很危險的。

          程序清單L6.21建立一個消息隊列

          OS_EVENT*OSQCreate(void**start,INT16Usize)

          {

          OS_EVENT*pevent;

          OS_Q*pq;

          OS_ENTER_CRITICAL();

          pevent=OSEventFreeList;(1)

          if(OSEventFreeList!=(OS_EVENT*)0){

          OSEventFreeList=(OS_EVENT*)OSEventFreeList->OSEventPtr;(2)

          }

          OS_EXIT_CRITICAL();

          if(pevent!=(OS_EVENT*)0){

          OS_ENTER_CRITICAL();

          pq=OSQFreeList;(3)

          if(OSQFreeList!=(OS_Q*)0){

          OSQFreeList=OSQFreeList->OSQPtr;

          }

          OS_EXIT_CRITICAL();

          if(pq!=(OS_Q*)0){

          pq->OSQStart=start;(4)

          pq->OSQEnd=start[size];

          pq->OSQIn=start;

          pq->OSQOut=start;

          pq->OSQSize=size;

          pq->OSQEntries=0;

          pevent->OSEventType=OS_EVENT_TYPE_Q;(5)

          pevent->OSEventPtr=pq;(6)

          OSEventWaitListInit(pevent);(7)

          }else{

          OS_ENTER_CRITICAL();

          pevent->OSEventPtr=(void*)OSEventFreeList;(8)

          OSEventFreeList=pevent;

          OS_EXIT_CRITICAL();

          pevent=(OS_EVENT*)0;

          }

          }

          return(pevent);(9)

          }

          6.8.2 等待一個消息隊列中的消息,OSQPend()

          程序清單L6.22是OSQPend()函數(shù)的源代碼。OSQPend()函數(shù)首先檢查事件控制塊是否是由OSQCreate()函數(shù)建立的[L6.22(1)],接著,該函數(shù)檢查消息隊列中是否有消息可用(即.OSQEntries是否大于0) [L6.22(2)]。 如果有, OSQPend()函數(shù)將指向消息的指針復(fù)制到msg變量中, 并讓.OSQOut指針指向隊列中的下一個單元[L6.22(3)],然后將隊列中的有效消息數(shù)減1[L6.22(4)]。因為消息隊列是一個循環(huán)的緩沖區(qū),OSQPend()函數(shù)需要檢查.OSQOut是否超過了

          隊列中的最后一個單元[L6.22(5)]。當(dāng)發(fā)生這種越界時,就要將.OSQOut重新調(diào)整到指向隊列的起始單元[L6.22(6)]。這是我們調(diào)用OSQPend()函數(shù)時所期望的,也是執(zhí)行OSQPend()函數(shù)最快的路徑。

          程序清單L6.22在一個消息隊列中等待一條消息

          void*OSQPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err)

          {

          void*msg;

          OS_Q*pq;

          OS_ENTER_CRITICAL();

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

          OS_EXIT_CRITICAL();

          *err=OS_ERR_EVENT_TYPE;

          return((void*)0);

          }

          pq=pevent->OSEventPtr;

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

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

          pq->OSQEntries--;(4)

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

          pq->OSQOut=pq->OSQStart;(6)

          }

          OS_EXIT_CRITICAL();

          *err=OS_NO_ERR;

          }elseif(OSIntNesting>0){(7)

          OS_EXIT_CRITICAL();

          *err=OS_ERR_PEND_ISR;

          }else{

          OSTCBCur->OSTCBStat|=OS_STAT_Q;(8)

          OSTCBCur->OSTCBDly=timeout;

          OSEventTaskWait(pevent);

          OS_EXIT_CRITICAL();

          OSSched();(9)

          OS_ENTER_CRITICAL();

          if((msg=OSTCBCur->OSTCBMsg)!=(void*)0){(10)

          OSTCBCur->OSTCBMsg=(void*)0;

          OSTCBCur->OSTCBStat=OS_STAT_RDY;

          OSTCBCur->OSTCBEventPtr=(OS_EVENT*)0;(11)

          OS_EXIT_CRITICAL();

          *err=OS_NO_ERR;

          }elseif(OSTCBCur->OSTCBStatOS_STAT_Q){(12)

          OSEventTO(pevent);(13)

          OS_EXIT_CRITICAL();

          msg=(void*)0;(14)

          *err=OS_TIMEOUT;

          }else{

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

          pq->OSQEntries--;

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

          pq->OSQOut=pq->OSQStart;

          }

          OSTCBCur->OSTCBEventPtr=(OS_EVENT*)0;(16)

          OS_EXIT_CRITICAL();

          *err=OS_NO_ERR;

          }

          }

          return(msg);(17)

          }

          如果這時消息隊列中沒有消息(.OSEventEntries是0),OSQPend()函數(shù)檢查它的調(diào)用者是否是中斷服務(wù)子程序[L6.22(7)]。象OSSemPend()和OSMboxPend()函數(shù)一樣,不能在中斷服務(wù)子程序中調(diào)用OSQPend(), 因為中斷服務(wù)子程序是不能等待的。 但是, 如果消息隊列中有消息,即使從中斷服務(wù)子程序中調(diào)用OSQPend()函數(shù),也一樣是成功的。

          如果消息隊列中沒有消息,調(diào)用OSQPend()函數(shù)的任務(wù)被掛起[L6.22(8)]。當(dāng)有其它的任

          務(wù)向該消息隊列發(fā)送了消息或者等待時間超時,并且該任務(wù)成為最高優(yōu)先級任務(wù)時,OSSched()

          返回[L6.22(9)]。這時,OSQPend()要檢查是否有消息被放到該任務(wù)的任務(wù)控制塊中[L6.22(10)]。如果有,那么該次函數(shù)調(diào)用成功,把任務(wù)的任務(wù)控制塊中指向消息隊列的指針刪除[L6.22(17)],并將對應(yīng)的消息被返回到調(diào)用函數(shù)[L6.22(17)]。

          在OSQPend()函數(shù)中,通過檢查任務(wù)的任務(wù)控制塊中的.OSTCBStat域,可以知道是否等到時間超時。如果其對應(yīng)的OS_STAT_Q位被置1,說明任務(wù)等待已經(jīng)超時[L6.22(12)]。這時,通過調(diào)用函數(shù)OSEventTo()可以將任務(wù)從消息隊列的等待任務(wù)列表中刪除[L6.22(13)]。這時,因為消息隊列中沒有消息,所以返回的指針是NULL[L6.22(14)]。

          如果任務(wù)控制塊標(biāo)志位中的OS_STAT_Q位沒有被置1,說明有任務(wù)發(fā)出了一條消息。

          OSQPend()函數(shù)從隊列中取出該消息[L6.22(15)]。然后,將任務(wù)的任務(wù)控制中指向事件控制塊的指針刪除[L6.22(16)]。

          6.8.3 向消息隊列發(fā)送一個消息(FIFO),OSQPost()

          程序清單L6.23是OSQPost()函數(shù)的源代碼。在確認(rèn)事件控制塊是消息隊列后

          [L6.23(1)],OSQPost()函數(shù)檢查是否有任務(wù)在等待該消息隊列中的消息[L6.23(2)]。當(dāng)事件控



          關(guān)鍵詞:

          評論


          相關(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); })();