现在非常多的的mcu性能都还不错,同时用户也会去扩展一些外部ram,这样如果高效便捷的管理这些内存是一个重要话题。
今天给大家分享一份源码:基于无操作系统的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//用户使用typedef struct{ void *addr; //申请到的内存的起始地址 uint32_t size; //申请到的内存的大小,按照块大小分配,大于等于申请大小 uint16_t tb; //申请表序号,申请内存时分配,释放内存时使用,用户不使用}dmem;//若返回空,则申请失败dmem *dynmemget(uint32_t size);void dynmemput(dmem *pdmem);#endif //__memory_h__
这里的代码比较简单,也是常规的写法,重点是要理解结构体成员的含义。
3
源文件memory.c
源文件主要就是实现内存管理的函数,源码比较多,这里才分为三部分。1、相关的定义#include memory.h#define dmem_block_size 256 //内存块大小为128字节#define dmem_block_num 20 //内存块个数为40个#define dmem_total_size (dmem_block_size*dmem_block_num) //内存总大小static uint8_t dmemory[dmem_total_size];static dmem_state dmems = {0};typedef enum{ dmem_free = 0, dmem_used = 1,}dmem_used_item;typedef struct{ dmem_used_item used; //使用状态 uint16_t blk_s; //起始块序号 uint16_t blk_num; //块个数}dmem_apply;typedef struct{ dmem_used_item tb_blk[dmem_block_num]; dmem tb_user[dmem_block_num]; //用户申请内存信息 dmem_apply tb_apply[dmem_block_num]; //系统分配内存信息 uint16_t apply_num; //内存申请表占用数目 uint16_t blk_num; //内存块占用数目}dmem_state;
2、内存分配函数dynmemgetdmem *dynmemget(uint32_t size){ uint16_t loop = 0; uint16_t find = 0; uint16_t blk_num_want = 0; dmem * user = null; dmem_apply *apply = null; //申请内存大小不能为0 if(size == 0) { return null; } //申请内存不可超过总内存大小 if(size > dmem_total_size) { return null; } //申请内存不可超过剩余内存大小 if(size > (dmem_block_num - dmems.blk_num) * dmem_block_size) { return null; } //申请表必须有空余 if(dmems.apply_num >= dmem_block_num) { return null; } //计算所需连续块的个数 blk_num_want = (size + dmem_block_size - 1) / dmem_block_size; //寻找申请表 for(loop = 0; loop tb = loop; //申请表编号记录 user->size = blk_num_want * dmem_block_size; //分配大小计算 break; } } //没有找到可用申请表,理论上是不会出现此现象的,申请表剩余已在上面校验 if(loop == dmem_block_num) { return null; } //寻找连续内存块 for(loop = 0; loop < dmem_block_num; loop++) { if(dmems.tb_blk[loop] == dmem_free) {//找到第一个空闲内存块 for(find = 1; (find < blk_num_want) && (loop + find = blk_num_want) {//寻找到的空闲内存块数目已经够用 user->addr = dmemory + loop * dmem_block_size; //计算申请到的内存的地址 apply->blk_s = loop; //记录申请到的内存块首序号 apply->blk_num = blk_num_want; //记录申请到的内存块数目 for(find = 0 ; find blk_num; find++) { dmems.tb_blk[loop + find] = dmem_used; } apply->used = dmem_used; //标记申请表已使用 dmems.apply_num += 1; dmems.blk_num += blk_num_want; return user; } else {//寻找到的空闲内存块不够用,从下一个开始找 loop += find; } } } //搜索整个内存块,未找到大小适合的空间 return null;}
3、内存释放函数dynmemputvoid dynmemput(dmem *user){ uint16_t loop = 0; //若参数为空,直接返回 if(null == user) { return; } //释放内存空间 for(loop = dmems.tb_apply[user->tb].blk_s; loop 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;}
代码中包含注释,注释描述的比较清楚,也比较容易理解。
原文标题:一个简单的mcu内存管理模块(附源码)
文章出处:【微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。
已确定Vivo V19的发布日期为3月10日
VR技术在零售商公共决策规划中发挥着重要作用
WiFi模块IBF165,3路开关量输入,2路开关量/PWM输出
闭环控制系统的结构框图
罗技发布新款无线游戏鼠标 提供1ms报告率几乎零延迟
基于无操作系统的STM32单片机开发
有助于数据集增强的GAN体系结构,包括样本增强和特征增强
丰田发布2023年全球销量数据
激发态分子内质子转移及荧光光谱的理论研究
Vishay推出节省空间的小型0402外形尺寸新型器件
振动在线监测系统中的传感器介绍
EL156 A类单端功率放大器,EL156 power amplifier
笔记本加装内存条的注意事项
关于RFID测温技术在电力行业中的应用
聚光太阳能业务发展
伺服电机工作原理的简单说明
高效电源管理可延长电池寿命
机器人改变了整个物流仓储生产模式的格局
Qorvo®推出首款具有业界领先的性能的高可靠性全集成式汽车eCall开关
小小的整流桥堆为什么能走25A的电流?