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

          新聞中心

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

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

          圖 F4.1 內(nèi)存碎片

          μC/OS-Ⅱ支持的處理器的堆棧既可以從上(高地址)往下(低地址)長(zhǎng)也可以從下往上長(zhǎng)(參看4.02,任務(wù)堆棧)。用戶在調(diào)用OSTaskCreate()或OSTaskCreateExt()的時(shí)候必須知道堆棧是怎樣長(zhǎng)的,因?yàn)橛脩舯仨毜冒讯褩5臈m攤鬟f給以上兩個(gè)函數(shù),當(dāng)OS_CPU.H文件中的OS_STK_GROWTH置為0時(shí),用戶需要將堆棧的最低內(nèi)存地址傳遞給任務(wù)創(chuàng)建函數(shù),如程序清單4.7所示。

          程序清單 L4.7 堆棧從下往上遞增

          OS_STKTaskStack[TASK_STACK_SIZE];

          OSTaskCreate(task,pdata,TaskStack[0],prio);

          當(dāng)OS_CPU.H文件中的OS_STK_GROWTH置為1時(shí),用戶需要將堆棧的最高內(nèi)存地址傳遞給任務(wù)創(chuàng)建函數(shù),如程序清單4.8所示。

          程序清單 L4.8 堆棧從上往下遞減

          OS_STKTaskStack[TASK_STACK_SIZE];

          OSTaskCreate(task,pdata,TaskStack[TASK_STACK_SIZE-1],prio);

          這個(gè)問(wèn)題會(huì)影響代碼的可移植性。 如果用戶想將代碼從支持往下遞減堆棧的處理器中移植到支持往上遞增堆棧的處理器中的話,用戶得使代碼同時(shí)適應(yīng)以上兩種情況。在這種特殊情況下,程序清單L4.7和4.8可重新寫(xiě)成如程序清單L4.9所示的形式。

          程序清單 L4.9 對(duì)兩個(gè)方向增長(zhǎng)的堆棧都提供支持

          OS_STKTaskStack[TASK_STACK_SIZE];

          #ifOS_STK_GROWTH==0

          OSTaskCreate(task,pdata,TaskStack[0],prio);

          #else

          OSTaskCreate(task,pdata,TaskStack[TASK_STACK_SIZE-1],prio);

          #endif

          任務(wù)所需的堆棧的容量是由應(yīng)用程序指定的。 用戶在指定堆棧大小的時(shí)候必須考慮用戶的任務(wù)所調(diào)用的所有函數(shù)的嵌套情況,任務(wù)所調(diào)用的所有函數(shù)會(huì)分配的局部變量的數(shù)目,以及所有可能的中斷服務(wù)例程嵌套的堆棧需求。另外,用戶的堆棧必須能儲(chǔ)存所有的CPU寄存器。

          4.3 堆棧檢驗(yàn),OSTaskStkChk()

          有時(shí)候決定任務(wù)實(shí)際所需的堆棧空間大小是很有必要的。因?yàn)檫@樣用戶就可以避免為任務(wù)分配過(guò)多的堆棧空間,從而減少自己的應(yīng)用程序代碼所需的RAM(內(nèi)存)數(shù)量。μC/OS-Ⅱ提供的OSTaskStkChk()函數(shù)可以為用戶提供這種有價(jià)值的信息。

          在圖4.2中,筆者假定堆棧是從上往下遞減的(即OS_STK_GROWTH被置為1),但以下的討論也同樣適用于從下往上長(zhǎng)的堆棧[F4.2(1)]。μC/OS-Ⅱ是通過(guò)查看堆棧本身的內(nèi)容來(lái)決定堆棧的方向的。只有內(nèi)核或是任務(wù)發(fā)出堆棧檢驗(yàn)的命令時(shí),堆棧檢驗(yàn)才會(huì)被執(zhí)行,它不會(huì)自動(dòng)地去不斷檢驗(yàn)任務(wù)的堆棧使用情況。在堆棧檢驗(yàn)時(shí),μC/OS-Ⅱ要求在任務(wù)建立的時(shí)候堆棧中存儲(chǔ)的必須是0值(即堆棧被清零)[F4.2(2)]。另外,μC/OS-Ⅱ還需要知道堆棧棧底(BOS)的位置和分配給任務(wù)的堆棧的大小[F4.2(2)]。在任務(wù)建立的時(shí)候,BOS的位置及堆棧的這兩個(gè)值儲(chǔ)存在任務(wù)的OS_TCB中。

          為了使用μC/OS-Ⅱ的堆棧檢驗(yàn)功能,用戶必須要做以下幾件事情:

          z 在OS_CFG.H文件中設(shè)OS_TASK_CREATE_EXT為1。

          z 用OSTaskCreateExt()建立任務(wù),并給予任務(wù)比實(shí)際需要更多的內(nèi)存空間。

          z 在OSTaskCreateExt()中, 將參數(shù)opt設(shè)置為OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR。注意如果用戶的程序啟動(dòng)代碼清除了所有的RAM,并且從未刪除過(guò)已建立了的任務(wù),那么用戶就不必設(shè)置選項(xiàng)OS_TASK_OPT_STK_CLR了。這樣就會(huì)減少OSTaskCreateExt()的執(zhí)行時(shí)間。

          z 將用戶想檢驗(yàn)的任務(wù)的優(yōu)先級(jí)作為OSTaskStkChk()的參數(shù)并調(diào)用之。

          圖 4.2 堆棧檢驗(yàn)

          OSTaskStkChk()順著堆棧的棧底開(kāi)始計(jì)算空閑的堆棧空間大小, 具體實(shí)現(xiàn)方法是統(tǒng)計(jì)儲(chǔ)存值為0的連續(xù)堆棧入口的數(shù)目,直到發(fā)現(xiàn)儲(chǔ)存值不為0的堆棧入口[F4.2(5)]。注意堆棧入口的儲(chǔ)存值在進(jìn)行檢驗(yàn)時(shí)使用的是堆棧的數(shù)據(jù)類(lèi)型(參看OS_CPU.H中的OS_STK)。換句話說(shuō),如果堆棧的入口有32位寬,對(duì)0值的比較也是按32位完成的。所用的堆棧的空間大小是指從用戶在OSTaskCreateExt()中定義的堆棧大小中減去了儲(chǔ)存值為0的連續(xù)堆棧入口以后的大小。OSTaskStkChk()實(shí)際上把空閑堆棧的字節(jié)數(shù)和已用堆棧的字節(jié)數(shù)放置在0S_STK_DATA數(shù)據(jù)結(jié)構(gòu)中(參看μCOS_Ⅱ.H)。注意在某個(gè)給定的時(shí)間,被檢驗(yàn)的任務(wù)的堆棧指針可能會(huì)指向最初的堆棧棧頂(TOS)與堆棧最深處之間的任何位置[F4.2(7)]。 每次在調(diào)用OSTaskStkChk()的時(shí)候, 用戶也可能會(huì)因?yàn)槿蝿?wù)還沒(méi)觸及堆棧的最深處而得到不同的堆棧的空閑空間數(shù)。

          用戶應(yīng)該使自己的應(yīng)用程序運(yùn)行足夠長(zhǎng)的時(shí)間,并且經(jīng)歷最壞的堆棧使用情況,這樣才能得到正確的數(shù)。一旦OSTaskStkChk()提供給用戶最壞情況下堆棧的需求,用戶就可以重新設(shè)置堆棧的最后容量了。為了適應(yīng)系統(tǒng)以后的升級(jí)和擴(kuò)展,用戶應(yīng)該多分配10%-100%的堆棧空間。在堆棧檢驗(yàn)中,用戶所得到的只是一個(gè)大致的堆棧使用情況,并不能說(shuō)明堆棧使用的全部實(shí)際情況。

          OSTaskStkChk()函數(shù)的代碼如程序清單L4.10所示。0S_STK_DATA(參看μCOS_Ⅱ.H)數(shù)據(jù)結(jié)構(gòu)用來(lái)保存有關(guān)任務(wù)堆棧的信息。筆者打算用一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)達(dá)到兩個(gè)目的。第一,把OSTaskStkChk()當(dāng)作是查詢類(lèi)型的函數(shù),并且使所有的查詢函數(shù)用同樣的方法返回,即返回查詢數(shù)據(jù)到某個(gè)數(shù)據(jù)結(jié)構(gòu)中。第二,在數(shù)據(jù)結(jié)構(gòu)中傳遞數(shù)據(jù)使得筆者可以在不改變OSTaskStkChk()的API(應(yīng)用程序編程接口)的條件下為該數(shù)據(jù)結(jié)構(gòu)增加其它域,從而擴(kuò)展OSTaskStkChk()的功能。現(xiàn)在,0S_STK_DATA只包含兩個(gè)域:OSFree和OSUsed。從代碼中用戶可看到,通過(guò)指定執(zhí)行堆棧檢驗(yàn)的任務(wù)的優(yōu)先級(jí)可以調(diào)用OSTaskStkChk()。如果用戶指定0S_PRIO_SELF[L4.10(1)],那么就表明用戶想知道當(dāng)前任務(wù)的堆棧信息。當(dāng)然,前提是任務(wù)已經(jīng)存在[L4.10(2)]。要執(zhí)行堆棧檢驗(yàn),用戶必須已用OSTaskCreateExt()建立了任務(wù)并且已經(jīng)傳遞了選項(xiàng)OS_TASK_OPT_CHK[L4.10(3)]。如果所有的條件都滿足了,OSTaskStkChk()就會(huì)象前面描述的那樣從堆棧棧底開(kāi)始統(tǒng)計(jì)堆棧的空閑空間[L4.10(4)]。 最后,儲(chǔ)存在0S_STK_DATA中的信息就被確定下來(lái)了[L4.10(5)]。注意函數(shù)所確定的是堆棧的實(shí)際空閑字節(jié)數(shù)和已被占用的字節(jié)數(shù),而不是堆棧的總字節(jié)數(shù)。當(dāng)然,堆棧的實(shí)際大小(用



          關(guān)鍵詞:

          評(píng)論


          相關(guān)推薦

          技術(shù)專(zhuān)區(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); })();