在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 基于STM32原子戰(zhàn)艦板內(nèi)存管理源碼

            基于STM32原子戰(zhàn)艦板內(nèi)存管理源碼

            作者: 時間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
            */
            //復(fù)制內(nèi)存,作用是將源地址的內(nèi)容復(fù)制到目標(biāo)地址
            //*des:目的地址
            //*src:源地址
            //n:需要復(fù)制的內(nèi)存長度(字節(jié)為單位)
            void mymemcpy(void *des,void *src,u32 n)
            { //“void *des”無類型指針,不能指向具體的數(shù)據(jù),“void *des”無類型指針指向內(nèi)存中的數(shù)據(jù)類型由用戶自己確定
            u8 *xdes=des;//目標(biāo)地址,“*xdes”轉(zhuǎn)換成u8類型,也可以理解為把目的地地址des存儲到xdes指針中
            u8 *xsrc=src;
            while(n--)*xdes++=*xsrc++;
            }
            //設(shè)置內(nèi)存
            //*s:內(nèi)存首地址
            //c :要設(shè)置的值
            //count:需要設(shè)置的內(nèi)存大小(字節(jié)為單位)
            void mymemset(void *s,u8 c,u32 count)
            {
            u8 *xs = s;
            while(count--)*xs++=c;
            } //以*s為內(nèi)存首地址的count個字節(jié)中,填充c,即把c寫入到*s為首地址的內(nèi)存中,個數(shù)多少由count值決定
            //內(nèi)存管理初始化
            //memx:所屬內(nèi)存塊,要么SRAMEX==1(外部內(nèi)存);要么SRAMIN(內(nèi)部內(nèi)存)==0
            /*
            const u32 memtblsize[2]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE};//內(nèi)存管理表大小
            const u32 memblksize[2]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE}; //內(nèi)存分塊大小
            const u32 memsize[2]={MEM1_MAX_SIZE,MEM2_MAX_SIZE}; //內(nèi)存總大小
            */
            void mem_init(u8 memx) //如“mem_init(SRAMIN);”表示內(nèi)部內(nèi)存塊
            { //memmap,是16位的,mymemset,設(shè)置是針對8位的,那么1個16位的數(shù)據(jù)是不是2個8位組成的???!
            mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//內(nèi)存狀態(tài)表數(shù)據(jù)清零
            //把u8類型的數(shù)據(jù)“0”填充到u16類型指針元素memmap[0]中(根據(jù)結(jié)構(gòu)體定義“u16 *memmap[2]; ”),memmap[0]=mem1mapbase==1250,
            //也就是說“mallco_dev.memmap[memx]”在這里表示1250個內(nèi)部內(nèi)存塊用以存儲u16類型指針,
            //“memtblsize[memx]”是什么呢?memtblsize[memx]即memtblsize[0]==1250個內(nèi)部內(nèi)存管理表,
            //而mallco_dev.memmap[memx]是16位的,為了將其全部清零,所以乘以2.
            mymemset(mallco_dev.membase[memx], 0,memsize[memx]); //內(nèi)存池所有數(shù)據(jù)清零
            //memsize[0]==40K字節(jié)空間, mallco_dev.membase[memx]==40K字節(jié)空間,
            mallco_dev.memrdy[memx]=1; //內(nèi)存管理初始化OK
            }
            /*
            */
            //獲取內(nèi)存使用率
            //memx:所屬內(nèi)存塊,要么SRAMEX==1(外部內(nèi)存);要么SRAMIN(內(nèi)部內(nèi)存)==0
            //返回值:使用率(0~100)
            u8 mem_perused(u8 memx)
            {
            u32 used=0;
            u32 i;
            for(i=0;i {
            if(mallco_dev.memmap[memx][i])used++;
            } //mallco_dev.memmap[memx][i]是二維數(shù)組。當(dāng)內(nèi)存塊初始化后該值為0,
            return (used*100)/(memtblsize[memx]); //used*100,乘以100是將小數(shù)變成整數(shù)
            }
            //內(nèi)存分配(內(nèi)部調(diào)用)
            //memx:所屬內(nèi)存塊
            //size:要分配的內(nèi)存大小(字節(jié)數(shù))
            //返回值:0XFFFFFFFF,代表錯誤;其他,內(nèi)存偏移地址
            //向memx存儲器申請size個字節(jié)的連續(xù)存儲空間,并將size個字節(jié)中首個字節(jié)的地址偏移值標(biāo)注出來,注意是地址偏移值而不是地址。
            u32 mem_malloc(u8 memx,u32 size)
            {
            signed long offset=0;
            u16 nmemb; //需要的內(nèi)存塊數(shù)
            u16 cmemb=0;//連續(xù)空內(nèi)存塊數(shù)
            u32 i;
            if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先執(zhí)行初始化
            /*
            “mallco_dev.init(memx);”是什么意思?mallco_dev.init(memx)是結(jié)構(gòu)體變量mallco_dev的一個成員,本句中就是對結(jié)構(gòu)體成員的引用,即執(zhí)行
            mem_init(u8 memx)函數(shù)的意思;如何引用結(jié)構(gòu)體中指向函數(shù)的指針變量成員?既然是指向函數(shù)的指針變量且有賦值,在引用時按照格式:
            結(jié)構(gòu)體變量名.指向函數(shù)的指針變量名(形參);
            */
            if(size==0)return 0XFFFFFFFF;//不需要分配 memblksize[memx]==32
            nmemb=size/memblksize[memx]; //獲取需要分配的連續(xù)內(nèi)存塊數(shù)
            /*
            c語言規(guī)定:除法的運算結(jié)果與運算對象的數(shù)據(jù)類型有關(guān),兩個數(shù)都是int則商(即結(jié)果)是int,若商(即結(jié)果)有小數(shù)則省略掉小數(shù)點部分。本例中
            size和memblksize[memx]都是int,所以結(jié)果只能是int。假設(shè)size<32,則nmemb==0;
            c語言規(guī)定取余運算的運算對象必須是int。當(dāng)小數(shù)對大數(shù)取余時余(即結(jié)果)是小數(shù)本身;例如,在“if(size%memblksize[memx])nmemb++;”中 ,
            假設(shè)size<32,則size%memblksize[memx]的結(jié)果是size值本身,所以執(zhí)行“nmemb++;”運算,這時運算結(jié)果是nmemb==1;如果size是32的整數(shù)倍則不執(zhí)行
            “nmemb++;”運算;
            memtblsize[0]==1250,memtblsize[1]==6250,
            mallco_dev.memmap[memx][offset]是什么意思?
            */
            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ù)增加,offset從1249->0變化
            /*
            如,{ memmap[0][149],memmap[0][148],...memmap[0][1],memmap[0][0]};實際上可以把“mallco_dev.memmap[memx][offset]”視為具有1250個變量的
            一維數(shù)組,每個元素對應(yīng)的實際意義是對應(yīng)的一個內(nèi)存塊,順序是offset從1249(高)->0(低)變化;如果哪個變量等于0(即空閑)就執(zhí)行
            “cmemb++;”操作,這樣就可以計算出連續(xù)空閑內(nèi)存塊數(shù)cmemb;切記!目的是要獲取連續(xù)的空閑的內(nèi)存塊數(shù)!這樣就必須結(jié)合下一句
            “else cmemb=0;”來分析;如果沒有出現(xiàn)連續(xù)的空閑內(nèi)存塊(即數(shù)組順序相連的變量值沒有出現(xiàn)類似“0,0,0,0,0”這樣的情況),程序會執(zhí)行下一語
            句“else cmemb=0;”即把上面的“cmemb”統(tǒng)計值清零,這樣程序就會在for循環(huán)里面繼續(xù)尋找符合“if(cmemb==nmemb)”條件的狀態(tài)出現(xiàn),
            如果for循環(huán)執(zhí)行完了還沒有出現(xiàn)符合“if(cmemb==nmemb)”條件的狀態(tài),則返回0XFFFFFFFF結(jié)束本函數(shù)表示沒有找到符合條件的內(nèi)存塊。假
            設(shè):size=65,那么nmemb就是3即需要獲取連續(xù)3個內(nèi)存塊來存放65個字節(jié),再假設(shè)數(shù)組順序相連的變量值出現(xiàn)了類似“0,0,0,0,0”這樣的情況(即有
            連續(xù)4個空閑的內(nèi)存塊),這時就出現(xiàn)了符合“if(cmemb==nmemb)”條件的狀態(tài),即當(dāng)cmemb計數(shù)計到3的時候(即出現(xiàn)了連續(xù)相連的3個內(nèi)存塊)就
            符合“cmemb==nmemb”了,程序就自然進入“if(cmemb==nmemb)”語句。
            offset*memblksize[memx]代表什么呢?offset的取值范圍是0-1249,memblksize[memx]代表每個內(nèi)存塊的字節(jié)數(shù)即32,offset*memblksize[memx]就
            是返回偏移地址值;也就是把連續(xù)空閑的內(nèi)存塊對應(yīng)的地址的首地址值標(biāo)注出來。
            */
            else cmemb=0; //連續(xù)內(nèi)存塊清零
            if(cmemb==nmemb) //找到了連續(xù)nmemb個空內(nèi)存塊
            {
            for(i=0;i {
            mallco_dev.memmap[memx][offset+i]=nmemb;
            }
            return (offset*memblksize[memx]);//返回偏移地址
            }
            }
            return 0XFFFFFFFF;//未找到符合分配條件的內(nèi)存塊
            }
            //釋放內(nèi)存(內(nèi)部調(diào)用)
            //memx:所屬內(nèi)存塊
            //offset:內(nèi)存地址偏移
            //返回值:0,釋放成功;1,釋放失敗;
            u8 mem_free(u8 memx,u32 offset)
            {
            int i;
            if(!mallco_dev.memrdy[memx])//未初始化,先執(zhí)行初始化
            {
            mallco_dev.init(memx); //本句等價于“mem_init(memx);”
            return 1;//未初始化
            }
            if(offset {
            int index=offset/memblksize[memx]; //偏移所在內(nèi)存塊號碼 memblksize[memx]==32,
            int nmemb=mallco_dev.memmap[memx][index]; //內(nèi)存塊數(shù)量
            for(i=0;i {
            mallco_dev.memmap[memx][index+i]=0;
            }
            return 0;
            }else return 2;//偏移超區(qū)了.
            }
            //釋放內(nèi)存(外部調(diào)用)
            //memx:所屬內(nèi)存塊
            //ptr:內(nèi)存首地址
            void myfree(u8 memx,void *ptr)
            {
            u32 offset;
            if(ptr==NULL)return;//地址為0.
            offset=(u32)ptr-(u32)mallco_dev.membase[memx];
            mem_free(memx,offset);//釋放內(nèi)存
            }
            //分配內(nèi)存(外部調(diào)用)
            //memx:所屬內(nèi)存塊
            //size:內(nèi)存大小(字節(jié))
            //返回值:分配到的內(nèi)存首地址.
            //在memx存儲器中,找出size個字節(jié)的連續(xù)空閑的內(nèi)存空間,并將連續(xù)空閑的內(nèi)存空間指針值標(biāo)注出來;返回值就是這個指針值
            /*
            mallco_dev.membase[memx]即mallco_dev.membase[0]代表MCU內(nèi)部存儲器的40K字節(jié)中的第一個字節(jié)變量的地址,是u8類型指針變量,也就是說一個字節(jié)占用一個地址;換句話說,把內(nèi)部存儲器的40K字節(jié)的地址定義為一個“u8 mem1base[MEM1_MAX_SIZE]”數(shù)組,指針類型數(shù)組“u8 *membase[2];”的賦值是{mem1base,mem2base},而“mem1base,mem2base”分別是內(nèi)部內(nèi)存池和外部內(nèi)存池的數(shù)組名,各自首元素的地址亦是個指針常量;因為事先已經(jīng)定義
            “u8 mem1base[MEM1_MAX_SIZE]”即“u8 mem1base[40K];”。如何理解“(void*)((u32)mallco_dev.membase[memx]+offset); ”呢?
            1),已經(jīng)說過mallco_dev.membase[memx]是首個變量的地址即40k字節(jié)中首個字節(jié)的地址值;
            2),“offset”是:向memx存儲器申請size個字節(jié)的連續(xù)空閑存儲空間,這個找到的連續(xù)空閑空間當(dāng)中首個字節(jié)的地址偏移值就是offset,offset==32(將32個字節(jié)空間組成一個內(nèi)存塊)*內(nèi)存塊號(如,假設(shè)向內(nèi)部存儲器申請64個字節(jié)的連續(xù)空閑存儲空間,通過“mem_malloc(memx,size); ”函數(shù)得到在第五個存儲塊開始有連續(xù)2個存儲快空閑可供使用(假設(shè)是5號和4號存儲快),因為每個存儲快有32個字節(jié)即有32個地址編號,4*32==128(這里的4是指第四塊),5*32==160(這里的5是指第五塊),那么這個160就是40K個字節(jié)編號當(dāng)中的地址偏移值offset,即128-192號就是第四塊和第五塊內(nèi)存塊所對應(yīng)的指針編號);注意offset是地址偏移值而不是地址;為什么要引入地址偏移值這個概念呢?假設(shè)第一個字節(jié)的地址值是0x0000 6800,那么就知道(0x0000 6800+160)的值就是第五塊內(nèi)存的指針。
            3),“(u32)mallco_dev.membase[memx]”代表指針類型數(shù)組,意義是內(nèi)部存儲器40K字節(jié)中的第一個字節(jié)變量的地址,原來存放的是u8類型數(shù)據(jù)的地址,現(xiàn)在強制類型轉(zhuǎn)換擴展為u32類型;
            4),(void*)((u32)mallco_dev.membase[memx]+offset); 轉(zhuǎn)換為無類型指針,指針值是32位,由此可知,“void *mymalloc(u8 memx,u32 size)”函數(shù)的返回值就是一個指針,即形參size所指向的由高向低的首個指針值;“void *mymalloc(u8 memx,u32 size)”是個指針類型函數(shù),只能賦給指針。
            */
            void *mymalloc(u8 memx,u32 size) //p=mymalloc(sramx,2048)
            {
            u32 offset;
            offset=mem_malloc(memx,size);
            if(offset==0XFFFFFFFF)return NULL;
            else return (void*)((u32)mallco_dev.membase[memx]+offset);
            }
            //重新分配內(nèi)存(外部調(diào)用)
            //memx:所屬內(nèi)存塊
            //*ptr:舊內(nèi)存首地址
            //size:要分配的內(nèi)存大小(字節(jié))
            //返回值:新分配到的內(nèi)存首地址.
            void *myrealloc(u8 memx,void *ptr,u32 size)
            {
            u32 offset;
            offset=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)存
            // 把size個字節(jié)指針ptr復(fù)制到“((u32)mallco_dev.membase[memx]+offset)”,
            myfree(memx,ptr); //釋放舊內(nèi)存,因為在mem_malloc(memx,size)中已經(jīng)將連續(xù)空閑內(nèi)存塊標(biāo)注為1(已被占用),清除掉原來的標(biāo)記
            return (void*)((u32)mallco_dev.membase[memx]+offset); //返回新內(nèi)存首地址,無類型指針
            }
            }
            頭文件:
            #ifndef __MALLOC_H
            #define __MALLOC_H
            typedef unsigned long u32;
            typedef unsigned short u16;
            typedef unsigned char u8;
            #ifndef NULL
            #define NULL 0
            #endif
            #define SRAMIN 0 //內(nèi)部內(nèi)存池
            #define SRAMEX 1 //外部內(nèi)存池
            //mem1內(nèi)存參數(shù)設(shè)定.mem1完全處于內(nèi)部SRAM里面
            #define MEM1_BLOCK_SIZE 32 //內(nèi)存塊大小為32字節(jié)
            #define MEM1_MAX_SIZE 40*1024 //最大管理內(nèi)存 40K
            #define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //內(nèi)存表大小
            //mem2內(nèi)存參數(shù)設(shè)定.mem2的內(nèi)存池處于外部SRAM里面,其他的處于內(nèi)部SRAM里面
            #define MEM2_BLOCK_SIZE 32 //內(nèi)存塊大小為32字節(jié)
            #define MEM2_MAX_SIZE 200*1024 //最大管理內(nèi)存200K
            #define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //內(nèi)存表大小

            評論


            技術(shù)專區(qū)

            關(guān)閉