uCOS II 之事件控制塊學習

來源:互聯網
上載者:User
uCOS II 之事件控制塊學習時間:2007-06-04   來源:   作者:Mike zhong   點擊:1940  

一.   事件控制塊ECB資料結構:

typedef struct
{
  INT8U   OSEventType; //事件類型
  INT8U   OSEventGrp;  //等待任務所在的組
  INT16U  OSEventCnt;  //當事件是訊號量時的計數器
  void    *OSEventPtr;   //指向訊息或訊息佇列的指標
  INT8U OSEventTbl[OS_EVENT_TBL_SIZE];  //等待工作清單
} OS_EVENT; 

二.關鍵演算法:

1、將一個任務插入到等待事件的工作清單中:

   當調用函數OS_EventTaskWait( )使一個任務進入等待某事件發生時,需要此演算法,從而將任務插入到等待事件的工作清單中。

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

   pevent -> OSEventTbl[prio>>3]  = OSMapTbl[prio & 0x07];

2、從等待事件的工作清單中使任務脫離等待狀態:

當調用函數OS_EventTaskRdy( )使一個任務進入就緒態時,需要調用此演算法,從而使等待的任務脫離等待狀態進入就緒。

    if ((pevent -> OSEventTbl[prio >>3] &= ~OSMapTbl[prio & 0x07]) == 0)
    {
      pevent -> OSEventGrp &= ~OSMapTbl[prio >>3];
    }

3、在等待事件的工作清單中尋找優先順序最高的任務:

   當調用函數OS_EventTaskRdy( )使一個任務進入就緒態時,需要調用此演算法,從而首先找出在等待事件工作清單中最高優先順序的任務進入就緒狀態。

    y = OSUnMapTbl[pevent -> OSEventGrp];

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

    prio = (y << 3) + x;

三.對事件控制塊ECB的基本操作

1、初始化一個事件控制塊:

   函數OSSemCreate( ),OSMutexCreate( ),OSMboxCreate( ),OSQCreate( )建立時,必須調用此函數進行初始化,初始化一個空的等待列表,表中沒有任何等待事件的任務。

   OS_EventWaitListInit( );

2、使一個任務進入就緒態:

   當某個事件發生了時,要將事件等待工作清單中最高優先順序的任務進入就緒態,函數OSSemPost,OSMutexPost( ),OSMboxPost( ),OSQPost( )必將調用此函數從而使一個任務進入就緒態。

   OS_EventTaskRdy( );

3、使一個任務進入等待某事件發生:

   當某個任務須等待一個事件的發生時,訊號量、互斥型訊號量、郵箱、訊息佇列會通過相應的PEND函數來調用這個函數。

   OS_EventTaskWait( );

4、由於等待逾時而將任務置為就緒態:

   如果在預先指定的等待時間內任務等待的事件沒有發生,那麼PNED類型函數將會調用此函數從而將等待逾時的任務進入就緒態。

   OS_EventTo( );

四.事件控制塊ECB基本作業碼的分析。

1、OS_EventWaitListInit( );

 void OS_EventWaitListInit(OS_EVENT *pevent)
 {
    INT8U *ptbl;  //定義指標變數ptbl
    pevent -> OSEventGrp = 0x00; //清除任務所在的組

OS_EVENT_TBL_SIZE在UCOS_ II.H中定義大小
    ptbl  = &pevent -> OSEventTbl[0];

    #if OS_EVENT_TBL_SIZE > 0
        *ptbl++ = 0x00;      //清除等待工作清單,在這裡沒有使用for迴圈是為了節省系統開銷
    #endif

    #if OS_EVENT_TBL_SIZE > 1
        *ptbl++ = 0x00;
    #endif

    #if OS_EVENT_TBL_SIZE > 2
        *ptbl++ = 0x00;
    #endif

    #if OS_EVENT_TBL_SIZE > 3
        *ptbl++ = 0x00;
    #endif

    #if OS_EVENT_TBL_SIZE > 4
        *ptbl++ = 0x00;
    #endif

    #if OS_EVENT_TBL_SIZE > 5
        *ptbl++ = 0x00;
    #endif

    #if OS_EVENT_TBL_SIZE > 6
        *ptbl++ = 0x00;
    #endif

    #if OS_EVENT_TBL_SIZE > 7
        *ptbl++ = 0x00;
    #endif
}

2、OS_EventTaskRdy( );

    INT8U OS_EventTaskRdy(OS_EVENT *pevent, void *msg,INT8U msk)
    {
      OS_TCB *ptcb;
      INT8U  x;
      INT8U  y;

按照關鍵演算法3,在等待事件的工作清單中找到優先順序最高的任務,並確定其優先順序。

      INT8U  bitx;
      INT8U  bity;
      INT8U  prio;

      y = OSUnMapTbl[pevent -> OSEventGrp];     
      bity = OSMapTbl[y];
      x = OSUnMapTbl[pevent -> OSEventTbl[y]];

利用演算法2,從等待工作清單中刪除此優先順序最高的任務。

      bitx = OSMapTbl[x];
      prio = (INT8U)(( y << 3) + x);
      if ((pevent -> OSEventTbl[y] &= ~bitx) == 0x00)
        { pevent -> OSEventGrp &= ~bity;} 

      ptcb  = OSTCBPrioTbl[prio]; //知道了任務優先順序,從而找到任務控制塊的指標
      ptcb -> OSTCBDly     = 0;  //由於此任務已經不再等待事件的發生,因此直接清0
      ptcb -> OSTCBEventPtr = (OS_EVENT *)0;//由於不再等待事件的發生,使指向事件控制塊的指標指向NULL

      #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
          ptcb -> OSTCBMsg = msg;//如果此函數是郵箱或隊列POST函數調用的,則需要將傳遞來的參數放到它的任務控制塊中

        #else
          msg = msg;
        #endif

          ptcb -> OSTCBStat &= ~msk;
          if (ptcb -> OSTCBStat == OS_STAT_RDY)]
          {
            OSRdyGrp   |= bity;    ---最高優先順序的任務插入到就緒工作清單,由後續POST函數中的
            OSRdyTbl[y]  |= bitx;   ---OSSched( )函數進行調度使任務進入就緒,請參考第三章之就緒表
          }
          return (prio);
       }

3、OS_EventTaskWait( );

   void OS_EventTaskWait(OS_EVENT *pevent)
   {
     OSTCBCur -> OSTCBEventPtr = pevent;
     if (( OSRdyTbl[OSTCBCur -> OSTCBY] &= ~OSTCBCur->OSTCBBitx) == 0x00)
      { OSRdyGrp &= ~OSTCBCur -> OSTCBBity; } //如果在PEND函數中沒有收到有效訊號量,
//那麼將調用此函數進入睡眠態,在這裡將任務在任務就緒列表中刪除    

      pevent -> OSEventTbl[OSTCBCur -> OSTCBY] |= OSTCBCur -> OSTCBBitx;
      pevent -> OSEventGrp |= OSTCBCur -> OSTCBBity;//把此任務放到ECB的等待事件的工作清單中去
   }

 4、OS_EventTo( );
       void OS_EventTO (OS_EVENT *pevent)
       {
          if (( pevent -> OSEventTbl[OSTCBCur -> OSTCBY] &= ~OSTCBCur -> OSTCBBitx) ==0x00)
          { pevent -> OSEventGrp &= ~OSTCBCur -> OSTCBBitY; }//將逾時的任務在等待工作清單中刪除
          OSTCBCur -> OSTCBStat = OS_STAT_RDY; //任務置為就緒態
          OSTCBCur -> OSTCBEventPtr = (OS_EVENT *)0;
       }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.