主要是依照原子哥哥的代碼來(lái)初步了解或者說(shuō)學(xué)習一下內存管理,特別對于我們這個(gè)想往嵌入式方向發(fā)展的人來(lái)說(shuō),內存管理應該是一種藝術(shù)的。今天在對原子的代碼稍作修改是可以進(jìn)行內存分配和回收的,所以開(kāi)始深入分析一下這個(gè)代碼的實(shí)現過(guò)程。一、所謂的內存管理內存管理,是指軟件運行時(shí)對計算機內存資源的分配和使用的技術(shù)。其最主要的目的是如何高效,快速的分配,并且在適當的時(shí)候釋放和回收內存資源。
本文引用地址:http://dyxdggzs.com/article/201612/324495.htm二、代碼分析
1、首先了解一下一個(gè)數據結構,這是一個(gè)聲明
/*************************** 內存管理控制 **********************************************/ typedef struct {void (*init)(u8);//初始化u8 (*perused)(u8); //內存使用率u8 *membase[2];//內存池 管理2個(gè)區域的內存u16 *memmap[2]; //內存管理狀態(tài)表u8 memrdy[2]; //內存管理是否就緒}_m_mallco_dev;
成員包括兩個(gè)函數指針(該指針指向函數),兩個(gè)指針數組和一個(gè)u8類(lèi)型的數組,具體分析下這幾個(gè)成員的含義,那么首先要找到這個(gè)
_m_mallco_dev mallco_dev={mem_init,//內存初始化mem_perused,//內存使用率mem1base,mem2base,//內存池 mem1mapbase,mem2mapbase,//內存管理狀態(tài)表0,0, //內存管理未就緒};這才是真正定義的地方,現在就可以了解這個(gè)幾個(gè)成員的具體功能了。
a、初始化中 mem_init,mem_perused,這是兩個(gè)函數,為什么可以這樣用呢(直接用函數名)?
可以這樣理解么,函數名就像數組名一樣,只不過(guò)函數名是代碼段的指針,而數組名是數據段的指針 ,所以這里函數名就是給函數指針賦值了。當然函數指針并不能說(shuō)是等于指針的,就像數組一樣,數組名不等于指針的??倳?shū)記和主席還是不一樣的。所以暫時(shí)可以這樣理解,函數名雖然代表了一個(gè)地址,但是這個(gè)值是確定了的,但是指針是可以指向別的地址的。就這樣!這樣寫(xiě)只不過(guò)是為了方便我們訪(fǎng)問(wèn)罷了??梢园醋约旱男枰薷?!
那么這兩個(gè)函數的作用?這才是我們最關(guān)心的,看這個(gè)
void mem_init(u8 memx) { mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//內存狀態(tài)表數據清零 mymemset(mallco_dev.membase[memx], 0,memsize[memx]);//內存池所有數據清零 mallco_dev.memrdy[memx]=1;//內存管理初始化OK } b、注釋很明確,那么接下來(lái)就是分析這個(gè)三句話(huà)的作用,沒(méi)辦法,我無(wú)法做到,一眼能看出究竟。
mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);等價(jià)于mymemset(mem1base, 0,0x500*2)
它里面的內容很簡(jiǎn)單就是
void mymemset(void *s,u8 c,u32 count) { u8 *xs = s; while(count--)*xs++=c; }以mem1base為首地址的大小為0xa00的內容清0,那么mem1base又是什么呢?接下來(lái)看看
__align(4) u8 mem1base[MEM1_MAX_SIZE];這明顯是4字節對齊的內部SRAM的地址,也就是我們的flash里面的地址。所以這就實(shí)現了對我們內部flash0xa00的內容清零,好的繼續看下面的
c、 mymemset(mallco_dev.membase[memx], 0,memsize[memx]);//內存池所有數據清零
自然地這個(gè)也是一個(gè)意思,清零,唯一不同的就是代表的意思不一樣,到底是內存池數據清零,還是狀態(tài)表的清零,我們看不出來(lái),那么只有繼續分析了。清零完成就給相應的數組元素填充1表示完成標志。至此我們第一個(gè)初始化成員就分析完畢??!
2、下面開(kāi)始分析第二個(gè)成員perused函數
先看函數如何定義的/***************************************************************************************
名 稱(chēng): mem_perused
* 功 能: 獲取內存使用率
* 參 數: *memx:所屬內存塊
* 返 回 值: 使用率(0~100)**************************************************************************************
/u8 mem_perused(u8 memx)
{ u32 used=0; u32 i;
for(i=0;i{ if(mallco_dev.memmap[memx][i])used++;
} return (used*100)/(memtblsize[memx]);
} 這里可以看到出現一個(gè)這樣的表達式,需要仔細分析!mallco_dev.memmap[memx][i]
分解一下,還是一樣,這個(gè)是指針數組,也就是數組里面存放的是指針,那么這里給它賦值為一個(gè)數組名mem1mapbase,但是訪(fǎng)問(wèn)的時(shí)候還是可以用下表來(lái)訪(fǎng)問(wèn)的。那么可以替換為:if(mem1mapbase[i]) used++;看到?jīng)],這還是我們之前訪(fǎng)問(wèn)過(guò)了的那個(gè)數組,只不過(guò)這里是當非零的時(shí)候執行used++,也就是我們占用了才會(huì )進(jìn)行++。那么作用就是:used表示的是占用了的大小。(used*100)/(memtblsize[memx])表示的就是占用值,memtblsize[memx]使我們分配的總的大小,到這里那么第二個(gè)成員也分析完畢。
3、后面這幾個(gè)成員變量,之前就已經(jīng)分析過(guò)了。mem1base,mem2base,//內存池mem1mapbase,mem2mapbase,//內存管理狀態(tài)表0,0, 這里就不詳述了。這個(gè)數據結果分析至此,那么接下來(lái)看我們分配內存的過(guò)程究竟如何實(shí)現?
三、分配內存
首先看一個(gè)核心代碼如下
評論