<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          整理了一份通用的內(nèi)存管理驅(qū)動代碼

          共 6960字,需瀏覽 14分鐘

           ·

          2022-07-17 15:12

              關(guān)注、星標公眾號,直達精彩內(nèi)容

          來源:技術(shù)讓夢想更偉大

          作者:李肖遙


          malloc的全稱是memory allocation,即動態(tài)內(nèi)存分配,當無法知道內(nèi)存具體位置的時候,想要綁定真正的內(nèi)存空間的時候,就需要用到動態(tài)的分配內(nèi)存。

          可以說動態(tài)內(nèi)存分配在嵌入式開發(fā)中是經(jīng)常用到的,也是比較容易出錯和被忽略的,經(jīng)常忘了free,導(dǎo)致分配失敗程序死機等等。

          這里在工作的時候整理了一份通用的內(nèi)存管理驅(qū)動代碼。

          一些基本定義

          定義內(nèi)存池(32字節(jié)對齊)

          __align(32) u8 mem1base[MEM1_MAX_SIZE];             //內(nèi)部SRAM內(nèi)存池
          __align(32) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0XC01F4000)));     //外部SDRAM內(nèi)存池,前面2M給LTDC用了(1280*800*2)
          __align(32) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0X10000000)));     //內(nèi)部CCM內(nèi)存池

          定義內(nèi)存管理表

          u32 mem1mapbase[MEM1_ALLOC_TABLE_SIZE];             //內(nèi)部SRAM內(nèi)存池MAP
          u32 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0XC01F4000+MEM2_MAX_SIZE))); //外部SRAM內(nèi)存池MAP
          u32 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X10000000+MEM3_MAX_SIZE))); //內(nèi)部CCM內(nèi)存池MAP

          定義內(nèi)存管理參數(shù)

          const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE}; //內(nèi)存表大小
          const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE};     //內(nèi)存分塊大小
          const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE};       //內(nèi)存總大小

          一個結(jié)構(gòu)體來定義內(nèi)存管理控制器

          struct _m_mallco_dev mallco_dev=
          {
           my_mem_init,      //內(nèi)存初始化
           my_mem_perused,      //內(nèi)存使用率
           mem1base,mem2base,mem3base,   //內(nèi)存池
           mem1mapbase,mem2mapbase,mem3mapbase,//內(nèi)存管理狀態(tài)表
           0,0,0,          //內(nèi)存管理未就緒
          };

          重寫函數(shù)

          需要復(fù)制的內(nèi)存長度(字節(jié)為單位),復(fù)制內(nèi)存,重寫一個memcpy

          void mymemcpy(void *des,void *src,u32 n)  
          {  
              u8 *xdes=des;
           u8 *xsrc=src; 
              while(n--)*xdes++=*xsrc++;  
          }  

          需要設(shè)置的內(nèi)存大小(字節(jié)為單位),設(shè)置內(nèi)存,重寫一個memset

          void mymemset(void *s,u8 c,u32 count)  
          {  
              u8 *xs = s;  
              while(count--)*xs++=c;  

          常用模塊函數(shù)

          獲取內(nèi)存使用率

          u16 my_mem_perused(u8 memx)  
          {  
              u32 used=0;  
              u32 i;  
              for(i=0;i<memtblsize[memx];i++)  
              {  
                  if(mallco_dev.memmap[memx][i])used++; 
              } 
              return (used*1000)/(memtblsize[memx]);  

          內(nèi)存分配(內(nèi)部調(diào)用)

          u32 my_mem_malloc(u8 memx,u32 size)  
          {  
              signed long offset=0;  
              u32 nmemb; //需要的內(nèi)存塊數(shù)  
           u32 cmemb=0;//連續(xù)空內(nèi)存塊數(shù)
              u32 i;  
              if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先執(zhí)行初始化 
              if(size==0)return 0XFFFFFFFF;//不需要分配
              nmemb=size/memblksize[memx];   //獲取需要分配的連續(xù)內(nèi)存塊數(shù)
              if(size%memblksize[memx])nmemb++;  
              for(offset=memtblsize[memx]-1;offset>=0;offset--)//搜索整個內(nèi)存控制區(qū)  
              {     
            if(!mallco_dev.memmap[memx][offset])cmemb++;//連續(xù)空內(nèi)存塊數(shù)增加
            else cmemb=0;        //連續(xù)內(nèi)存塊清零
            if(cmemb==nmemb)       //找到了連續(xù)nmemb個空內(nèi)存塊
            {
                      for(i=0;i<nmemb;i++)       //標注內(nèi)存塊非空 
                      {  
                          mallco_dev.memmap[memx][offset+i]=nmemb;  
                      }  
                      return (offset*memblksize[memx]);//返回偏移地址  
            }
              }  
              return 0XFFFFFFFF;//未找到符合分配條件的內(nèi)存塊  
          }  

          釋放內(nèi)存

          u8 my_mem_free(u8 memx,u32 offset)  
          {  
              int i;  
              if(!mallco_dev.memrdy[memx])//未初始化,先執(zhí)行初始化
           {
            mallco_dev.init(memx);    
                  return 1;//未初始化  
              }  
              if(offset<memsize[memx])//偏移在內(nèi)存池內(nèi). 
              {  
                  int index=offset/memblksize[memx];   //偏移所在內(nèi)存塊號碼  
                  int nmemb=mallco_dev.memmap[memx][index]; //內(nèi)存塊數(shù)量
                  for(i=0;i<nmemb;i++)        //內(nèi)存塊清零
                  {  
                      mallco_dev.memmap[memx][index+i]=0;  
                  }  
                  return 0;  
              }else return 2;//偏移超區(qū)了.  
          }  

          當然也可以把上面的函數(shù)封裝為外部調(diào)用的,方便使用,比如重新分配內(nèi)存(外部調(diào)用)

          void *myrealloc(u8 memx,void *ptr,u32 size)  
          {  
              u32 offset;    
              offset=my_mem_malloc(memx,size);    
              if(offset==0XFFFFFFFF)return NULL;     
              else  
              {              
               mymemcpy((void*)((u32)mallco_dev.membase[memx]+offset),ptr,size); //拷貝舊內(nèi)存內(nèi)容到新內(nèi)存   
                  myfree(memx,ptr);                 //釋放舊內(nèi)存
                  return (void*)((u32)mallco_dev.membase[memx]+offset);      //返回新內(nèi)存首地址
              }  
          }


          版權(quán)聲明:本文來源網(wǎng)絡(luò),免費傳達知識,版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請聯(lián)系我進行刪除。

          ????????????????  END  ???????????????

          關(guān)注我的微信公眾號,回復(fù)“加群”按規(guī)則加入技術(shù)交流群。


          點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。

          瀏覽 28
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产ss视频在线观看 | 苍进空一区二区三区 | 极品人妻超碰在线 | 免费区欧美一级毛片99宜春院 | 日韩人妻精品视频一区 |