實時系統(tǒng)中動靜結(jié)合的內(nèi)存管理實現(xiàn)
摘要:提出了實時系統(tǒng)中內(nèi)存管理的一種實現(xiàn)方法。該方法采用動靜結(jié)合的方式,給用戶提供了比較大的自由度,同時也提高了系統(tǒng)的靈活性。本文主要從實現(xiàn)方面進行了詳細闡述。
本文引用地址:http://m.butianyuan.cn/article/87548.htm關(guān)鍵字: 實時系統(tǒng) 內(nèi)存管理 實時系統(tǒng)內(nèi)存分配
實時系統(tǒng)分為硬實時系統(tǒng)和軟實時系統(tǒng)。硬實時系統(tǒng)是指系統(tǒng)中各任務不僅要執(zhí)行無誤而且要做到準時;軟實時系統(tǒng)是指系統(tǒng)中各任務運行的越快越好,并不要求限定某一任務必須在多長時間內(nèi)完成。
可以看出動態(tài)內(nèi)存分配是絕對不能用于硬實時系統(tǒng)的,因為動態(tài)分配具有時間不確定性(分配時間與內(nèi)存塊數(shù)量有關(guān)),而且動態(tài)分配可能產(chǎn)生分配不成功的情況。所以對于硬實時系統(tǒng),只能采用靜態(tài)內(nèi)存分配方式。靜態(tài)分配是指在編譯或鏈接時將程序所需的內(nèi)存空間分配好,這樣不會出現(xiàn)分配失敗的情況。
其實對于大多數(shù)實時系統(tǒng)而言,內(nèi)存分配都是采用兩種方式的結(jié)合,即動靜結(jié)合的分配方式。
2. 動靜結(jié)合內(nèi)存分配的一種實現(xiàn)
對于整個內(nèi)存,把它分為4個部分,即中斷向量區(qū)、系統(tǒng)映射區(qū)、系統(tǒng)內(nèi)存區(qū)和用戶內(nèi)存區(qū)。如圖1所示。
其中中斷向量表和系統(tǒng)映射區(qū)在編譯時已經(jīng)設(shè)定好,即采用靜態(tài)分區(qū)的方式。剩下的兩個部分可以按用戶要求配置。
2.1 系統(tǒng)內(nèi)存區(qū)分區(qū)
對于整個系統(tǒng)內(nèi)存區(qū),還需要要進行分區(qū)操作,使它產(chǎn)生多個分區(qū),每個分區(qū)中內(nèi)存塊的大小相等,各個分區(qū)之間內(nèi)存塊大小不等。這樣來滿足多種內(nèi)存申請需求。
2.1.1 系統(tǒng)分區(qū)類結(jié)構(gòu)定義
系統(tǒng)建立了一個內(nèi)存塊結(jié)構(gòu),它由一個指向下一個內(nèi)存塊的指針構(gòu)成,因為系統(tǒng)使用單向鏈表來管理空閑內(nèi)存塊,所以必須用每個內(nèi)存塊的這個指針來讓所有的空閑內(nèi)存塊連成一個鏈表。
結(jié)構(gòu)如下:
struct memblock
{
void * next;
};
對于塊內(nèi)存的申請,采用c語言提供的malloc函數(shù)從內(nèi)存中申請。這對于程序設(shè)計者而言提供了極大的方便,對于系統(tǒng)分區(qū)不適合嵌入式應用(該實時系統(tǒng)設(shè)計應用于嵌入式設(shè)備中)需求的情況下,可以刪除該分區(qū)另外再建立。不過這樣做的情況應該盡可能少,因為多次調(diào)用malloc/free會產(chǎn)生較多的內(nèi)存碎片。在做設(shè)計時,應該盡可能預先設(shè)定好分區(qū)數(shù)量和各個分區(qū)中內(nèi)存塊的數(shù)量和大小,盡管系統(tǒng)提供了重建分區(qū)的功能。
每個塊內(nèi)存的第一部分存儲該分區(qū)對象,其后才是各個內(nèi)存塊。在內(nèi)存塊空閑時,其內(nèi)部存儲了下一個節(jié)點的的指針。分配以后,該信息丟失,直接分配給申請者,這樣省掉了存儲每個內(nèi)存塊信息額外的RAM開銷。內(nèi)存釋放時,直接加到該分區(qū)空閑內(nèi)存鏈表的尾部,同時設(shè)定下一個節(jié)點內(nèi)存塊信息為NULL。這樣在多次分配與釋放后,內(nèi)存塊的位置會發(fā)生比較大的變化。
系統(tǒng)設(shè)置了一個全局鏈表 mempartion **partition_list 來存儲所有的內(nèi)存分區(qū)指針,該鏈表的長度可以動態(tài)定義。也就是說分區(qū)的數(shù)量可以動態(tài)定義。鏈表中的分區(qū)需要進行排序,排序的標準是每個分區(qū)中內(nèi)存塊的大小,內(nèi)存塊小的分區(qū)排在前面,內(nèi)存塊大的排在后面。因為分區(qū)采用首次適配的算法,排序以后可以減少內(nèi)存浪費。
同時,系統(tǒng)提供了Mem_Alloc/Mem_Free兩個函數(shù)來支持系統(tǒng)分區(qū)的申請和釋放。申請的算法很簡單,采用首次適配方法從分區(qū)鏈表中找到合適內(nèi)存分區(qū),如果該區(qū)空閑內(nèi)存鏈表不為空,則返回該鏈表第一個內(nèi)存塊地址,否則查看下一個分區(qū)。如果找不到合適的內(nèi)存塊,則返回空指針。
釋放算法稍微復雜一些,它需要先檢查該內(nèi)存塊屬于哪個分區(qū)。這樣做非常必要,如果把一個小塊放到大塊的內(nèi)存分區(qū)中,一個任務申請了該空間,則該空間的一部分將跨越到另一個內(nèi)存塊,對該內(nèi)存塊的操作可能覆蓋另一個內(nèi)存塊的數(shù)據(jù)。如果把一個大塊放到了小塊的分區(qū)中,則在分配的時候?qū)⒎峙淞硕嘤嗟目臻g,造成了內(nèi)存空間的浪費。找到所 圖2創(chuàng)建內(nèi)存分區(qū)流程圖
屬分區(qū)后,直接把該塊放到該區(qū)空閑內(nèi)存鏈表的尾部。
上述系統(tǒng)分區(qū)的方式其實是小范圍動態(tài)分區(qū)上實現(xiàn)的靜態(tài)方式。因為每個內(nèi)存塊大小是固定的,這樣不可避免地要浪費一部分空間。對于這個問題的解決,系統(tǒng)還提供了一種純動態(tài)的解決辦法,就是調(diào)用malloc/free函數(shù)來申請內(nèi)存塊。
2.1.3 內(nèi)存用戶區(qū)的動態(tài)內(nèi)存分配
從內(nèi)存劃分圖中可以看到有一塊用戶內(nèi)存區(qū),這是一塊內(nèi)核不會使用的內(nèi)存區(qū)。該區(qū)留給用戶使用,對于這塊區(qū)域的申請和釋放不調(diào)用系統(tǒng)提供的Mem_Alloc/Mem_Free函數(shù),而是直接調(diào)用c語言提供的malloc/free函數(shù)。malloc具有不確定性,因為它的執(zhí)行時間和空閑內(nèi)存塊的數(shù)量有關(guān),而且多次使用malloc/free調(diào)用和釋放內(nèi)存塊,可能產(chǎn)生大量的內(nèi)存碎片。所以這種方式的調(diào)用要謹慎。由于用戶內(nèi)存區(qū)大小是可配置的,所以用戶可以控制該區(qū)大小以減少碎片產(chǎn)生的問題。同時對于系統(tǒng)調(diào)用,例如任務堆棧分配,不會因為碎片太多而導致分配失敗的問題。
3. 小結(jié)
動靜結(jié)合的方式給用戶提供了比較大的自由度,用戶可以從系統(tǒng)分區(qū)中申請內(nèi)存塊,也可以從用戶內(nèi)存區(qū)申請內(nèi)存塊。這樣增加了系統(tǒng)的靈活性,同時也限制了大量碎片產(chǎn)生的可能(在不頻繁刪除建立系統(tǒng)內(nèi)存分區(qū)的前提下)。也增加了部分c代碼的可移植性。
4. 參考文獻
曾非一、桑 楠、熊光澤,嵌入式系統(tǒng)內(nèi)存管理方案研究。
Jean J.Labrosse 著,邵貝貝 譯,μC/OS-Ⅱ源碼公開的實時嵌入式操作系統(tǒng),中國電力出版社,2001。
William Stallings著,魏迎梅等譯,操作系統(tǒng)--內(nèi)核與設(shè)計原理,電子工業(yè)出版社,2001。
作者簡介:
楊雷:男,1977年12月6日,漢,碩士,計算機應用,實時操作系統(tǒng)設(shè)計。
吳玨:女,1978年8月26日,漢,碩士,計算機應用,教學和研究。
導師簡介:
陳汶濱,副教授,男,1965年5月1日,漢,碩士,計算機應用,教學和研究。
評論