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

        共 6960字,需瀏覽 14分鐘

         ·

        2022-07-17 15:12

            關(guān)注、星標(biāo)公眾號(hào),直達(dá)精彩內(nèi)容

        來(lái)源:技術(shù)讓夢(mèng)想更偉大

        作者:李肖遙


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

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

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

        一些基本定義

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

        __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)存總大小

        一個(gè)結(jié)構(gòu)體來(lái)定義內(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)存管理未就緒
        };

        重寫(xiě)函數(shù)

        需要復(fù)制的內(nèi)存長(zhǎng)度(字節(jié)為單位),復(fù)制內(nèi)存,重寫(xiě)一個(gè)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)存,重寫(xiě)一個(gè)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--)//搜索整個(gè)內(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個(gè)空內(nèi)存塊
          {
                    for(i=0;i<nmemb;i++)       //標(biāo)注內(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)存塊號(hào)碼  
                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ū)了.  
        }  

        當(dāng)然也可以把上面的函數(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)聲明:本文來(lái)源網(wǎng)絡(luò),免費(fèi)傳達(dá)知識(shí),版權(quán)歸原作者所有。如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系我進(jìn)行刪除。

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

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


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

        瀏覽 28
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 日本最新偷拍视频 | 欧美一级婬片AAAAAAA牛牛 | 久久久久无码精品国产H动漫猫咪 | 青娱乐精品视频在线观看 | 国产精品一二三在线观看 |