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

          新聞中心

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

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

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

          程序清單L6.26清空消息隊(duì)列

          INT8UOSQFlush(OS_EVENT*pevent)

          {

          OS_Q*pq;

          OS_ENTER_CRITICAL();

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

          OS_EXIT_CRITICAL();

          return(OS_ERR_EVENT_TYPE);

          }

          pq=pevent->OSEventPtr;

          pq->OSQIn=pq->OSQStart;(2)

          pq->OSQOut=pq->OSQStart;

          pq->OSQEntries=0;

          OS_EXIT_CRITICAL();

          return(OS_NO_ERR);

          }

          6.8.7 查詢一個(gè)消息隊(duì)列的狀態(tài),OSQQuery()

          OSQQuery()函數(shù)使用戶可以查詢一個(gè)消息隊(duì)列的當(dāng)前狀態(tài)。 程序清單L6.27是該函數(shù)的源代碼。OSQQuery()需要兩個(gè)參數(shù):一個(gè)是指向消息隊(duì)列的指針pevent。它是在建立一個(gè)消息隊(duì)列時(shí),由OSQCreate()函數(shù)返回的;另一個(gè)是指向OS_Q_DATA(見uCOS_II.H)數(shù)據(jù)結(jié)構(gòu)的指針pdata。該結(jié)構(gòu)包含了有關(guān)消息隊(duì)列的信息。在調(diào)用OSQQuery()函數(shù)之前,必須先定義該數(shù)據(jù)結(jié)構(gòu)變量。OS_Q_DATA結(jié)構(gòu)包含下面的幾個(gè)域:

          .OSMsg 如果消息隊(duì)列中有消息,它包含指針.OSQOut所指向的隊(duì)列單元中的內(nèi)容。如果隊(duì)列是空的,.OSMsg包含一個(gè)NULL指針。

          .OSNMsgs是消息隊(duì)列中的消息數(shù)(.OSQEntries的拷貝)。

          .OSQSize 是消息隊(duì)列的總的容量

          .OSEventTbl[]和.OSEventGrp是消息隊(duì)列的等待任務(wù)列表。通過它們,OSQQuery()的調(diào)用函數(shù)可以得到等待該消息隊(duì)列中的消息的任務(wù)總數(shù)。

          OSQQuery()函數(shù)首先檢查pevent指針指向的事件控制塊是一個(gè)消息隊(duì)列[L6.27(1)],然后復(fù)制等待任務(wù)列表[L6.27(2)]。如果消息隊(duì)列中有消息[L6.27(3)],.OSQOut指向的隊(duì)列單元中的內(nèi)容被復(fù)制到OS_Q_DATA結(jié)構(gòu)中[L6.27(4)], 否則的話, 就復(fù)制一個(gè)NULL指針[L6.27(5)]。

          最后,復(fù)制消息隊(duì)列中的消息數(shù)和消息隊(duì)列的容量大小[L6.27(6)]。

          程序清單L6.27程序消息隊(duì)列的狀態(tài)

          INT8UOSQQuery(OS_EVENT*pevent,OS_Q_DATA*pdata)

          {

          OS_Q*pq;

          INT8Ui;

          INT8U*psrc;

          INT8U*pdest;

          OS_ENTER_CRITICAL();

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

          OS_EXIT_CRITICAL();

          return(OS_ERR_EVENT_TYPE);

          }

          pdata->OSEventGrp=pevent->OSEventGrp;(2)

          psrc=pevent->OSEventTbl[0];

          pdest=pdata->OSEventTbl[0];

          for(i=0;i

          *pdest++=*psrc++;

          }

          pq=(OS_Q*)pevent->OSEventPtr;

          if(pq->OSQEntries>0){(3)

          pdata->OSMsg=pq->OSQOut;(4)

          }else{

          pdata->OSMsg=(void*)0;(5)

          }

          pdata->OSNMsgs=pq->OSQEntries;(6)

          pdata->OSQSize=pq->OSQSize;

          OS_EXIT_CRITICAL();

          return(OS_NO_ERR);

          }

          6.8.8 使用消息隊(duì)列讀取模擬量的值

          在控制系統(tǒng)中,經(jīng)常要頻繁地讀取模擬量的值。這時(shí),可以先建立一個(gè)定時(shí)任務(wù)OSTimeDly()[見5.00節(jié),延時(shí)一個(gè)任務(wù),OSTimeDly()],并且給出希望的抽樣周期。然后,如圖F6.11所示,讓A/D采樣的任務(wù)從一個(gè)消息隊(duì)列中等待消息。該程序最長的等待時(shí)間就是抽樣周期。當(dāng)沒有其它任務(wù)向該消息隊(duì)列中發(fā)送消息時(shí),A/D采樣任務(wù)因?yàn)榈却瑫r(shí)而退出等待狀態(tài)并進(jìn)行執(zhí)行。這就模仿了OSTimeDly()函數(shù)的功能。

          也許,讀者會(huì)提出疑問,既然OSTimeDly()函數(shù)能完成這項(xiàng)工作,為什么還要使用消息隊(duì)列呢?這是因?yàn)?,借助消息?duì)列,我們可以讓其它的任務(wù)向消息隊(duì)列發(fā)送消息來終止A/D采樣任務(wù)等待消息,使其馬上執(zhí)行一次A/D采樣。此外,我們還可以通過消息隊(duì)列來通知A/D采樣程序具體對(duì)哪個(gè)通道進(jìn)行采樣,告訴它增加采樣頻率等等,從而使得我們的應(yīng)用更智能化。換句話說,我們可以告訴A/D采樣程序,“現(xiàn)在馬上讀取通道3的輸入值!”之后,該采樣任務(wù)將重新開始在消息隊(duì)列中等待消息,準(zhǔn)備開始一次新的掃描過程。

          圖F6.11讀模擬量輸入——Figure6.11

          6.8.9 使用一個(gè)消息隊(duì)列作為計(jì)數(shù)信號(hào)量

          在消息隊(duì)列初始化時(shí),可以將消息隊(duì)列中的多個(gè)指針設(shè)為非NULL值(如void*1),來實(shí)現(xiàn)計(jì)數(shù)信號(hào)量的功能。這里,初始化為非NULL值的指針數(shù)就是可用的資源數(shù)。系統(tǒng)中的任務(wù)可以通過OSQPend()來請(qǐng)求“信號(hào)量”,然后通過調(diào)用OSQPost()來釋放“信號(hào)量”,如程序清單L6.28。如果系統(tǒng)中只使用了計(jì)數(shù)信號(hào)量和消息隊(duì)列,使用這種方法可以有效地節(jié)省代碼空間。

          這時(shí)將OS_SEM_EN設(shè)為0,就可以不使用信號(hào)量,而只使用消息隊(duì)列。值得注意的是,這種方法

          為共享資源引入了大量的指針變量。也就是說,為了節(jié)省代碼空間,犧牲了RAM空間。另外,

          對(duì)消息隊(duì)列的操作要比對(duì)信號(hào)量的操作慢,因此,當(dāng)用計(jì)數(shù)信號(hào)量同步的信號(hào)量很多時(shí),這種

          方法的效率是非常低的。

          程序清單L6.28使用消息隊(duì)列作為一個(gè)計(jì)數(shù)信號(hào)量

          OS_EVENT*QSem;

          void*QMsgTbl[N_RESOURCES]

          voidmain(void)

          {

          OSInit();

          .

          QSem=OSQCreate(QMsgTbl[0],N_RESOURCES);

          for(i=0;i

          OSQPost(Qsem,(void*)1);

          }

          .

          .

          OSTaskCreate(Task1,..,..,..);

          .

          .

          OSStart();

          }

          voidTask1(void*pdata)

          {

          INT8Uerr;

          for(;;){

          OSQPend(QSem,0,err);/*得到對(duì)資源的訪問權(quán)*/

          .

          ./*任務(wù)獲得信號(hào)量,對(duì)資源進(jìn)行訪問*/

          .

          OSMQPost(QSem,(void*)1);/*釋放對(duì)資源的訪問權(quán)*/

          }

          }


          上一頁 1 2 3 4 5 6 7 8 9 10 11 下一頁

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