<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > STM32 內存管理 實(shí)現了malloc,free,remalloc等函數

STM32 內存管理 實(shí)現了malloc,free,remalloc等函數

作者: 時(shí)間:2016-11-23 來(lái)源:網(wǎng)絡(luò ) 收藏
這兩天寫(xiě)的一個(gè)STM32上的內存管理函數,實(shí)現了malloc和free以及remalloc幾個(gè)函數.還實(shí)現了一個(gè)內存使用率查詢(xún)的函數.

實(shí)驗環(huán)境:ALIENTEK STM32 Mini 開(kāi)發(fā)板
思路如下:
將內存分塊管理.
內存池等分為固定大小的內存塊.
建立一個(gè)內存狀態(tài)表,對應每個(gè)塊,有多少個(gè)塊,狀態(tài)表就有多少個(gè)元素,一一對應.
通過(guò)狀態(tài)表的值判斷該塊內存是否可用(為0則表示可用,為其他值則表示被占用了,而且占用的內存塊數量,就是該值的數字)

初始化的時(shí)候,狀態(tài)表的值全0,代表所有的內存塊都未被占用.當需要分配的時(shí)候,malloc從內存塊的最高地址往下查找,查找到連續的空內存大于等于要分配的內存的時(shí)候,結束此次分配,返回地址給要分配的指針,完成一次malloc. free的時(shí)候,就比較簡(jiǎn)單了,只要找到所分配的內存對應在狀態(tài)表的位置,然后把狀態(tài)表的值清0,及實(shí)現free.

內存使用率則通過(guò)查詢(xún)狀態(tài)表有多少個(gè)非0值,來(lái)計算占用率.

代碼如下:
malloc.h頭文件:
#ifndef __MALLOC_H
#define __MALLOC_H
//////////////////////////////////////////////////////////////////////////////////
//本程序只供學(xué)習使用,未經(jīng)作者許可,不得用于其它任何用途
//ALIENTEK 開(kāi)發(fā)板
//內存管理 代碼
//正點(diǎn)原子@ALIENTEK
//技術(shù)論壇:www.openedv.com
//創(chuàng )建日期:2011/7/5
//版本:V1.0
//版權所有,盜版必究。
//Copyright(C) 正點(diǎn)原子 2009-2019
//All rights reserved
//********************************************************************************
//沒(méi)有更新信息
//////////////////////////////////////////////////////////////////////////////////
typedef unsigned longu32;
typedef unsigned short u16;
typedef unsigned charu8;
#ifndef NULL
#define NULL 0
#endif
#define MEM_BLOCK_SIZE 32 //內存塊大小為32字節
#define MAX_MEM_SIZE 10*1024 //最大管理內存 10K
#define MEM_ALLOC_TABLE_SIZE MAX_MEM_SIZE/MEM_BLOCK_SIZE //內存表大小
//內存管理控制器
struct _m_mallco_dev
{
void (*init)(void); //初始化
u8 (*perused)(void); //內存使用率
u8membase[MAX_MEM_SIZE]; //內存池
u16 memmap[MEM_ALLOC_TABLE_SIZE];//內存管理狀態(tài)表
u8memrdy; //內存管理是否就緒
};
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 mem_init(void); //內存管理初始化函數(外/內部調用)
u32 mem_malloc(u32 size); //內存分配(內部調用)
u8 mem_free(u32 offset); //內存釋放(內部調用)
u8 mem_perused(void); //獲得內存使用率(外/內部調用)
////////////////////////////////////////////////////////////////////////////////
//用戶(hù)調用函數
void myfree(void *ptr); //內存釋放(外部調用)
void *mymalloc(u32 size); //內存分配(外部調用)
void *myrealloc(void *ptr,u32 size);//重新分配內存(外部調用)

#endif


