<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 實(shí)時(shí)系統中動(dòng)靜結合的內存管理實(shí)現

實(shí)時(shí)系統中動(dòng)靜結合的內存管理實(shí)現

作者:楊雷 吳玨 陳汶濱 時(shí)間:2008-08-29 來(lái)源:微計算機信息 收藏

摘要:提出了的一種實(shí)現方法。該方法采用動(dòng)靜結合的方式,給用戶(hù)提供了比較大的自由度,同時(shí)也提高了系統的靈活性。本文主要從實(shí)現方面進(jìn)行了詳細闡述。

本文引用地址:http://dyxdggzs.com/article/87548.htm

關(guān)鍵字:    

  1. 內存分配

  實(shí)時(shí)系統分為硬實(shí)時(shí)系統和軟實(shí)時(shí)系統。硬實(shí)時(shí)系統是指系統中各任務(wù)不僅要執行無(wú)誤而且要做到準時(shí);軟實(shí)時(shí)系統是指系統中各任務(wù)運行的越快越好,并不要求限定某一任務(wù)必須在多長(cháng)時(shí)間內完成。

  可以看出動(dòng)態(tài)內存分配是絕對不能用于硬實(shí)時(shí)系統的,因為動(dòng)態(tài)分配具有時(shí)間不確定性(分配時(shí)間與內存塊數量有關(guān)),而且動(dòng)態(tài)分配可能產(chǎn)生分配不成功的情況。所以對于硬實(shí)時(shí)系統,只能采用靜態(tài)內存分配方式。靜態(tài)分配是指在編譯或鏈接時(shí)將程序所需的內存空間分配好,這樣不會(huì )出現分配失敗的情況。

  其實(shí)對于大多數實(shí)時(shí)系統而言,內存分配都是采用兩種方式的結合,即動(dòng)靜結合的分配方式。

  2. 動(dòng)靜結合內存分配的一種實(shí)現

  對于整個(gè)內存,把它分為4個(gè)部分,即中斷向量區、系統映射區、系統內存區和用戶(hù)內存區。如圖1所示。

  其中中斷向量表和系統映射區在編譯時(shí)已經(jīng)設定好,即采用靜態(tài)分區的方式。剩下的兩個(gè)部分可以按用戶(hù)要求配置。

  2.1 系統內存區分區

  對于整個(gè)系統內存區,還需要要進(jìn)行分區操作,使它產(chǎn)生多個(gè)分區,每個(gè)分區中內存塊的大小相等,各個(gè)分區之間內存塊大小不等。這樣來(lái)滿(mǎn)足多種內存申請需求。

  2.1.1 系統分區類(lèi)結構定義

  系統建立了一個(gè)內存塊結構,它由一個(gè)指向下一個(gè)內存塊的指針構成,因為系統使用單向鏈表來(lái)管理空閑內存塊,所以必須用每個(gè)內存塊的這個(gè)指針來(lái)讓所有的空閑內存塊連成一個(gè)鏈表。                               

  結構如下:
  struct memblock
  {
  void * next;
  };

  對于內存分區,采用的方式,這樣減少了全局變量的使用,同時(shí)提高了可操作性。系統建立了內存分區類(lèi)結構。它包含了該分區的信號量、內存區的起始地址、內存塊大小、內存塊數量、空閑內存塊數量、空閑內存塊鏈表和鏈表尾部等。類(lèi)結構定義如下:

  class mempartition
  {
  private:
  semphore s;          //控制該內存分區的信號量
  public:
  long *start;         //塊起始位置
  void *freeulist;     //空閑內存塊鏈表 
  void *tail;          //空閑內存塊鏈表尾部 
  int unitsize;        //內存塊大小
  short unitnum;       //內存塊數量
  short freeunum;      //空閑內存塊數量
  mempartition();      //初始化鏈表、信號量
  void *GetUnit();        //獲取內存塊
  void PutUnit(void *);   //釋放內存塊
  };

  因為每個(gè)內存分區都是多任務(wù)共享的,每次只能有一個(gè)任務(wù)或中斷服務(wù)程序進(jìn)入該內存分區,所以需要設置信號量來(lái)管理它,當然也可以采用關(guān)中斷的方式,關(guān)中斷可能導致中斷響應延遲等問(wèn)題,所以沒(méi)有采用這種方式。

  2.1.2 系統分區的實(shí)現

  通過(guò)Partition_Create()函數創(chuàng )建一個(gè)內存分區,函數定義為
  int Partition_Create(mempartition *mp,unsigned int unum,unsigned int usize);

  mp為創(chuàng )建的內存分區,unum為該分區中內存塊數量,usize為內存塊大小。函數流程圖如圖2所示。

  對于塊內存的申請,采用c語(yǔ)言提供的malloc函數從內存中申請。這對于程序設計者而言提供了極大的方便,對于系統分區不適合應用(該實(shí)時(shí)系統設計應用于設備中)需求的情況下,可以刪除該分區另外再建立。不過(guò)這樣做的情況應該盡可能少,因為多次調用malloc/free會(huì )產(chǎn)生較多的內存碎片。在做設計時(shí),應該盡可能預先設定好分區數量和各個(gè)分區中內存塊的數量和大小,盡管系統提供了重建分區的功能。

  每個(gè)塊內存的第一部分存儲該分區對象,其后才是各個(gè)內存塊。在內存塊空閑時(shí),其內部存儲了下一個(gè)節點(diǎn)的的指針。分配以后,該信息丟失,直接分配給申請者,這樣省掉了存儲每個(gè)內存塊信息額外的RAM開(kāi)銷(xiāo)。內存釋放時(shí),直接加到該分區空閑內存鏈表的尾部,同時(shí)設定下一個(gè)節點(diǎn)內存塊信息為NULL。這樣在多次分配與釋放后,內存塊的位置會(huì )發(fā)生比較大的變化。

  系統設置了一個(gè)全局鏈表 mempartion **partition_list 來(lái)存儲所有的內存分區指針,該鏈表的長(cháng)度可以動(dòng)態(tài)定義。也就是說(shuō)分區的數量可以動(dòng)態(tài)定義。鏈表中的分區需要進(jìn)行排序,排序的標準是每個(gè)分區中內存塊的大小,內存塊小的分區排在前面,內存塊大的排在后面。因為分區采用首次適配的算法,排序以后可以減少內存浪費。

  同時(shí),系統提供了Mem_Alloc/Mem_Free兩個(gè)函數來(lái)支持系統分區的申請和釋放。申請的算法很簡(jiǎn)單,采用首次適配方法從分區鏈表中找到合適內存分區,如果該區空閑內存鏈表不為空,則返回該鏈表第一個(gè)內存塊地址,否則查看下一個(gè)分區。如果找不到合適的內存塊,則返回空指針。

  釋放算法稍微復雜一些,它需要先檢查該內存塊屬于哪個(gè)分區。這樣做非常必要,如果把一個(gè)小塊放到大塊的內存分區中,一個(gè)任務(wù)申請了該空間,則該空間的一部分將跨越到另一個(gè)內存塊,對該內存塊的操作可能覆蓋另一個(gè)內存塊的數據。如果把一個(gè)大塊放到了小塊的分區中,則在分配的時(shí)候將分配了多余的空間,造成了內存空間的浪費。找到所  圖2創(chuàng )建內存分區流程圖

  屬分區后,直接把該塊放到該區空閑內存鏈表的尾部。

  上述系統分區的方式其實(shí)是小范圍動(dòng)態(tài)分區上實(shí)現的靜態(tài)方式。因為每個(gè)內存塊大小是固定的,這樣不可避免地要浪費一部分空間。對于這個(gè)問(wèn)題的解決,系統還提供了一種純動(dòng)態(tài)的解決辦法,就是調用malloc/free函數來(lái)申請內存塊。

  2.1.3 內存用戶(hù)區的動(dòng)態(tài)內存分配

  從內存劃分圖中可以看到有一塊用戶(hù)內存區,這是一塊內核不會(huì )使用的內存區。該區留給用戶(hù)使用,對于這塊區域的申請和釋放不調用系統提供的Mem_Alloc/Mem_Free函數,而是直接調用c語(yǔ)言提供的malloc/free函數。malloc具有不確定性,因為它的執行時(shí)間和空閑內存塊的數量有關(guān),而且多次使用malloc/free調用和釋放內存塊,可能產(chǎn)生大量的內存碎片。所以這種方式的調用要謹慎。由于用戶(hù)內存區大小是可配置的,所以用戶(hù)可以控制該區大小以減少碎片產(chǎn)生的問(wèn)題。同時(shí)對于系統調用,例如任務(wù)堆棧分配,不會(huì )因為碎片太多而導致分配失敗的問(wèn)題。

  3. 小結

  動(dòng)靜結合的方式給用戶(hù)提供了比較大的自由度,用戶(hù)可以從系統分區中申請內存塊,也可以從用戶(hù)內存區申請內存塊。這樣增加了系統的靈活性,同時(shí)也限制了大量碎片產(chǎn)生的可能(在不頻繁刪除建立系統內存分區的前提下)。也增加了部分c代碼的可移植性。

  4. 參考文獻

  曾非一、桑 楠、熊光澤,系統方案研究。
  Jean J.Labrosse 著(zhù),邵貝貝 譯,μC/OS-Ⅱ源碼公開(kāi)的實(shí)時(shí)嵌入式操作系統,中國電力出版社,2001。
  William Stallings著(zhù),魏迎梅等譯,操作系統--內核與設計原理,電子工業(yè)出版社,2001。

  作者簡(jiǎn)介:
  楊雷:男,1977年12月6日,漢,碩士,計算機應用,實(shí)時(shí)操作系統設計。
  吳玨:女,1978年8月26日,漢,碩士,計算機應用,教學(xué)和研究。

  導師簡(jiǎn)介:
  陳汶濱,副教授,男,1965年5月1日,漢,碩士,計算機應用,教學(xué)和研究。

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>