找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 11126|回復(fù): 2
收起左側(cè)

uC/OS-II學(xué)習(xí)筆記—空閑鏈表和就緒鏈表

[復(fù)制鏈接]
ID:51773 發(fā)表于 2013-7-14 04:05 | 顯示全部樓層 |閱讀模式
uC/OS-II將任務(wù)控制塊分成兩個(gè)鏈表來(lái)管理,這就是空閑任務(wù)鏈表和就緒任務(wù)鏈表。其中,空閑任務(wù)鏈表包含了所有空閑的任務(wù)控制塊。所謂空閑任務(wù)控制塊,是指未分配給某個(gè)任務(wù)的任務(wù)控制塊。創(chuàng)建一個(gè)新任務(wù),前提條件就是系統(tǒng)中還有這樣的空閑任務(wù)塊。就緒鏈表則是將所有的就緒任務(wù)拴在一起,如果有新的任務(wù)就緒,就要將其任務(wù)控制塊從空閑鏈表中取出,加入到就緒鏈表中。
操作系統(tǒng)剛啟動(dòng)的時(shí)候,在沒(méi)有執(zhí)行主程序(Main)任何代碼之前,只有任務(wù)控制塊數(shù)組,還沒(méi)有空閑任務(wù)鏈表和就緒任務(wù)鏈表,或者說(shuō)這兩個(gè)鏈表都空著。這兩個(gè)鏈表是在操作系統(tǒng)的初始化程序OSInit中創(chuàng)建的。如下圖所示為系統(tǒng)初始化程序OSInit執(zhí)行后的空閑任務(wù)控制塊鏈表。

1.JPG
如圖可見(jiàn),全局變量OSTCBFreeList指向的是空閑鏈表的表頭,表尾的任務(wù)控制塊的OSTCBNext指向的是空地址,也就是說(shuō),如果OSTCBFreeList指向的是空地址,就沒(méi)有空閑的任務(wù)控制塊,不能創(chuàng)建新的任務(wù)。
既然OSTCBFreeList是指向任務(wù)控制塊的地址,定義如下:

2.JPG
就是這樣,指向任務(wù)控制塊的指針。因?yàn)樗c硬件無(wú)關(guān),所以在ucos_ii.h中定義。
如果OS_MAX_TASKS的值是14,也就是最多可以同時(shí)運(yùn)行14個(gè)用戶任務(wù),系統(tǒng)任務(wù)數(shù)是2,那么內(nèi)存中就有16個(gè)任務(wù)控制塊,從OSTCBTbl[0]到OSTCBTbl[15]。在操作系統(tǒng)沒(méi)有建立任何任務(wù)的時(shí)候,OSTCBFreeList指向OSTCBTbl[0], OSTCBTbl[0]的OSTCBNext指向OSTCBTbl[1],依此類(lèi)推。最后,OSTCBTbl[15]的OSTCBNext指向空地址。如果要?jiǎng)?chuàng)建一個(gè)新的任務(wù),就根據(jù)OSTCBFreeList找到一個(gè)任務(wù)控制塊。
當(dāng)我們創(chuàng)建第一個(gè)任務(wù)即空閑任務(wù)的時(shí)候,就從空閑控制塊鏈表中摘下一個(gè)任務(wù)控制塊給這個(gè)任務(wù)。當(dāng)然,這個(gè)控制塊隨即被插入就緒鏈表。很明顯,在沒(méi)有任務(wù)被創(chuàng)建的時(shí)候,就緒鏈表是空的。就緒鏈表的指針式OS_TCBList,它和OSTCBFreeList的定義方法是完全相同的:

3.JPG
第一個(gè)任務(wù)應(yīng)該是空閑任務(wù),如下圖所示就是完成了這一操作后的空閑鏈表和就緒鏈表。

4.JPG
當(dāng)創(chuàng)建第一個(gè)任務(wù)即空閑任務(wù)后,空閑鏈表和就緒鏈表如上圖所示,這時(shí)可以清楚地看到就緒鏈表包含了OSTCBTbl[0]一個(gè)控制塊,OSTCBList就只想這個(gè)任務(wù)控制塊,而該控制塊的前后指針都為0,即OSTCBNext=0,OSTCBPrev=0,表示前面和后面都沒(méi)有了,就緒鏈表只有這一個(gè)塊。比較一下,空閑鏈表的指針OSTCBFreeList現(xiàn)在指向OSTCBTbl[1]了,空閑鏈表比原來(lái)少了一個(gè)控制塊,OSTCBTbl[0]被分配了。
創(chuàng)建一個(gè)任務(wù)的過(guò)程,首先應(yīng)該查看OSTCBFreeList,看它是否為0,如果為0,說(shuō)明沒(méi)有空閑的任務(wù)控制塊可以分配了,于是不能創(chuàng)建新的任務(wù)。如果不是0,就將OSTCBFreeList指向的那個(gè)任務(wù)控制塊分配給新的任務(wù),將這個(gè)控制塊移動(dòng)到就緒鏈表,并將OSTCBFreeList指向原來(lái)的空閑鏈表中的下一個(gè)任務(wù)控制塊。
那么,如何將任務(wù)控制塊移動(dòng)到就緒鏈表呢?是插入到表頭還是表尾呢?
在上圖的基礎(chǔ)上我們?cè)趧?chuàng)建一個(gè)任務(wù)——統(tǒng)計(jì)任務(wù)。需要再?gòu)目臻e鏈表中移出一個(gè)任務(wù)控制塊到就緒鏈表中,結(jié)果如下圖所示:
5.JPG
當(dāng)再創(chuàng)建一個(gè)任務(wù)即統(tǒng)計(jì)任務(wù)后,OSTCBFreeList所指向的任務(wù)控制塊OSTCBTbl[1]就被分配給這個(gè)任務(wù),OSTCBFreeList就指向了OSTCBTbl[2]。形成如上圖所示的右半部分新的空閑鏈表。uC/OS-II將這個(gè)OSTCBTbl[2]插入就緒鏈表,方法是把它放在表頭而不是表尾,于是形成了如圖所示的左半部分新的就緒鏈表,原來(lái)在這個(gè)鏈表中OSTCBTbl[0]就到了表尾。這時(shí)候,OS_TCBList不再指向OSTCBTbl[0],而是指向OSTCBTbl[1]。需要注意的是,就緒鏈表是雙向鏈表,而空閑鏈表只是一個(gè)單項(xiàng)鏈表,從圖中很容易分辨這一點(diǎn)。
從圖中可以清楚地看出,OSTCBFreeList永遠(yuǎn)指向空閑鏈表的表頭,如果它為0,說(shuō)明沒(méi)有空閑任務(wù)控制塊了;OSTCBList永遠(yuǎn)指向就緒鏈表的表頭,如果它為0,說(shuō)明沒(méi)有就緒的任務(wù)了。

回復(fù)

使用道具 舉報(bào)

ID:302649 發(fā)表于 2019-5-17 08:39 | 顯示全部樓層
看著這個(gè)圖在就os_task.c    真的很給力
回復(fù)

使用道具 舉報(bào)

ID:598238 發(fā)表于 2019-8-9 10:59 | 顯示全部樓層
講的很清晰,樓主還是花了功夫。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表