malloc.c文件:
#include "malloc.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供學(xué)習使用,未經(jīng)作者許可,不得用于其它任何用途
//ALIENTEK 開(kāi)發(fā)板
//內存管理 代碼
//正點(diǎn)原子@ALIENTEK
//技術(shù)論壇:www.openedv.com
//創(chuàng )建日期:2011/7/5
//版本:V1.0
//版權所有,盜版必究。
//Copyright(C) 正點(diǎn)原子 2009-2019
//All rights reserved
//********************************************************************************
//沒(méi)有更新信息
//////////////////////////////////////////////////////////////////////////////////
//內存管理控制器
struct _m_mallco_dev mallco_dev=
{
mem_init, //內存初始化
mem_perused,//內存使用率
0, //內存池
0, //內存管理狀態(tài)表
0, //內存管理未就緒
};
//復制內存
//*des:目的地址
//*src:源地址
//n:需要復制的內存長(cháng)度(字節為單位)
void memcpy(void *des,void *src,u32 n)
{
u8 *xdes=des;
u8 *xsrc=src;
while(n--)*xdes++=*xsrc++;
}
//設置內存
//*s:內存首地址
//c :要設置的值
//count:需要設置的內存大小(字節為單位)
void memset(void *s,u8 c,u32 count)
{
u8 *xs = s;
while(count--)*xs++=c;
}
//內存管理初始化
void mem_init(void)
{
memset(mallco_dev.membase, 0, sizeof(mallco_dev.membase));//內存池素有數據清零
mallco_dev.memrdy=1;//內存管理初始化OK
}
//獲取內存使用率
//返回值:使用率(0~100)
u8 mem_perused(void)
{
u16 used=0;
u32 i;
for(i=0;i {
if(mallco_dev.memmap)used++;
}
return used*100/MEM_ALLOC_TABLE_SIZE;
}
//內存分配(內部調用)
//size:要分配的內存大小(字節)
//返回值:0XFFFFFFFF,代表錯誤;其他,內存偏移地址
u32 mem_malloc(u32 size)
{
signed long offset=0;
u16 nmemb; //需要的內存塊數
u16 cmemb=0;//連續空內存塊數
u32 i;
if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先執行初始化
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/MEM_BLOCK_SIZE; //獲取需要分配的連續內存塊數
if(size%MEM_BLOCK_SIZE)nmemb++;
for(offset=MEM_ALLOC_TABLE_SIZE-1;offset>=0;offset--)//搜索整個(gè)內存控制區
{
if(!mallco_dev.memmap[offset])cmemb++; //連續空內存塊數增加
else cmemb=0; //連續內存塊清零
if(cmemb==nmemb) //找到了連續nmemb個(gè)空內存塊
{
for(i=0;i {
mallco_dev.memmap[offset+i]=nmemb;
}
return (offset*MEM_BLOCK_SIZE);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配條件的內存塊
}
//釋放內存(內部調用)
//offset:內存地址偏移
//返回值:0,釋放成功;1,釋放失敗;
u8 mem_free(u32 offset)
{
int i;
if(!mallco_dev.memrdy)//未初始化,先執行初始化
{
mallco_dev.init();
return 1;//未初始化
}
if(offset {
int index=offset/MEM_BLOCK_SIZE;//偏移所在內存塊號碼
int nmemb=mallco_dev.memmap[index]; //內存塊數量
for(i=0;i {
mallco_dev.memmap[index+i]=0;
}
return 0;
}else return 2;//偏移超區了.
}
//釋放內存(外部調用)
//ptr:內存首地址
void myfree(void *ptr)
{
u32 offset;
if(ptr==NULL)return;//地址為0.
offset=(u32)ptr-(u32)&mallco_dev.membase;
mem_free(offset);//釋放內存
}
//分配內存(外部調用)
//size:內存大小(字節)
//返回值:分配到的內存首地址.
void *mymalloc(u32 size)
{
u32 offset;
offset=mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)&mallco_dev.membase+offset);
}
//重新分配內存(外部調用)
//*ptr:舊內存首地址
//size:要分配的內存大小(字節)
//返回值:新分配到的內存首地址.
void *myrealloc(void *ptr,u32 size)
{
u32 offset;
offset=mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else
{
memcpy((void*)((u32)&mallco_dev.membase+offset),ptr,size);//拷貝舊內存內容到新內存
myfree(ptr); //釋放舊內存
return (void*)((u32)&mallco_dev.membase+offset); //返回新內存首地址
}
}

最后測試代碼如下:
int main(void)
{
u8 *ptr;
u16 *ptr1;
u32 *ptr2;
u32 *ptr3;

u8 i;
Stm32_Clock_Init(9);//系統時(shí)鐘設置
delay_init(72);//延時(shí)初始化
uart_init(72,9600); //串口1初始化
LED_Init();
//LCD_Init();
ptr=(u8*)mymalloc(100);
if(*ptr)i=0;
i=mallco_dev.perused();//查看使用率
ptr1=(u16*)mymalloc(2*100);
i=mallco_dev.perused();//查看使用率
ptr2=(u32*)mymalloc(4*100);
i=mallco_dev.perused();//查看使用率
myfree(ptr);
i=mallco_dev.perused();//查看使用率
ptr3=(u32*)mymalloc(4*20);
i=mallco_dev.perused();//查看使用率
myfree(ptr1);
i=mallco_dev.perused();//查看使用率
ptr=(u8*)mymalloc(8*32);

myfree(ptr2);
i=mallco_dev.perused();//查看使用率
myfree(ptr3);
i=mallco_dev.perused();//查看使用率
if(i)i=0;
usmart_dev.init();
POINT_COLOR=RED;
while(1)
{
LED0=!LED0;
delay_ms(500);
}
}


關(guān)鍵詞: STM32內存管理函

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>