一个简单的MCU内存管理方法附源码

北京皮炎网上医院 http://m.39.net/pf/a_9051917.html

点击上方“嵌入式情报局”,选择“置顶/星标”

嵌入式情报,第一时间送达

内存管理一般在操作系统中才有,比如:Linux、Windows这些操作系统都有内存管理器,包括大部分RTOS同样也有内存管理。

那你知道,在无操作系统的情况下,怎么管理内存吗?

下面给大家分享一份源码:基于无操作系统的STM32单片机开发,功能强大,可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。

1、源码说明

源码包含memory.h和memory.c两个文件(嵌入式C/C++代码的“标配”),其源码中包含重要的注释。

memory.h文件包含结构体等定义,函数API申明等;memory.c文件是实现内存管理相关API函数的原型。2、头文件memory.h头文件是相关的定义和申请:

#ifndef__MEMORY_H__#define__MEMORY_H__#include"stdio.h"#include"string.h"#include"includes.h"//用户使用typedefstruct{void*addr;//申请到的内存的起始地址uint32_tsize;//申请到的内存的大小,按照块大小分配,大于等于申请大小uint16_ttb;//申请表序号,申请内存时分配,释放内存时使用,用户不使用}DMEM;//若返回空,则申请失败DMEM*DynMemGet(uint32_tsize);voidDynMemPut(DMEM*pDmem);#endif//__MEMORY_H__

这里的代码比较简单,也是常规的写法,重点是要理解结构体成员的含义。

3、源文件memory.c源文件主要就是实现内存管理的函数,源码比较多,这里才分为三部分。1.相关的定义

#include"memory.h"#defineDMEM_BLOCK_SIZE//内存块大小为字节#defineDMEM_BLOCK_NUM20//内存块个数为40个#defineDMEM_TOTAL_SIZE(DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM)//内存总大小staticuint8_tDMEMORY[DMEM_TOTAL_SIZE];staticDMEM_STATEDMEMS={0};typedefenum{DMEM_FREE=0,DMEM_USED=1,}DMEM_USED_ITEM;typedefstruct{DMEM_USED_ITEMused;//使用状态uint16_tblk_s;//起始块序号uint16_tblk_num;//块个数}DMEM_APPLY;typedefstruct{DMEM_USED_ITEMtb_blk[DMEM_BLOCK_NUM];DMEMtb_user[DMEM_BLOCK_NUM];//用户申请内存信息DMEM_APPLYtb_apply[DMEM_BLOCK_NUM];//系统分配内存信息uint16_tapply_num;//内存申请表占用数目uint16_tblk_num;//内存块占用数目}DMEM_STATE;2.内存分配函数DynMemGet

DMEM*DynMemGet(uint32_tsize){uint16_tloop=0;uint16_tfind=0;uint16_tblk_num_want=0;DMEM*user=NULL;DMEM_APPLY*apply=NULL;//申请内存大小不能为0if(size==0){returnNULL;}//申请内存不可超过总内存大小if(sizeDMEM_TOTAL_SIZE){returnNULL;}//申请内存不可超过剩余内存大小if(size(DMEM_BLOCK_NUM-DMEMS.blk_num)*DMEM_BLOCK_SIZE){returnNULL;}//申请表必须有空余if(DMEMS.apply_num=DMEM_BLOCK_NUM){returnNULL;}//计算所需连续块的个数blk_num_want=(size+DMEM_BLOCK_SIZE-1)/DMEM_BLOCK_SIZE;//寻找申请表for(loop=0;loopDMEM_BLOCK_NUM;loop++){if(DMEMS.tb_apply[loop].used==DMEM_FREE){apply=DMEMS.tb_apply[loop];//申请表已找到user=DMEMS.tb_user[loop];//用户表对应找到user-tb=loop;//申请表编号记录user-size=blk_num_want*DMEM_BLOCK_SIZE;//分配大小计算break;}}//没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验if(loop==DMEM_BLOCK_NUM){returnNULL;}//寻找连续内存块for(loop=0;loopDMEM_BLOCK_NUM;loop++){if(DMEMS.tb_blk[loop]==DMEM_FREE){//找到第一个空闲内存块for(find=1;(findblk_num_want)(loop+findDMEM_BLOCK_NUM);find++){//找到下一个空闲内存块if(DMEMS.tb_blk[loop+find]!=DMEM_FREE){//发现已使用内存块break;}}if(find=blk_num_want){//寻找到的空闲内存块数目已经够用user-addr=DMEMORY+loop*DMEM_BLOCK_SIZE;//计算申请到的内存的地址apply-blk_s=loop;//记录申请到的内存块首序号apply-blk_num=blk_num_want;//记录申请到的内存块数目for(find=0;findapply-blk_num;find++){DMEMS.tb_blk[loop+find]=DMEM_USED;}apply-used=DMEM_USED;//标记申请表已使用DMEMS.apply_num+=1;DMEMS.blk_num+=blk_num_want;returnuser;}else{//寻找到的空闲内存块不够用,从下一个开始找loop+=find;}}}//搜索整个内存块,未找到大小适合的空间returnNULL;}

3.内存释放函数DynMemPut

voidDynMemPut(DMEM*user){uint16_tloop=0;//若参数为空,直接返回if(NULL==user){return;}//释放内存空间for(loop=DMEMS.tb_apply[user-tb].blk_s;loopDMEMS.tb_apply[user-tb].blk_s+DMEMS.tb_apply[user-tb].blk_num;loop++){DMEMS.tb_blk[loop]=DMEM_FREE;DMEMS.blk_num-=1;}//释放申请表DMEMS.tb_apply[user-tb].used=DMEM_FREE;DMEMS.apply_num-=1;}代码中包含注释,注释描述的比较清楚,也比较容易理解。素材来源:


转载请注明:http://www.aierlanlan.com/rzgz/468.html