简单的办法来实现STM32分块式内存管理

发布者:fnfeecjknquc最新更新时间:2023-10-25 来源: elecfans关键字:STM32  软件运行 手机看文章 扫描二维码
随时随地手机看文章

一、内存管理简介

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


简单的办法来实现STM32分块式内存管理


内存管理表的项值代表的意义为:当该项值为 0 的时候,代表对应的内存块未被占用,当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为 10,那么说明包括本项对应的内存块在内,总共分配了 10 个内存块给外部的某
个指针。内寸分配方向如图所示,是从顶到底的分配方向。即首先从最末端开始找空内存。当内存管理刚初始化的时候,内存表全部清零,表示没有任何内存块被占用。


二、分配原理

当指针 p 调用 malloc 申请内存的时候,先判断 p 要分配的内存块数(m),然后从第 n 项开始,向下查找,直到找到 m 块连续的空内存块(即对应内存管理表项为 0),然后将这 m 个内存管理表项的值都设置为 m(标记被占用),最后,把最后的这个空内存块的地址返回指针 p,完成一次分配。注意,如果当内存不够的时候(找到最后也没找到连续的 m 块空闲内存),则返回 NULL 给 p,表示分配失败。


三、释放原理
当 p 申请的内存用完,需要释放的时候,调用 free 函数实现。free 函数先判断 p 指向的内存地址所对应的内存块,然后找到对应的内存管理表项目,得到 p 所占用的内存块数目 m(内存管理表项目的值就是所分配内存块的数目),将这 m 个内存管理表项目的值都清零,标记释放,完成一次内存释放。

四、部分驱动函数

//内存池(32字节对齐)
__align(32) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
__align(32) 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[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE};//内存表大小
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE};//内存分块大小
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE};//内存总大小


