天天看點

MCU記憶體管理(碎片整理的可行性)MCU記憶體管理的一個想法(碎片整理的可行性)

MCU記憶體管理的一個想法(碎片整理的可行性)

前幾天搗鼓了下MCU的記憶體管理,自己用連結清單實作了一個。相同思路的程式網上一抓一大把。但是找了一圈都沒有發現能實作碎片整理。盡管MCU上記憶體管理就不常用,還用到碎片整理的基本沒有。但是用不用是一碼事,能不能是另一碼事。

這篇文章隻是我的一些想法和思路,可能思考的不全面且并未實踐過,不保證明際可行性。

要能實作碎片回收要做到兩件事。

1:空閑記憶體的查找,記憶體資料的移動。

2:記憶體移動後,原來的應用程式還能定位到它。

第1點不難,之前的記憶體管理方法都能實作。第2點是關鍵。正常的malloc程式,都是傳回一個位址給應用程式,一旦記憶體被移動,那如果應用程式還根據原來的位址找記憶體就不對了。

是以我想找一個不會變的标志替代指針傳回給應用程式。

typedef struct node  
{   
    u32  linkid;//記憶體塊id ,替代指針,傳回給應用程式 0表示失敗。
    u32 offset; //與記憶體首位址的偏移 
	u32 size;//本節點帶的記憶體大小 
    PNode Prior;//前一節點	
    PNode Pnext;//後一節點
}Node;
           

如上,在節點中引入一個id。該id在malloc階段生成,并傳回給應用程式,應用程式每次使用記憶體前,要周遊連結清單找到對應id的節點,該節點後的記憶體就是應用程式能用的記憶體。這樣碎片整理進行記憶體移動時,隻要保證本節點中的id不變,應用程式就能找到記憶體位址。僞代碼邏輯如下。

// u32 malloc(size);
//void *GetMenaddr(id)
//void free(id)
   u32 id = malloc(1024);
   u8 *p1 ;
   p1= (u8*)GetMenaddr(id);
   /*
   .......
   */
      u8 *p2 ;
   p2= (u8*)GetMenaddr(id);
      /*
   .......
   */
   free(id);
           

但是上述方式如果在記憶體被任務程式使用過程中,任務程式被打斷進入記憶體整理,然後傳回繼續執行任務程式。這樣就會有問題。因為在GetMenaddr後,應用程式處理的就是指針。如果被中斷進性記憶體整理,那指針所指的資料就已經被搬移。是以還要做一些處理。

typedef struct node  
{   
    u32  linkid;//記憶體塊id ,替代指針,傳回給應用程式
    u32  state; //狀态 記憶體是否鎖定。
    u32 offset; //與記憶體首位址的偏移 
	u32 size;//本節點帶的記憶體大小 
    PNode Prior;//前一節點	
    PNode Pnext;//後一節點
}Node;
           

加入一個鎖定标志,碎片整理程式先判斷該節點的記憶體是否是被鎖定的,是的話就不對該節點進性整理。僞代碼邏輯如下。

// u32 malloc(size);
//void MenLock(id);
//void *GetMenaddr(id)
//void MenUnlock(id);
//void *GetMenaddr(id)
//void free(id)
   u32 id = malloc(1024);
   MenLock(id);
   u8 *p1 ;
   p1= (u8*)GetMenaddr(id);
   /*
   .......
   */
    MenUnlock(id);
    //這之後允許碎片整理任務整理該id對應的記憶體
    /*
    ...
    */
     MenLock(id);
      u8 *p2 ;
   p2= (u8*)GetMenaddr(id);
      /*
   .......
   */
   MenUnlock(id);
   free(id);
           

以上就是對碎片整理時記憶體處理方式的思考,應該還有一些問題沒解決,先這樣!

繼續閱讀