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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32 內(nèi)存管理 實(shí)現(xiàn)了malloc,free,remalloc等函數(shù)

          STM32 內(nèi)存管理 實(shí)現(xiàn)了malloc,free,remalloc等函數(shù)

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

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

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

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

          代碼如下:
          malloc.h頭文件:
          #ifndef __MALLOC_H
          #define __MALLOC_H
          //////////////////////////////////////////////////////////////////////////////////
          //本程序只供學(xué)習(xí)使用,未經(jīng)作者許可,不得用于其它任何用途
          //ALIENTEK 開(kāi)發(fā)板
          //內(nèi)存管理 代碼
          //正點(diǎn)原子@ALIENTEK
          //技術(shù)論壇:www.openedv.com
          //創(chuàng)建日期:2011/7/5
          //版本:V1.0
          //版權(quán)所有,盜版必究。
          //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 //內(nèi)存塊大小為32字節(jié)
          #define MAX_MEM_SIZE 10*1024 //最大管理內(nèi)存 10K
          #define MEM_ALLOC_TABLE_SIZE MAX_MEM_SIZE/MEM_BLOCK_SIZE //內(nèi)存表大小
          //內(nèi)存管理控制器
          struct _m_mallco_dev
          {
          void (*init)(void); //初始化
          u8 (*perused)(void); //內(nèi)存使用率
          u8membase[MAX_MEM_SIZE]; //內(nèi)存池
          u16 memmap[MEM_ALLOC_TABLE_SIZE];//內(nèi)存管理狀態(tài)表
          u8memrdy; //內(nèi)存管理是否就緒
          };
          extern struct _m_mallco_dev mallco_dev;//在mallco.c里面定義
          void mymemset(void *s,u8 c,u32 count);//設(shè)置內(nèi)存
          void mymemcpy(void *des,void *src,u32 n);//復(fù)制內(nèi)存
          void mem_init(void); //內(nèi)存管理初始化函數(shù)(外/內(nèi)部調(diào)用)
          u32 mem_malloc(u32 size); //內(nèi)存分配(內(nèi)部調(diào)用)
          u8 mem_free(u32 offset); //內(nèi)存釋放(內(nèi)部調(diào)用)
          u8 mem_perused(void); //獲得內(nèi)存使用率(外/內(nèi)部調(diào)用)
          ////////////////////////////////////////////////////////////////////////////////
          //用戶調(diào)用函數(shù)
          void myfree(void *ptr); //內(nèi)存釋放(外部調(diào)用)
          void *mymalloc(u32 size); //內(nèi)存分配(外部調(diào)用)
          void *myrealloc(void *ptr,u32 size);//重新分配內(nèi)存(外部調(diào)用)

          #endif


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

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

          u8 i;
          Stm32_Clock_Init(9);//系統(tǒng)時(shí)鐘設(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內(nèi)存管理函

          評(píng)論


          技術(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); })();