//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
my_mem_init, //内存初始化
my_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 my_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 my_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]);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
u32 my_mem_malloc(u8 memx,u32 size)
{
signed long offset=0;
u32 nmemb; //需要的内存块数
u32 cmemb=0;//连续空内存块数
u32 i;
if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先执行初始化
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/memblksize[memx]; //获取需要分配的连续内存块数
if(size%memblksize[memx])nmemb++;
for(offset=memtblsize[memx]-1;offset>=0;offset--)//搜索整个内存控制区
{
if(!mallco_dev.memmap[memx][offset])cmemb++;//连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb)//找到了连续nmemb个空内存块
{
for(i=0;i {
mallco_dev.memmap[memx][offset+i]=nmemb;
}
return (offset*memblksize[memx]);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
u8 my_mem_free(u8 memx,u32 offset)
{
int i;
if(!mallco_dev.memrdy[memx])//未初始化,先执行初始化
{
mallco_dev.init(memx);
return 1;//未初始化
}
if(offset {
int index=offset/memblksize[memx]; //偏移所在内存块号码
int nmemb=mallco_dev.memmap[memx][index]; //内存块数量
for(i=0;i {
mallco_dev.memmap[memx][index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
//释放内存(外部调用)
//memx:所属内存块
//ptr:内存首地址
void myfree(u8 memx,void *ptr)
{
u32 offset;
if(ptr==NULL)return;//地址为0.
offset=(u32)ptr-(u32)mallco_dev.membase[memx];
my_mem_free(memx,offset); //释放内存
}
//分配内存(外部调用)
//memx:所属内存块
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u8 memx,u32 size)
{
u32 offset;
offset=my_mem_malloc(memx,size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)mallco_dev.membase[memx]+offset);
}


关键字:STM32  软件运行 引用地址:简单的办法来实现STM32分块式内存管理

上一篇:stm32mp1 Cortex M4开发篇7:窗口看门狗
下一篇:GD32 MCU的引脚输出功能应用配置

推荐阅读最新更新时间:2024-11-13 11:22

stm32 嵌套向量中断控制器NVIC
嵌套向量中断控制器(NVIC)和处理器核的接口紧密相连,可以实现低延迟的中断处理和高效地处理晚到的中断。 嵌套向量中断控制器管理着包括内核异常等中断 NVIC 相关的函数包含在 misc.c 文件中 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) void NVIC_SystemLPConfig(uint8_t LowPower
[单片机]
<font color='red'>stm32</font> 嵌套向量中断控制器NVIC
STM32自学之串口中断模式
今天是自学STM32的第7天了,之前的流水灯,按键,查询方式串口,PWM,计数器和红外有时间再补上来吧,先从今天调试的中断式串口写起吧。 事先说明,写此博客只是为了记录自己的自学历程,由于水平极其有限,所以很多理解可能是错的,欢迎大家积极指出,让我们一起在嵌入式的开发上向前进。 我所使用的是神舟三号学习开发板,芯片型号是STM32F103ZE。功能很齐全了,作为初期自学用绰绰有余。 串口的printf在STM32程序调试过程中,确实可以起到实时跟踪程序进程的作用,但是经过昨天的红外和今天的中断式串口程序的坑爹BUG之后,深深感觉,没事还是不要加printf了,特别是在待处理事件的时间频率很高时,如昨天的红外调试时,
[单片机]
STM32 FreeRTOS Keil环境搭建
由于FreeRTOS的官方已经支持STM32F1X系列的Cortex-M3的移植,所以只需要在Keil IDE中设置相关即可了; 在Keil中新建一工程,在工程中新建3个组,分别对应3个目录用来存放:user、rtos、stmlib user中添加用户自己的代码和头文件; rtos中添加rots的文件主要有:list.c、task.c、queue.c、head_2.c、port.c stmlib中添加STM32官方提供的STM32操作的lib库(注意stm32f10x_md.s中的内容和替换为FreeRTOS Demo 中的STM32F10X.s否则系统调度不能正常工作) 另外需要把FreeRTOS/source/inc
[单片机]
STM32单片机学习(12) 红外信号接收解码(外部中断)
本程序主要利用外部中断,实现红外遥控器信号接收解码,并利用串口通信把编码传至计算机显示 注: 请用质量好点的遥控器实验 用了劣质遥控器浪费了一天时间,数据位接收总是不完整,后来用宿舍空调遥控器就解码成功了 相关资料 STM32单片机学习(2) 外部中断 http://blog.csdn.net/leytton/article/details/38063335 STM32单片机学习(3) 串口中断通信 http://blog.csdn.net/leytton/article/details/38393553 STM32单片机学习(7) 串口通信printf重定向 http://blog.csdn.net/leytto
[单片机]
<font color='red'>STM32</font>单片机学习(12) 红外信号接收解码(外部中断)
基于STM32设计的宠物投喂器
1. 前言 随着物联网技术的快速发展,智能家居已经进入人们的日常生活中,在政策加持的背景下,智能家居企业越来越关注相关技术的研发和应用;但是市场上的宠物投喂装置已经难以满足宠物主人的需求。文章介绍的宠物智能投喂装置是以STM32为核心,多个模块协调配合,共同完成针对不同年龄段的宠物进行定时定量投喂及实时环境监测与高温报警、以及主人随时可以通过智能设备了解宠物生活环境、为宠物加餐等功能。该系统的功能完善、价格低廉,使用方便,解决了宠物饲养者外出时的后顾之忧,还能保证宠物的进食有一定的规律性。 设计了一个宠物投喂器,支持手动控制粮食投喂,设置恒温阀值,定时投喂、温度、湿度实时显示、剩余粮食重量等功能。 2. 需求 做一个基于S
[单片机]
基于<font color='red'>STM32</font>设计的宠物投喂器
stm32 在线升级 总结
一、前两篇博客实现的功能是在APP和IAP之间进行程序跳转; 二、这里面有以下需要注意的地方; 1、程序跳转函数切记不要在定时器中断里编写,否则程序可以正常跳转但是中断功能却不能执行。原因,可以参考以下链接; http://xzq1019.blog.163.com/blog/static/5996566520100181146689/ 就是,在中断里进行跳转的话,stm32会认为跳转函数只是中断处理函数的一部分,所以会出现挂起,不能再响应中断。一般的做法是在中断里设标志位,在主函数里进行跳转。 2、在IAP程序跳转前关闭总中断,在跳转到APP程序后,打开总中断。 3、中断的打开和关闭可以利用下面的函数 __disable_irq(
[单片机]
在Keil MDK环境下使用STM32固件库
简介 写这篇教程主要是和大家分享使用STM32的基本方法,也是给自己学习过程的总结、记录和备忘,避免重复学习之前明白但又忘记的知识和操作。我现在也是刚开始接触学习STM32,我是在STM32的固件库V3基础上进行学习。在这里我和大家分享一下使用V3.x库的方法,希望大家喜欢,如有错误请指出。 这篇教程分以下几个方面,一:建立工程,设置工程属性。二:建立条理清晰的GROUP;三:使用JLINK仿真调试。下面就分别逐个说明。 一、新建MDK工程 1、首先,打开MDK软件,再点击Project- New uVision Project ,如下图所示: 弹出如下对话框: 新建一个文件夹MDK工
[单片机]
STM32 之二 HAL库详解 及 手动移植
HAL库结构   说到STM32的HAL库,就不得不提STM32CubeMX,其作为一个可视化的配置工具,对于开发者来说,确实大大节省了开发时间。STM32CubeMX就是以HAL库为基础的,且目前仅支持HAL库及LL库!首先看一下,官方给出的HAL库的包含结构: - **stm32f2xx.h**主要包含STM32同系列芯片的不同具体型号的定义,是否使用HAL库等的定义,接着,其会根据定义的芯片信号包含具体的芯片型号的头文件: #if defined(STM32F205xx) #include stm32f205xx.h #elif defined(STM32F215xx) #include stm32f215xx
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved