標(biāo)題: uC/OS-II學(xué)習(xí)筆記—任務(wù)的刪除 [打印本頁]

作者: xueren    時間: 2013-7-18 20:04
標(biāo)題: uC/OS-II學(xué)習(xí)筆記—任務(wù)的刪除
任務(wù)狀態(tài)轉(zhuǎn)換圖如下所示:

一開始,任務(wù)在操作系統(tǒng)中是以函數(shù)代碼的形式存在的,在操作系統(tǒng)啟動的時候被加載到內(nèi)存中,并未運(yùn)行。并且,最開始的時候就緒表和就緒組是空的,或者說里面的內(nèi)容都是0。很明顯,這時候任務(wù)在內(nèi)存中睡眠,處于睡眠態(tài)。 如果不調(diào)用任務(wù)創(chuàng)建函數(shù)對任務(wù)進(jìn)行操作,該任務(wù)將永遠(yuǎn)處于睡眠態(tài)直到操作系統(tǒng)結(jié)束運(yùn)行,被清除出內(nèi)存。
任務(wù)的創(chuàng)建的學(xué)習(xí)中可以看到,任務(wù)創(chuàng)建的過程,首先分配一個空閑的TCB給任務(wù),然后對該TCB的各個域進(jìn)行賦值,對任務(wù)的堆棧進(jìn)行初始化,其中,任務(wù)的代碼的地址被壓入堆棧。這為以后任務(wù)的運(yùn)行做了充分的準(zhǔn)備。就緒表和就緒組做了適當(dāng)?shù)奶幚恚鶕?jù)任務(wù)的優(yōu)先級進(jìn)行了設(shè)置。就緒TCB鏈表也插入了該TCB。
那么,若將任務(wù)刪除,如上圖所示,很明顯是任務(wù)的逆過程,應(yīng)該將就緒表、就緒組進(jìn)行逆向的操作,就緒鏈表中的相關(guān)TCB應(yīng)該被移除,轉(zhuǎn)移到空閑TCB鏈表。和任務(wù)創(chuàng)建一,也要進(jìn)行一些檢查,看任務(wù)是否符合被刪除的條件。
任務(wù)刪除還涉及一個請求刪除的問題,因此任務(wù)刪除看似簡單,實(shí)際上是比較復(fù)雜的一個過程。
任務(wù)刪除函數(shù)的參數(shù)只有一個,這個參數(shù)就是任務(wù)的優(yōu)先級。 我們知道,任務(wù)的優(yōu)先級是uC/OS-II標(biāo)志任務(wù)的唯一標(biāo)志,任務(wù)控制塊中雖然也有一個ID,但只是為了擴(kuò)展使用。因此,任務(wù)刪除函數(shù)也可以理解為刪除指定優(yōu)先級的任務(wù)。程序代碼如下所示:


從任務(wù)刪除的代碼中可以看到,任務(wù)刪除遠(yuǎn)遠(yuǎn)不像想象中那么簡單。刪除一個任務(wù),就要照顧到該任務(wù)已經(jīng)影響到的方方面面,否則系統(tǒng)就可能崩潰。由于任務(wù)刪除的代碼很長,而在執(zhí)行的過程中一直在訪問全局變量,因此使系統(tǒng)不能響應(yīng)中斷,破壞系統(tǒng)實(shí)時性。因此,在代碼的中間,使用巧妙的手段開一次中斷,過程如下:
(1)將任務(wù)調(diào)度鎖加1。
(2)開中斷
(3)執(zhí)行一條空語句保證中斷有時間執(zhí)行。
(4)關(guān)中斷
(5)將調(diào)度鎖減1,恢復(fù)原來的值。
刪除任務(wù)的代碼盡管復(fù)雜,但無外乎先進(jìn)行參數(shù)的檢查,然后如果該任務(wù)在等待某些事件,就刪除等待的標(biāo)志,之后對TCB中的值進(jìn)行修改,對就緒表、就緒組、任務(wù)優(yōu)先級指針表、就緒任務(wù)鏈表、空閑任務(wù)鏈表等重要的數(shù)據(jù)結(jié)構(gòu)進(jìn)行與創(chuàng)建任務(wù)相反的操作,只不過中間因?yàn)榇a執(zhí)行時間過長,增加了臨時允許中斷的操作。

關(guān)于任務(wù)的刪除,除了這個直接刪除任務(wù)的函數(shù)之外,還有一個非常重要的請求刪除任務(wù)的函數(shù)——OSTaskDelReq。
當(dāng)以其他任務(wù)的優(yōu)先級作為參數(shù)的時候,OSTaskDel粗暴地刪除了任務(wù),這在某些情況下是有效的,但是卻不是必須這樣做。通知對方任務(wù),告訴它要刪除你了,請任務(wù)自己刪除自己是一種更好的做法。因?yàn)檫@么做,任務(wù)可以在刪除自己之前先放棄自己使用的資源,如緩沖區(qū)、信號量、郵箱、隊(duì)列等。如果總是用OSTaskDel刪除一個任務(wù),這個任務(wù)占用的資源不能得到釋放,系統(tǒng)就會產(chǎn)生內(nèi)存泄漏,在內(nèi)存泄漏累積到較大的時候,系統(tǒng)就會最后因?yàn)闆]有可用的內(nèi)存崩潰。
其實(shí),OSTaskDelReq名稱雖然是請求,卻是集請求與響應(yīng)于一段代碼內(nèi),該代碼的功能是請求刪除某任務(wù)和查看自己是否有任務(wù)要刪除自己。
例如,優(yōu)先級為5的任務(wù)A調(diào)用OSTaskDelReq(10),請求刪除優(yōu)先級為10的任務(wù)B。任務(wù)B調(diào)用OSTaskDelReq(OS_PRIO_SEL)并查看返回值,如果返回值為OS_ERR_TASK_DEL_REQ,說明有任務(wù)要求刪除自己了。任務(wù)B應(yīng)該先釋放自己使用的資源,然后調(diào)用OSTaskDel(10)或OSTaskDel(OS_PRIO_SEL)來刪除自己。代碼如下所示:

可見,請求刪除任務(wù)的代碼是比較少的,且前面一段是參數(shù)的檢查。后半部分的代碼根據(jù)參數(shù)不同,分別執(zhí)行判斷是否有請求參數(shù)標(biāo)志和給對方任務(wù)打上請求刪除標(biāo)志。





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1