<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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

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

          本文引用地址:http://www.ex-cimer.com/article/201612/324495.htm

          二、代碼分析

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

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

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

          _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)在就可以了解這個幾個成員的具體功能了。

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

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


          上一頁 1 2 下一頁

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

          評論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();