目錄:
1.記憶體管理的原理
2.解析程式
3.程式(在stm32系列微控制器開發中都可以使用)
內容:
一:記憶體管理的原理
記憶體管理,是指軟體執行時對計算機記憶體資源的分配和使用。
記憶體管理的實現方法有很多種,他們其實最終都是要實現 2 個函式:malloc 函式(用於記憶體申請),free函式( 用於記憶體釋放)
本程式實現的是分塊式記憶體管理。原理如下:
分塊式記憶體管理由記憶體池和記憶體管理錶兩部分組成。記憶體池被等分為 n塊,對應的記憶體管理表,大小也為 n,記憶體管理表的每乙個項對應記憶體池的一塊記憶體。
記憶體管理表的項值代表的意義為:當該項值為 0 的時候,代表對應的記憶體塊未被占用,當該項值非零的時候,代表該項對應的記憶體塊已經被占用,其數值則代表被連續占用的記憶體塊數。比如某項值為 10,那麼說明包括本項對應的記憶體塊在內,總共分配了 10 個記憶體塊給外部的某個指標。
內寸分配方向如圖所示,是從頂底的分配方向。即首先從最末端開始找空記憶體。當記憶體管理剛初始化的時候,記憶體表全部清零,表示沒有任何記憶體塊被占用。
分配原理
當指標 p 呼叫 malloc 申請記憶體的時候,先判斷 p 要分配的記憶體塊數(m),然後從第 n 項開始,向下查詢,直到找到 m 塊連續的空記憶體塊(即對應記憶體管理表項為 0),然後將這 m 個記憶體管理表項的值都設定為 m(標記被占用),最後,把最後的這個空記憶體塊的位址返回指標 p,完成一次分配。注意,如果當記憶體不夠的時候(找到最後也沒找到連續的 m 塊空閒記憶體),則返回 null 給 p,表示分配失敗。
釋放原理
當 p 申請的記憶體用完,需要釋放的時候,呼叫 free 函式實現。free 函式先判斷 p 指向的記憶體位址所對應的記憶體塊,然後找到對應的記憶體管理表專案,得到 p 所占用的記憶體塊數目 m(記憶體管理表專案的值就是所分配記憶體塊的數目),將這 m 個記憶體管理表專案的值都清零,標記釋放,完成一次記憶體釋放。
二、解析程式
1.記憶體管理控制器
struct _m_mallco_dev mallco_dev=
;2.記憶體管理初始化
memx:所屬記憶體塊
void my_mem_init(u8 memx)
3.記憶體分配(內部呼叫)
memx:所屬記憶體塊,size:要分配的記憶體大小(位元組),返值:0xffffffff,代表錯誤;其他,記憶體偏移位址。
u32 my_mem_malloc(u8 memx,u32 size)
return (offset*memblksize[memx]);//返回偏移位址 }}
return 0xffffffff;//未找到符合分配條件的記憶體塊
}4.分配記憶體(外部呼叫)
memx:所屬記憶體塊,size:記憶體大小(位元組)。
void *mymalloc(u8 memx,u32 size)
5.釋放記憶體(內部呼叫)
memx:所屬記憶體塊,offset:記憶體位址偏移,返回值:0,釋放成功;1,釋放失敗;
u8 my_mem_free(u8 memx,u32 offset)
if(offset
return 0;
}else return 2;//偏移超區了.
}6.釋放記憶體(外部呼叫)
memx:所屬記憶體塊,ptr:記憶體首位址 。
void myfree(u8 memx,void *ptr)
三、程式
/*malloc.c*/
#include "malloc.h"
//記憶體池(32位元組對齊)
__align(32) u8 mem1base[mem1_max_size]; //內部sram記憶體池
__align(32) u8 mem2base[mem2_max_size] __attribute__((at(0x68000000))); //外部sram記憶體池
//記憶體管理表
u16 mem1mapbase[mem1_alloc_table_size]; //內部sram記憶體池map
u16 mem2mapbase[mem2_alloc_table_size] __attribute__((at(0x68000000+mem2_max_size))); //外部sram記憶體池map
//記憶體管理引數
const u32 memtblsize[srambank]=; //記憶體表大小
const u32 memblksize[srambank]=; //記憶體分塊大小
const u32 memsize[srambank]=; //記憶體總大小
//記憶體管理控制器
struct _m_mallco_dev mallco_dev=
;void mymemcpy(void *des,void *src,u32 n)
void mymemset(void *s,u8 c,u32 count)
void my_mem_init(u8 memx)
u8 my_mem_perused(u8 memx)
return (used*100)/(memtblsize[memx]);
}u32 my_mem_malloc(u8 memx,u32 size)
return (offset*memblksize[memx]);//返回偏移位址 }}
return 0xffffffff;//未找到符合分配條件的記憶體塊
} u8 my_mem_free(u8 memx,u32 offset)
if(offset
return 0;
}else return 2;//偏移超區了.
} void myfree(u8 memx,void *ptr)
void *mymalloc(u8 memx,u32 size)
void *myrealloc(u8 memx,void *ptr,u32 size) }
/*malloc.h*/
#ifndef __malloc_h
#define __malloc_h
#ifndef null
#define null 0
#endif
//定義兩個記憶體池
#define sramin 0 //內部記憶體池
#define sramex 1 //外部記憶體池
#define srambank 2 //定義支援的sram塊數.
//mem1記憶體引數設定.mem1完全處於內部sram裡面.
#define mem1_block_size 32 //記憶體塊大小為32位元組
#define mem1_max_size 10*1024 //最大管理記憶體 4k
#define mem1_alloc_table_size mem1_max_size/mem1_block_size //記憶體表大小
//mem2記憶體引數設定.mem2的記憶體池處於外部sram裡面
#define mem2_block_size 32 //記憶體塊大小為32位元組
#define mem2_max_size 800 *1024 //最大管理記憶體960k
#define mem2_alloc_table_size mem2_max_size/mem2_block_size //記憶體表大小
//記憶體管理控制器
struct _m_mallco_dev
;extern struct _m_mallco_dev mallco_dev; //在mallco.c裡面定義
void mymemset(void *s,u8 c,u32 count); //設定記憶體
void mymemcpy(void *des,void *src,u32 n);//複製記憶體
void my_mem_init(u8 memx); //記憶體管理初始化函式(外/內部呼叫)
u32 my_mem_malloc(u8 memx,u32 size); //記憶體分配(內部呼叫)
u8 my_mem_free(u8 memx,u32 offset); //記憶體釋放(內部呼叫)
u8 my_mem_perused(u8 memx); //獲得記憶體使用率(外/內部呼叫)
//外部呼叫函式
void myfree(u8 memx,void *ptr); //記憶體釋放(外部呼叫)
void *mymalloc(u8 memx,u32 size); //記憶體分配(外部呼叫)
void *myrealloc(u8 memx,void *ptr,u32 size);//重新分配記憶體(外部呼叫)
#endif
STM32記憶體管理
這是我的第一篇文章,寫的不好請多多見諒 針對stm32f429來進行講解,其他型號的也可以參照學習 相信很多新手在記憶體管理這個程式中比較疑惑,為什麼分配那麼大,可不可以更改大小?但是改大了編譯會錯誤又是為什麼?這裡將對大家心中的疑惑進行講解,並且教大家進行計算。當該項值為 0 的時候,代表對應的記...
STM32CubeMX系列 記憶體管理
1.記憶體管理簡介 stm32f103zet6內部有64kb的sram記憶體,加上外擴的128kb容量的sram後,可使用的記憶體還是比較多的。本例程將介紹一種簡單的記憶體管理方式 即分塊記憶體管理 來有效管理這些記憶體,類似於c語言中通過malloc函式和free函式來申請和釋放記憶體 記憶體管理...
stm32記憶體分配
原文 1 棧區 stack 由編譯器自動分配和釋放,存放函式的引數值 區域性變數的值等,其操作方式類似 於資料結構中的棧。2 堆區 heap 一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時可能由作業系統 分配 方式類似於資料結構中的鍊錶。3 全域性區 靜態區 static 全域性變數和靜...