正点原子的内存管理_正点原子【STM32-F407探索者】第四十二章 内存管理实验

1)资料下载:点击资料即可下载

2)对正点原子Linux感兴趣的同学可以加群讨论:935446741

3)关注正点原子公众号,获取最新资料更新

上一章,我们学会了使用 STM32F4 驱动外部 SRAM,以扩展 STM32F4 的内存,加上 STM32F4 本身自带的 192K 字节内存,我们可供使用的内存还是比较多的。如果我们所用的内 存都像上一节的 testsram 那样,定义一个数组来使用,显然不是一个好办法。 本章,我们将学习内存管理,实现对内存的动态管理。本章分为如下几个部分:

42.1 内存管理简介

42.2 硬件设计

42.3 软件设计

42.4 下载验证

42.1 内存管理简介

内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如 何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存管理的实现方法有很多种, 他们其实最终都是要实现 2 个函数:malloc 和 free;malloc 函数用于内存申请,free 函数用于 内存释放。

本章,我们介绍一种比较简单的办法来实现:分块式内存管理。下面我们介绍一下该方法 的实现原理,如图 42.1.1 所示:图 42.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 个内存管理表项目的值都清零,标记释 放,完成一次内存释放。

关于分块式内存管理的原理,我们就介绍到这里。

42.2 硬件设计

本章实验功能简介:开机后,显示提示信息,等待外部输入。KEY0 用于申请内存,每次 申请 2K 字节内存。KEY1 用于写数据到申请到的内存里面。KEY2 用于释放内存。KEY_UP 用于切换操作内存区(内部 SRAM 内存/外部 SRAM 内存/内部 CCM 内存)。DS0 用于指示程 序运行状态。本章我们还可以通过 USMART 调试,测试内存管理函数。

本实验用到的硬件资源有:

1) 指示灯 DS0

2) 四个按键

3) 串口

4) TFTLCD 模块

5) XM8A51216

这些我们都已经介绍过,接下来我们开始软件设计。

42.3 软件设计

打开本章实验工程可以看到,我们新增了 MALLOC 分组,同时在分组中新建了文件

malloc.c 以及头文件 malloc.h。 内存管理相关的函数和定义主要是在这两个文件中。

打开 malloc.c 文件,代码如下:

//内存池(32 字节对齐)

__align(32) u8 mem1base[MEM1_MAX_SIZE]; //内部 SRAM 内存池

__align(32) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000)));

//外部 SRAM 内存池

__align(32) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0X10000000)));

//内部 CCM 内存池

//内存管理表

u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE];

//内部 SRAM 内存池 MAP

u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000

+MEM2_MAX_SIZE)));

//外部 SRAM 内存池 MAP

u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X10000000

+MEM3_MAX_SIZE)));

//内部 CCM 内存池 MAP

//内存管理参数

const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,

MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE}; //内存表大小

const u32 memblksize[SRAMBANK]={MEM1_BLOC

你可能感兴趣的:(正点原子的内存管理)