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

          新聞中心

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

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

          作者: 時間:2016-10-08 來源:網絡 收藏

          表T6.1OSMapTbl[]

          從等待任務列表中刪除一個任務的算法則正好相反,如程序清單L6.3所示。

          程序清單L6.3從等待任務列表中刪除一個任務

          if((pevent->OSEventTbl[prio>>3]=~OSMapTbl[prio0x07])==0){

          pevent->OSEventGrp=~OSMapTbl[prio>>3];

          }

          該代碼清除了任務在.OSEventTbl[]中的相應位,并且,如果其所在的組中不再有處于等待該事件的任務時(即.OSEventTbl[prio>>3]為0),將.OSEventGrp中的相應位也清除了。和上面的由任務優(yōu)先級確定該任務在等待表中的位置的算法類似,從等待任務列表中查找處于等待狀態(tài)的最高優(yōu)先級任務的算法,也不是從.OSEventTbl[0]開始逐個查詢,而是采用了查找另一個表OSUnMapTbl[256](見文件OS_CORE.C)。這里,用于索引的8位分別代表對應的8組中有任務處于等待狀態(tài),其中的最低位具有最高的優(yōu)先級。用這個值索引,首先得到最高優(yōu)先級任務所在的組的位置(0~7之間的一個數)。然后利用.OSEventTbl[]中對應字節(jié)再在OSUnMapTbl[]中查找,就可以得到最高優(yōu)先級任務在組中的位置(也是0~7之間的一個數)。

          這樣,最終就可以得到處于等待該事件狀態(tài)的最高優(yōu)先級任務了。程序清單L6.4是該算法的具體實現代碼。

          程序清單L6.4在等待任務列表中查找最高優(yōu)先級的任務

          y=OSUnMapTbl[pevent->OSEventGrp];

          x=OSUnMapTbl[pevent->OSEventTbl[y]];

          prio=(y3)+x;

          舉例來說,如果.OSEventGrp的值是01101000(二進制),而對應的OSUnMapTbl[.OSEventGrp]值為3,說明最高優(yōu)先級任務所在的組是3。類似地,如果.OSEventTbl[3]的值是11100100(二進制),OSUnMapTbl[.OSEventTbl[3]]的值為2,則處于等待狀態(tài)的任務的最高優(yōu)先級是3×8+2=26。

          在μC/OS-II中,事件控制塊的總數由用戶所需要的信號量、郵箱和消息隊列的總數決定。

          該值由OS_CFG.H中的#defineOS_MAX_EVENTS定義。 在調用OSInit()時 (見3.11節(jié), μC/OS-II

          的初始化),所有事件控制塊被鏈接成一個單向鏈表——空閑事件控制塊鏈表(圖F6.3)。每

          當建立一個信號量、郵箱或者消息隊列時,就從該鏈表中取出一個空閑事件控制塊,并對它進

          行初始化。因為信號量、郵箱和消息隊列一旦建立就不能刪除,所以事件控制塊也不能放回到

          空閑事件控制塊鏈表中。

          圖F6.3空閑事件控制塊鏈表——Figure6.3

          對于事件控制塊進行的一些通用操作包括:

          y 初始化一個事件控制塊

          y 使一個任務進入就緒態(tài)

          y 使一個任務進入等待該事件的狀態(tài)

          y 因為等待超時而使一個任務進入就緒態(tài)

          為了避免代碼重復和減短程代碼長度,μC/OS-II將上面的操作用4個系統(tǒng)函數實現,它們是:OSEventWaitListInit(),OSEventTaskRdy(),OSEventWait()和OSEventTO()。

          6.2 初始化一個事件控制塊,OSEventWaitListInit()

          程序清單L6.5是函數OSEventWaitListInit()的源代碼。當建立一個信號量、郵箱或者消息隊列時,相應的建立函數OSSemInit(),OSMboxCreate(),或者OSQCreate()通過調用

          OSEventWaitListInit()對事件控制塊中的等待任務列表進行初始化。該函數初始化一個空的等

          待任務列表,其中沒有任何任務。該函數的調用參數只有一個,就是指向需要初始化的事件控

          制塊的指針pevent。

          程序清單L6.5初始化ECB塊的等待任務列表

          voidOSEventWaitListInit(OS_EVENT*pevent)

          {

          INT8Ui;

          pevent->OSEventGrp=0x00;

          for(i=0;i

          pevent->OSEventTbl[i]=0x00;

          }

          }

          6.3 使一個任務進入就緒態(tài),OSEventTaskRdy()

          程序清單L6.6是函數OSEventTaskRdy()的源代碼。當發(fā)生了某個事件,該事件等待任務列表中的最高優(yōu)先級任務(HighestPriorityTask–HPT)要置于就緒態(tài)時,該事件對應的OSSemPost(),OSMboxPost(),OSQPost(),和OSQPostFront()函數調用OSEventTaskRdy()實現該操作。換句話說,該函數從等待任務隊列中刪除HPT任務(HighestPriorityTask),并把該任務置于就緒態(tài)。圖F6.4給出了OSEventTaskRdy()函數最開始的4個動作。

          該函數首先計算HPT任務在.OSEventTbl[]中的字節(jié)索引[L6.6/F6.4(1)],其結果是一個從0到OS_LOWEST_PRIO/8+1之間的數,并利用該索引得到該優(yōu)先級任務在.OSEventGrp中的位屏蔽碼[L6.6/F6.4(2)](從表T6.1可以得到該值)。然后,OSEventTaskRdy()函數判斷HPT任務在.OSEventTbl[]中相應位的位置[L6.6/F6.4(3)], 其結果是一個從0到OS_LOWEST_PRIO/8+1

          之間的數,以及相應的位屏蔽碼[L6.6/F6.4(4)]。根據以上結果,OSEventTaskRdy()函數計算

          出HPT任務的優(yōu)先級[L6.6(5)],然后就可以從等待任務列表中刪除該任務了[L6.6(6)]。

          任務的任務控制塊中包含有需要改變的信息。知道了HPT任務的優(yōu)先級,就可以得到指向該任務的任務控制塊的指針[L6.6(7)]。因為最高優(yōu)先級任務運行條件已經得到滿足,必須停止OSTimeTick()函數對.OSTCBDly域的遞減操作,所以OSEventTaskRdy()直接將該域清澈0[L6.6(8)]。因為該任務不再等待該事件的發(fā)生,所以OSEventTaskRdy()函數將其任務控制塊中指向事件控制塊的指針指向NULL[L6.6(9)]。如果OSEventTaskRdy()是由OSMboxPost()或者OSQPost()調用的,該函數還要將相應的消息傳遞給HPT,放在它的任務控制塊中[L6.6(10)]。

          另外,當OSEventTaskRdy()被調用時,位屏蔽碼msk作為參數傳遞給它。該參數是用于對任務控制塊中的位清零的位屏蔽碼,和所發(fā)生事件的類型相對應[L6.6(11)]。最后,根據.OSTCBStat判斷該任務是否已處于就緒狀態(tài)[L6.6(12)]。如果是,則將HPT插入到μC/OS-II的就緒任務列表中[L6.6(13)]。注意,HPT任務得到該事件后不一定進入就緒狀態(tài),也許該任務已經由于其它



          關鍵詞:

          評論


          相關推薦

          技術專區(qū)

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