单片机的动态内存管理——自己实现heap管理

2019-04-15 18:48发布

两年前一位同事和我说过,单片机不能实现动态内存管理,两天后我在keil上利用malloc()在coterx m3芯片上实现了一个链表,然后把代码给他看了,对固执的人摆事实好过讲道理。之后我觉得使用malloc()并不能满足我的需求,然后想自己实现一个heap管理。这就是这篇文章的由来,这是我今天下午突然想到的一种简单的方法,其实这很没有意义,因为我能想到的东西,别人都已经做出来了。嗯,姑且当是一个编程题的实现吧。数据结构很简单,就是先开辟一个大数组,然后将数组分割,每个块大小固定,我定义为16个字节,每个块用一个字节管理,然后记录下有几个块没有被使用。malloc的实现,输入形参和malloc一样,就是内存需求大小,申请成功返回地址,不成功返回NULL。实现思想如下,先计算的出需要几个内存块,然后检测剩余内存块是否足够,如果足够,再检测是否连续,都满足的话,将第一个内存块的管理单元赋值1,第二个赋值2,以此类推。然后将剩余内存块数量减去使用掉的数量,返回地址。free的实现,输入形参和free一样,就是malloc获得的地址,无返回。实现思想如下,先计算出地址相对heap起始地址的偏移,然后得出相应的内存管理单元,如果该内存管理单元为1,将该单元以下连续管理单元都清空,然后将剩余内存块加上相应的地址,返回。这份代码算是1.0版本,没有dubug过,不建议使用。没有debug的原因是没有想到怎么实现碎片管理的办法,我想在2.0版本上面实现,这个姑且算是一份伪代码吧。如果谁有内存碎片管理算法的一些想法的话,欢迎讨论。#include "string.h" #define HEAP_QLY 16 struct general_buf { uint32_t block_qly; //剩余缓存块 uint8_t dirty[100]; //缓存空间脏标志 uint8_t buffer[HEAP_QLY*100]; //缓存空间 }Heap_Buf; /* * 功能:通用缓存初始化 * 输入:无 * 输入:无 * 返回:无 * 备注: */ void heap_buffer_init(void) { Heap_Buf.block_qly = sizeof(Heap_Buf.dirty); memset(Heap_Buf.buffer,0,sizeof(Heap_Buf.buffer)); memset(Heap_Buf.dirty,0,sizeof(Heap_Buf.dirty)); } /* * 功能:堆内存获取函数 * 输入:无 * 输入:无 * 返回:无 * 备注: */ void* my_malloc(uint32_t size) { uint32_t size_need=size/HEAP_QLY+(size%16?1:0);/*获得块需求*/ uint32_t i,j; uint32_t free_num=0; uint8_t* address=NULL; uint8_t enought_space=0; if(size_need>Heap_Buf.block_qly) return NULL; for(i=0;i=size_need){ enought_space=1; break; } }else free_num=0; } if(enought_space){ Heap_Buf.block_qly -= free_num; address = &Heap_Buf.buffer[(i-(free_num-1))*HEAP_QLY]; for(j=0;j=sizeof(Heap_Buf.dirty)); } } 写于2018年3月20日夜深圳