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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應用 > μC/OS-II的任務(wù)管理

          μC/OS-II的任務(wù)管理

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

          INT16Ui;

          OS_STK*pfill;

          if(prio>OS_LOWEST_PRIO){(1)

          return(OS_PRIO_INVALID);

          }

          OS_ENTER_CRITICAL();

          if(OSTCBPrioTbl[prio]==(OS_TCB*)0){(2)

          OSTCBPrioTbl[prio]=(OS_TCB*)1;(3)

          OS_EXIT_CRITICAL();(4)

          if(optOS_TASK_OPT_STK_CHK){(5)

          if(optOS_TASK_OPT_STK_CLR){

          Pfill=pbos;

          for(i=0;i

          #ifOS_STK_GROWTH==1

          *pfill++=(OS_STK)0;

          #else

          *pfill--=(OS_STK)0;

          #endif

          }

          }

          }

          psp=(void*)OSTaskStkInit(task,pdata,ptos,opt);(6)

          err=OSTCBInit(prio,psp,pbos,id,stk_size,pext,opt);(7)

          if(err==OS_NO_ERR){(8)

          OS_ENTER_CRITICAL;

          OSTaskCtr++;(9)

          OSTaskCreateHook(OSTCBPrioTbl[prio]);(10)

          OS_EXIT_CRITICAL();

          if(OSRunning){(11)

          OSSched();(12)

          }

          }else{

          OS_ENTER_CRITICAL();

          OSTCBPrioTbl[prio]=(OS_TCB*)0;(13)

          OS_EXIT_CRITICAL();

          }

          return(err);

          }else{

          OS_EXIT_CRITICAL();

          return(OS_PRIO_EXIST);

          }

          }

          OSTaskCreateExt()一開始先檢測分配給任務(wù)的優(yōu)先級是否有效[L4.3(1)]。 任務(wù)的優(yōu)先級必須在0到OS_LOWEST_PRIO之間。接著,OSTaskCreateExt()要確保在規(guī)定的優(yōu)先級上還沒有建立任務(wù)[L4.3(2)]。在使用μC/OS-Ⅱ時,每個任務(wù)都有特定的優(yōu)先級。如果某個優(yōu)先級是空閑的,μC/OS-Ⅱ通過放置一個非空指針在OSTCBPrioTbl[]中來保留該優(yōu)先級[L4.3(3)]。這就使得OSTaskCreateExt()在設(shè)置任務(wù)數(shù)據(jù)結(jié)構(gòu)的其他部分時能重新允許中斷[L4.3(4)]。

          為了對任務(wù)的堆棧進行檢驗[參看4.03,堆棧檢驗,OSTaskStkChk()],用戶必須在opt參數(shù)中設(shè)置OS_TASK_OPT_STK_CHK標志。 堆棧檢驗還要求在任務(wù)建立時堆棧的存儲內(nèi)容都是0(即堆棧已被清零)。為了在任務(wù)建立的時候?qū)⒍褩G辶?,需要在opt參數(shù)中設(shè)置OS_TASK_OPT_STK_CLR。當以上兩個標志都被設(shè)置好后,OSTaskCreateExt()才能將堆棧清零[L4.3(5)]。

          接著,OSTaskCreateExt()調(diào)用OSTaskStkInit()[L4.3(6)],它負責建立任務(wù)的堆棧。該函數(shù)是與處理器的硬件體系相關(guān)的函數(shù),可以在OS_CPU_C.C文件中找到。有關(guān)實現(xiàn)OSTaskStkInit()的細節(jié)可參看第八章——移植μC/OS-Ⅱ。如果已經(jīng)有人在你用的處理器上成功地移植了μC/OS-Ⅱ,而你又得到了他的代碼,就不必考慮該函數(shù)的實現(xiàn)細節(jié)了。

          OSTaskStkInit()函數(shù)返回新的堆棧棧頂(psp),并被保存在任務(wù)的0S_TCB中。

          μC/OS-Ⅱ支持的處理器的堆棧既可以從上(高地址)往下(低地址)遞減也可以從下往上遞增(參看4.02,任務(wù)堆棧)。用戶在調(diào)用OSTaskCreateExt()的時候必須知道堆棧是遞增的還是遞減的(參看用戶所用處理器的OS_CPU.H中的OS_STACK_GROWTH),因為用戶必須得把堆棧的棧頂傳遞給OSTaskCreateExt(),而棧頂可能是堆棧的最低地址(當OS_STK_GROWTH

          為0時),也可能是最高地址(當OS_STK_GROWTH為1時)。

          一旦OSTaskStkInit()函數(shù)完成了建立堆棧的任務(wù),OSTaskCreateExt()就調(diào)用

          OSTCBInit()[L4.3(7)], 從空閑的OS_TCB緩沖池中獲得并初始化一個OS_TCB。 OSTCBInit()

          的代碼在OSTaskCreate()中曾描述過(參看4.00節(jié)),從OSTCBInit()返回后,

          OSTaskCreateExt()要檢驗返回代碼[L4.3(8)],如果成功,就增加OSTaskCtr[L4.3(9)],

          OSTaskCtr用于保存產(chǎn)生的任務(wù)數(shù)目。 如果OSTCBInit()返回失敗, 就置OSTCBPrioTbl[prio]

          的入口為0[L4.3(13)]以放棄對該任務(wù)優(yōu)先級的占用。然后,OSTaskCreateExt()調(diào)用

          OSTaskCreateHook()[L4.3(10)],OSTaskCreateHook()是用戶自己定義的函數(shù),用來擴展

          OSTaskCreateExt()的功能。OSTaskCreateHook()可以在OS_CPU_C.C中定義(如果

          OS_CPU_HOOKS_EN置1),也可以在其它地方定義(如果OS_CPU_HOOKS_EN置0)。注意,

          OSTaskCreateExt()在調(diào)用OSTaskCreateHook()時,中斷是關(guān)掉的,所以用戶應該使

          OSTaskCreateHook()函數(shù)中的代碼盡量簡化,因為這將直接影響中斷的響應時間。

          OSTaskCreateHook()被調(diào)用時會收到指向任務(wù)被建立時的OS_TCB的指針。這意味著該函數(shù)可以訪問OS_TCB數(shù)據(jù)結(jié)構(gòu)中的所有成員。

          如果OSTaskCreateExt()函數(shù)是在某個任務(wù)的執(zhí)行過程中被調(diào)用的(即OSRunning置為

          True[L4.3(11)]),以任務(wù)調(diào)度函數(shù)會被調(diào)用[L4.3(12)]來判斷是否新建立的任務(wù)比原來的任務(wù)有更高的優(yōu)先級。如果新任務(wù)的優(yōu)先級更高,內(nèi)核會進行一次從舊任務(wù)到新任務(wù)的任務(wù)切換。如果在多任務(wù)調(diào)度開始之前(即用戶還沒有調(diào)用OSStart()),新任務(wù)就已經(jīng)建立了,則任務(wù)調(diào)度函數(shù)不會被調(diào)用。

          4.2任務(wù)堆棧

          每個任務(wù)都有自己的堆??臻g。堆棧必須聲明為OS_STK類型,并且由連續(xù)的內(nèi)存空間組成。用戶可以靜態(tài)分配堆??臻g(在編譯的時候分配)也可以動態(tài)地分配堆??臻g(在運行的時候分配)。靜態(tài)堆棧聲明如程序清單L4.4和4.5所示,這兩種聲明應放置在函數(shù)的外面。

          程序清單 L4.4 靜態(tài)堆棧

          staticOS_STKMyTaskStack[stack_size];

          程序清單 L4.5 靜態(tài)堆棧

          OS_STKMyTaskStack[stack_size];

          用戶可以用C編譯器提供的malloc()函數(shù)來動態(tài)地分配堆??臻g,如程序清單L4.6所示。在動態(tài)分配中,用戶要時刻注意內(nèi)存碎片問題。特別是當用戶反復地建立和刪除任務(wù)時,內(nèi)存堆中可能會出現(xiàn)大量的內(nèi)存碎片,導致沒有足夠大的一塊連續(xù)內(nèi)存區(qū)域可用作任務(wù)堆棧,這時malloc()便無法成功地為任務(wù)分配堆??臻g。

          程序清單 LL4.6 用malloc()為任務(wù)分配堆??臻g

          OS_STK*pstk;

          pstk=(OS_STK*)malloc(stack_size);

          if(pstk!=(OS_STK*)0){/* 確認malloc()能得到足夠地內(nèi)存空間 */

          Createthetask;

          }

          圖4.1表示了一塊能被malloc()動態(tài)分配的3K字節(jié)的內(nèi)存堆[F4.1(1)]。為了討論問題方便,假定用戶要建立三個任務(wù)(任務(wù)A,B和C),每個任務(wù)需要1K字節(jié)的空間。設(shè)第一個1K字節(jié)給任務(wù)A,第二個1K字節(jié)給任務(wù)B,第三個1K字節(jié)給任務(wù)C[F4.1(2)]。然后,用戶的應用程序刪除任務(wù)A和任務(wù)C,用free()函數(shù)釋放內(nèi)存到內(nèi)存堆中[F4.1(3)]。現(xiàn)在,用戶的內(nèi)存堆雖有2K字節(jié)的自由內(nèi)存空間,但它是不連續(xù)的,所以用戶不能建立另一個需要2K字節(jié)內(nèi)存的任務(wù)(即任務(wù)D)。如果用戶并不會去刪除任務(wù),使用malloc()是非常可行的。



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