μC/OS之OSTaskCreate()

轉自 http://blog.csdn.net/xiaocaichonga/article/details/7449409


建立任務OSTaskCreate()
1.OSTaskCreate()函數的聲明
    INT8U OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK *ptos,INT8U prio)
     1.1返回類型 INT8U
     1.2參數:4個參數,分別是指向任務代碼段的函數指針task,指向任務數據的指針pdata,指向任務所分配的堆棧的棧頂指針ptos,以及任務的優先級prio
2.OSTaskCreate()函數的定義
     INT8U OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK *ptos,INT8U prio)
     {
         void *psp;                             /*用於指向任務堆棧初始化後棧頂的指針*/
         INT8U err;                             /*用於存放任務TCB初始化後返回的值*/
 
         if(prio>OS_LOWEST_PRIO)                /*判斷任務的優先級是否在允許的範圍內,即如果該任務的優先級比系統的空閒優先級*/
         {                                       /*都低的話,那麼就出錯了*/
             return (OS_PRIO_INVALID)            /*返回優先級不可得*/
         }
         OS_ENTER_CRITICAL();
         if (OSTCBPrioTbl[prio]==(OS_TCB *)0)   /*判斷所分配的優先級是否已經被其他任務佔用,(OS_TCB)*0 表示沒有佔用*/
         {
             OSTCBPrioTbl[prio]=(OS_TCB *)1;    /*將新分配的優先級在OSTCBPrioTbl[]中更改爲已佔用狀態即(OS_TCB)*1,注意:
             OS_EXIT_CRITICAL();                /*在(OS_TCB)*1狀態下表示僅僅被佔用,但是並沒有爲任務分配資源等操作*/
             psp=(void *)OSTaskStkInit(task,pdata,ptos,0);/*將任務堆棧進行初始化,並返回初始化後的棧頂指針給psp*/  
                                                          /*注意任務堆棧的初始化函數的參數:①代碼段指針②數據段指針③堆棧的棧頂*/
             err=OSTCBInit(prio,psp,(void *)0,0,0,(void*0),0);/*TCB的初始化,注意傳入的參數:①任務的優先級即任務的標識符②堆棧初始化後的棧頂指針*/
             if(err==OS_NO_ERR)                              /*如果TCB初始化成功*/
             {
                OS_ENTER_CRITICAL();
                OSTaskCtr++;                                 /*則將系統中的進程數加1*/
                OSTaskCreateHook(OSTCBPrioTbl[prio]);        /*新建任務的擴展功能,可以由用戶自行定義,但是代碼不能太長,因爲此時中斷關閉*/
                OS_EXIT_CRITICAL();
                if(OSRunning)                               /*判斷任務建立時,系統中是否有其他任務在運行,即系統是否已經OSStart()了*/
                   {
                      OSSched();                           /*如果系統中已經有其他任務運行,則用任務調度函數OSSched()進行任務調度*/
                   }
              }
              else
              {
                 OS_ENTER_CRITICAL();
                 OSTCBPrioTble[prio]=(OS_TCB *)0;          /*如果TCB初始化失敗,則將本來佔用的OSTCBPrioTble[]中對應的位標識爲此優先級未被使用*/
                 OS_EXIT_CRITICAL();
              }
              return (err);                                /*在判斷優先級在於規定範圍內的情況下,無論TCB初始化是成功還是失敗,都將返回TCB初始化的值*/
           }
           else
           {
               OS_EXIT_CRITICAL();
               return (OS_PRIO_EXIST);                    /*如果此優先級已經被佔用,則返回OS_PRIO_EXIST,以告訴系統和用戶優先級已被佔用*/
            }
      }
    
    
3.小結
任務的建立函數OSTaskCreate()到底做了哪些事情呢?    
①判斷任務的優先級;
②系統的OSTCBPrioTbl[];
③任務堆棧的初始化;
④任務TCB的初始化。    


執行過程:第一步,判斷任務的優先級是否越界,如果越界則返回失敗,如果沒越界進行下一步;
          第二步,判斷任務的優先級是否已經被佔用,如果被佔用則返回失敗,如果沒有被佔用進行下一步;
          第三步,對OSTCBPrioTbl[]相應位置1,表明此優先級被使用了;
          第四步,任務堆棧的初始化;
          第五步,任務TCB的初始化,無論初始化失敗還是成功,都將TCB初始化的返回值返回給OSTaskCreate();
          第六步,如果TCB初始化失敗了,則將OSTCBPrioTbl[]中的相應位再清0,以表明此優先級沒被使用;如果TCB初始化成功了
                  則將系統中的任務數加1,並進行下一步;
          第七步,盤對系統是否已經處於運行狀態,如果處於運行狀態則進行任務調度。


注意:1.OSTaskCreate()的四個參數分別做了什麼:
      ①task,pdata和ptos用於了任務堆棧的初始化,即要對任務的代碼指針,數據指針,根據當前分配的棧頂繼續壓棧
      ②prio用於了PCB的初始化。
      2.對於OSTCBPrioTbl[]的理解,該表中的元素是指向TCB的指針,當該指針爲(OS_TCB *)0時標明該位對應的優先級並未被使用,
      該爲不爲(OS_TCB *)0時,標明該位對應的優先級被使用,至於使用的情況還要分爲兩種:
      ①(OS_TCB *)1時,標明該優先級被佔用但是並沒說明該優先級對應哪個TCB;
      ②指名該優先級被佔用並且指向對應的TCB,這部分在TCB的初始化中完成了。
            

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章