你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第四十三章 内存管理实验

[复制链接]
正点原子-90136 提问时间:2013-4-3 23:08 /
  
第四十三章内存管理实验

上一节,我们学会了使用STM32驱动外部SRAM,以扩展STM32的内存,加上STM32本身自带的64K字节内存,我们可供使用的内存还是比较多的。如果我们所用的内存都像上一节的testsram那样,定义一个数组来使用,显然不是一个好办法。
本章,我们将学习内存管理,实现对内存的动态管理。本章分为如下几个部分:
43.1 内存管理简介
43.2 硬件设计
43.3 软件设计
43.4 下载验证

<div style="layout-grid:  15.6pt none">43.1内存管理简介
内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存管理的实现方法有很多种,他们其实最终都是要实现2个函数:malloc和free;malloc函数用于内存申请,free函数用于内存释放。
本章,我们介绍一种比较简单的办法来实现:分块式内存管理。下面我们介绍一下该方法的实现原理,如图43.1.1所示:

图43.1.1 分块式内存管理原理       从上图可以看出,分块式内存管理由内存池和内存管理表两部分组成。内存池被等分为n块,对应的内存管理表,大小也为n,内存管理表的每一个项对应内存池的一块内存。
       内存管理表的项值代表的意义为:当该项值为0的时候,代表对应的内存块未被占用,当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为10,那么说明包括本项对应的内存块在内,总共分配了10个内存块给外部的某个指针。
内寸分配方向如图所示,是从顶à底的分配方向。即首先从最末端开始找空内存。当内存管理刚初始化的时候,内存表全部清零,表示没有任何内存块被占用。
分配原理
当指针p调用malloc申请内存的时候,先判断p要分配的内存块数(m),然后从第n项开始,向下查找,直到找到m块连续的空内存块(即对应内存管理表项为0),然后将这m个内存管理表项的值都设置为m(标记被占用),最后,把最后的这个空内存块的地址返回指针p,完成一次分配。注意,如果当内存不够的时候(找到最后也没找到连续的m块空闲内存),则返回NULL给p,表示分配失败。
释放原理
当p申请的内存用完,需要释放的时候,调用free函数实现。free函数先判断p指向的内存地址所对应的内存块,然后找到对应的内存管理表项目,得到p所占用的内存块数目m(内存管理表项目的值就是所分配内存块的数目),将这m个内存管理表项目的值都清零,标记释放,完成一次内存释放。
关于分块式内存管理的原理,我们就介绍到这里。
 
43.2硬件设计
本章实验功能简介:开机后,显示提示信息,等待外部输入。KEY0用于申请内存,每次申请2K字节内存。KEY1用于写数据到申请到的内存里面。KEY2用于释放内存。WK_UP用于切换操作内存区(内部内存/外部内存)。DS0用于指示程序运行状态。本章我们还可以通过USMART调试,测试内存管理函数。
本实验用到的硬件资源有:
1) 指示灯DS0
2) 四个按键
3) 串口
4) TFTLCD模块
5) IS62WV51216
这些我们都已经介绍过,接下来我们开始软件设计。
43.3软件设计
本章,我们将内存管理部分单独做一个分组,在工程目录下新建一个MALLOC的文件夹,然后新建malloc.c和malloc.h两个文件,将他们保存在MALLOC文件夹下。
在MDK新建一个MALLOC的组,然后将malloc.c文件加入到该组,并将MALLOC文件夹添加到头文件包含路径。
       打开malloc.c文件,输入如下代码:
#include "malloc.h"         
//内存池(4字节对齐)
__align(4) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池                                 
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000)));
//外部SRAM内存池
//内存管理表
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE];  //内部SRAM内存池MAP                        u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+
MEM2_MAX_SIZE))); //外部SRAM内存池MAP
//内存管理参数       
const u32 memtblsize[2]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE};        //内存表大小
const u32 memblksize[2]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE};                                //内存分块大小
const u32 memsize[2]={MEM1_MAX_SIZE,MEM2_MAX_SIZE};                                            //内存总大小
//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
       mem_init,                                   //内存初始化
       mem_perused,                             //内存使用率
       mem1base,mem2base,                  //内存池
       mem1mapbase,mem2mapbase,      //内存管理状态表
       0,0,                                   //内存管理未就绪
};
//复制内存
//*des:目的地址
//*src:源地址
//n:需要复制的内存长度(字节为单位)
void mymemcpy(void *des,void *src,u32 n) 

    u8 *xdes=des;
       u8 *xsrc=src;
    while(n--)*xdes++=*xsrc++; 

//设置内存
//*s:内存首地址
//c :要设置的值
//count:需要设置的内存大小(字节为单位)
void mymemset(void *s,u8 c,u32 count) 

    u8 *xs = s; 
    while(count--)*xs++=c; 
}       
//内存管理初始化 
//memx:所属内存块
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 

//获取内存使用率
//memx:所属内存块
//返回值:使用率(0~100)
u8 mem_perused(u8 memx) 

    u32 used=0; 
    u32 i; 
    for(i=0;i=0;offset--)//搜索整个内存控制区 
    {    
              if(!mallco_dev.memmap[memx][offset])cmemb++;//连续空内存块数增加
              else cmemb=0;                                          //连续内存块清零
              if(cmemb==nmemb)                                  //找到了连续nmemb个空内存块
              {
            for(i=0;i

《STM32开发指南》第四十三章 内存管理实验.rar

下载

574.29 KB, 下载次数: 12, 下载积分: ST金币 -1

实验38 内存管理实验.rar

下载

189.19 KB, 下载次数: 9, 下载积分: ST金币 -1

收藏 评论0 发布时间:2013-4-3 23:08

举报

0个回答

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版