新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于stm32f103zet6的內存管理的學習

        基于stm32f103zet6的內存管理的學習

        作者: 時間:2016-12-01 來源:網絡 收藏
        主要是依照原子哥哥的代碼來初步了解或者說學習一下內存管理,特別對于我們這個想往嵌入式方向發展的人來說,內存管理應該是一種藝術的。

        今天在對原子的代碼稍作修改是可以進行內存分配和回收的,所以開始深入分析一下這個代碼的實現過程。一、所謂的內存管理內存管理,是指軟件運行時對計算機內存資源的分配和使用的技術。其最主要的目的是如何高效,快速的分配,并且在適當的時候釋放和回收內存資源。

        本文引用地址:http://www.104case.com/article/201612/324495.htm

        二、代碼分析

        1、首先了解一下一個數據結構,這是一個聲明

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

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

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

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

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


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 广丰县| 蚌埠市| 白银市| 苗栗县| 克拉玛依市| 漠河县| 东兴市| 磐石市| 阳朔县| 乌兰县| 呼和浩特市| 行唐县| 石城县| 嵊泗县| 华安县| 铅山县| 九江市| 延吉市| 临海市| 大同县| 庆安县| 广宗县| 清水县| 阳信县| 灌云县| 板桥市| 盐边县| 密山市| 岫岩| 安丘市| 巍山| 崇仁县| 盈江县| 普兰店市| 雅安市| 黑山县| 赣榆县| 襄城县| 盐亭县| 仁布县| 金昌市|