新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于stm32f103zet6的內(nèi)存管理的學(xué)習(xí)

基于stm32f103zet6的內(nèi)存管理的學(xué)習(xí)

作者: 時(shí)間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
主要是依照原子哥哥的代碼來初步了解或者說學(xué)習(xí)一下內(nèi)存管理,特別對(duì)于我們這個(gè)想往嵌入式方向發(fā)展的人來說,內(nèi)存管理應(yīng)該是一種藝術(shù)的。

今天在對(duì)原子的代碼稍作修改是可以進(jìn)行內(nèi)存分配和回收的,所以開始深入分析一下這個(gè)代碼的實(shí)現(xiàn)過程。一、所謂的內(nèi)存管理內(nèi)存管理,是指軟件運(yùn)行時(shí)對(duì)計(jì)算機(jī)內(nèi)存資源的分配和使用的技術(shù)。其最主要的目的是如何高效,快速的分配,并且在適當(dāng)?shù)臅r(shí)候釋放和回收內(nèi)存資源。

本文引用地址:http://m.butianyuan.cn/article/201612/324495.htm

二、代碼分析

1、首先了解一下一個(gè)數(shù)據(jù)結(jié)構(gòu),這是一個(gè)聲明

/*************************** 內(nèi)存管理控制 **********************************************/ typedef struct {void (*init)(u8);//初始化u8 (*perused)(u8); //內(nèi)存使用率u8 *membase[2];//內(nèi)存池 管理2個(gè)區(qū)域的內(nèi)存u16 *memmap[2]; //內(nèi)存管理狀態(tài)表u8 memrdy[2]; //內(nèi)存管理是否就緒}_m_mallco_dev;

成員包括兩個(gè)函數(shù)指針(該指針指向函數(shù)),兩個(gè)指針數(shù)組和一個(gè)u8類型的數(shù)組,具體分析下這幾個(gè)成員的含義,那么首先要找到這個(gè)

_m_mallco_dev mallco_dev={mem_init,//內(nèi)存初始化mem_perused,//內(nèi)存使用率mem1base,mem2base,//內(nèi)存池 mem1mapbase,mem2mapbase,//內(nèi)存管理狀態(tài)表0,0, //內(nèi)存管理未就緒};這才是真正定義的地方,現(xiàn)在就可以了解這個(gè)幾個(gè)成員的具體功能了。

a、初始化中 mem_init,mem_perused,這是兩個(gè)函數(shù),為什么可以這樣用呢(直接用函數(shù)名)?

可以這樣理解么,函數(shù)名就像數(shù)組名一樣,只不過函數(shù)名是代碼段的指針,而數(shù)組名是數(shù)據(jù)段的指針 ,所以這里函數(shù)名就是給函數(shù)指針賦值了。當(dāng)然函數(shù)指針并不能說是等于指針的,就像數(shù)組一樣,數(shù)組名不等于指針的。總書記和主席還是不一樣的。所以暫時(shí)可以這樣理解,函數(shù)名雖然代表了一個(gè)地址,但是這個(gè)值是確定了的,但是指針是可以指向別的地址的。就這樣!這樣寫只不過是為了方便我們?cè)L問罷了??梢园醋约旱男枰薷模?/div>
那么這兩個(gè)函數(shù)的作用?這才是我們最關(guān)心的,看這個(gè)
void mem_init(u8 memx) { mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//內(nèi)存狀態(tài)表數(shù)據(jù)清零 mymemset(mallco_dev.membase[memx], 0,memsize[memx]);//內(nèi)存池所有數(shù)據(jù)清零 mallco_dev.memrdy[memx]=1;//內(nèi)存管理初始化OK } b、注釋很明確,那么接下來就是分析這個(gè)三句話的作用,沒辦法,我無法做到,一眼能看出究竟。
mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);等價(jià)于mymemset(mem1base, 0,0x500*2)
它里面的內(nèi)容很簡(jiǎn)單就是
void mymemset(void *s,u8 c,u32 count) { u8 *xs = s; while(count--)*xs++=c; }以mem1base為首地址的大小為0xa00的內(nèi)容清0,那么mem1base又是什么呢?接下來看看
__align(4) u8 mem1base[MEM1_MAX_SIZE];這明顯是4字節(jié)對(duì)齊的內(nèi)部SRAM的地址,也就是我們的flash里面的地址。所以這就實(shí)現(xiàn)了對(duì)我們內(nèi)部flash0xa00的內(nèi)容清零,好的繼續(xù)看下面的
c、 mymemset(mallco_dev.membase[memx], 0,memsize[memx]);//內(nèi)存池所有數(shù)據(jù)清零
自然地這個(gè)也是一個(gè)意思,清零,唯一不同的就是代表的意思不一樣,到底是內(nèi)存池?cái)?shù)據(jù)清零,還是狀態(tài)表的清零,我們看不出來,那么只有繼續(xù)分析了。清零完成就給相應(yīng)的數(shù)組元素填充1表示完成標(biāo)志。至此我們第一個(gè)初始化成員就分析完畢??!
2、下面開始分析第二個(gè)成員perused函數(shù)
先看函數(shù)如何定義的/***************************************************************************************
名 稱: mem_perused
* 功 能: 獲取內(nèi)存使用率
* 參 數(shù): *memx:所屬內(nèi)存塊
* 返 回 值: 使用率(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]);
} 這里可以看到出現(xiàn)一個(gè)這樣的表達(dá)式,需要仔細(xì)分析!mallco_dev.memmap[memx][i]
分解一下,還是一樣,這個(gè)是指針數(shù)組,也就是數(shù)組里面存放的是指針,那么這里給它賦值為一個(gè)數(shù)組名mem1mapbase,但是訪問的時(shí)候還是可以用下表來訪問的。那么可以替換為:if(mem1mapbase[i]) used++;看到?jīng)],這還是我們之前訪問過了的那個(gè)數(shù)組,只不過這里是當(dāng)非零的時(shí)候執(zhí)行used++,也就是我們占用了才會(huì)進(jìn)行++。那么作用就是:used表示的是占用了的大小。(used*100)/(memtblsize[memx])表示的就是占用值,memtblsize[memx]使我們分配的總的大小,到這里那么第二個(gè)成員也分析完畢。
3、后面這幾個(gè)成員變量,之前就已經(jīng)分析過了。mem1base,mem2base,//內(nèi)存池mem1mapbase,mem2mapbase,//內(nèi)存管理狀態(tài)表0,0, 這里就不詳述了。這個(gè)數(shù)據(jù)結(jié)果分析至此,那么接下來看我們分配內(nèi)存的過程究竟如何實(shí)現(xiàn)?
三、分配內(nèi)存
首先看一個(gè)核心代碼如下


上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: stm32f103zet6內(nèi)存管

評(píng)論


技術(shù)專區(qū)

關(guān)閉