新闻中心

EEPW首页>嵌入式系统>设计应用> 基于stm32f103zet6的内存管理的学习

基于stm32f103zet6的内存管理的学习

作者: 时间:2016-12-01 来源:网络 收藏
主要是依照原子哥哥的代码来初步了解或者说学习一下内存管理,特别对于我们这个想往嵌入式方向发展的人来说,内存管理应该是一种艺术的。

今天在对原子的代码稍作修改是可以进行内存分配和回收的,所以开始深入分析一下这个代码的实现过程。一、所谓的内存管理内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。

本文引用地址://m.amcfsurvey.com/article/201612/324495.htm

二、代码分析

1、首先了解一下一个数据结构,这是一个声明

/*************************** 内存管理控制 **********************************************/ typedef struct {void (*init)(u8);//初始化u8 (*perused)(u8); //内存使用率u8 *membase[2];//内存池 管理2个区域的内存u16 *memmap[2]; //内存管理状态表u8 memrdy[2]; //内存管理是否就绪}_m_mallco_dev;

成员包括两个函数指针(该指针指向函数),两个指针数组和一个u8类型的数组,具体分析下这几个成员的含义,那么首先要找到这个

_m_mallco_dev mallco_dev={mem_init,//内存初始化mem_perused,//内存使用率mem1base,mem2base,//内存池 mem1mapbase,mem2mapbase,//内存管理状态表0,0, //内存管理未就绪};这才是真正定义的地方,现在就可以了解这个几个成员的具体功能了。

a、初始化中 mem_init,mem_perused,这是两个函数,为什么可以这样用呢(直接用函数名)?

可以这样理解么,函数名就像数组名一样,只不过函数名是代码段的指针,而数组名是数据段的指针 ,所以这里函数名就是给函数指针赋值了。当然函数指针并不能说是等于指针的,就像数组一样,数组名不等于指针的。总书记和主席还是不一样的。所以暂时可以这样理解,函数名虽然代表了一个地址,但是这个值是确定了的,但是指针是可以指向别的地址的。就这样!这样写只不过是为了方便我们访问罢了。可以按自己的需要修改!
那么这两个函数的作用?这才是我们最关心的,看这个
void mem_init(u8 memx) { mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//内存状态表数据清零 mymemset(mallco_dev.membase[memx], 0,memsize[memx]);//内存池所有数据清零 mallco_dev.memrdy[memx]=1;//内存管理初始化OK } b、注释很明确,那么接下来就是分析这个三句话的作用,没办法,我无法做到,一眼能看出究竟。
mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);等价于mymemset(mem1base, 0,0x500*2)
它里面的内容很简单就是
void mymemset(void *s,u8 c,u32 count) { u8 *xs = s; while(count--)*xs++=c; }以mem1base为首地址的大小为0xa00的内容清0,那么mem1base又是什么呢?接下来看看
__align(4) u8 mem1base[MEM1_MAX_SIZE];这明显是4字节对齐的内部SRAM的地址,也就是我们的flash里面的地址。所以这就实现了对我们内部flash0xa00的内容清零,好的继续看下面的
c、 mymemset(mallco_dev.membase[memx], 0,memsize[memx]);//内存池所有数据清零
自然地这个也是一个意思,清零,唯一不同的就是代表的意思不一样,到底是内存池数据清零,还是状态表的清零,我们看不出来,那么只有继续分析了。清零完成就给相应的数组元素填充1表示完成标志。至此我们第一个初始化成员就分析完毕!!
2、下面开始分析第二个成员perused函数
先看函数如何定义的/***************************************************************************************
名 称: mem_perused
* 功 能: 获取内存使用率
* 参 数: *memx:所属内存块
* 返 回 值: 使用率(0~100)**************************************************************************************
/u8 mem_perused(u8 memx)
{ u32 used=0; u32 i;
for(i=0;i { if(mallco_dev.memmap[memx][i])used++;
} return (used*100)/(memtblsize[memx]);
} 这里可以看到出现一个这样的表达式,需要仔细分析!mallco_dev.memmap[memx][i]
分解一下,还是一样,这个是指针数组,也就是数组里面存放的是指针,那么这里给它赋值为一个数组名mem1mapbase,但是访问的时候还是可以用下表来访问的。那么可以替换为:if(mem1mapbase[i]) used++;看到没,这还是我们之前访问过了的那个数组,只不过这里是当非零的时候执行used++,也就是我们占用了才会进行++。那么作用就是:used表示的是占用了的大小。(used*100)/(memtblsize[memx])表示的就是占用值,memtblsize[memx]使我们分配的总的大小,到这里那么第二个成员也分析完毕。
3、后面这几个成员变量,之前就已经分析过了。mem1base,mem2base,//内存池mem1mapbase,mem2mapbase,//内存管理状态表0,0, 这里就不详述了。这个数据结果分析至此,那么接下来看我们分配内存的过程究竟如何实现?
三、分配内存
首先看一个核心代码如下


上一页 1 2 下一页

评论


技术专区

关闭