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);
以上就是對碎片整理時記憶體處理方式的思考,應該還有一些問題沒解決,先這樣!