本次给大家分享一位大佬写的应用于单片机内存管理模块memmalloc,这个memmalloc的使用不会产生内存碎片,可以高效利用单片机ram空间。 memmalloc代码仓库: https:github。comchenqy2018memmallocmemmalloc介绍 一般单片机的内存都比较小,而且没有MMU,malloc与free的使用容易造成内存碎片。而且可能因为空间不足而分配失败,从而导致系统崩溃,因此应该慎用,或者自己实现内存管理。memmalloc就是一个不会产生内存碎片的、适合单片机使用的内存管理模块。其与使用malloc的区别如: 算法原理:定义一个数组作为动态分配的堆空间,低地址空间保存管理数据,高地址空间实际分配给用户的缓存(类似堆栈使用,分配是往中间靠拢),free时移动高地址用户空间(以时间换空间),使得未使用的空间都是连续的。memmalloc测试验证 下面以小熊派IOT开发板来做实验。 实验过程很简单。准备一份开发板带串口打印的工程,下载memmalloc,把memmalloc。c、memmalloc。h复制到工程目录下,并添加到工程里: 然后进行编译,编译过程可能会报错:。。Srcmemmalloc。c(119):error:852:expressionmustbeapointertoacompleteobjecttype 这份代码在不同编译器下编译情况不同。gcc下编译不会报错,在keil下编译报如上错误。 keil编译器更严格些。报错原因是对memblock结构体的memptr成员进行操作,而memptr成员的类型是void,而memptr成员参与运算时的增、减偏移量取决于memptr的类型,所以这里我们需要指定类型。 我们把相关报错代码修改如: 再次编译就正常了。 下面简单看一下memmalloc的代码。 memmalloc。h:ifndefMEMMALLOCHdefineMEMMALLOCHifdefcplusplusexternC{endifincludestdio。hincludestdint。hincludestdlib。hincludestring。hincludestdarg。hpragmapack(1)typedefstructmemblock{voidmemptr;unsignedintmemsize;unsignedintmemindex;}memblock;pragmapack()defineMEMSIZE128voidprintmeminfo(void);voidprinthex(chardata,intlen);voidprintmemhex(intsize);intmemmalloc(unsignedintmsize);intmemrealloc(intid,unsignedintmsize);voidmembuffer(intid);intmemfree(intid);ifdefcplusplus}endifendif memmalloc。c: 暂不贴出,感兴趣的小伙伴可以在上面的仓库地址自行下载阅读。可以私信回复:memmalloc,进行获取。 下面对memmalloc进行测试验证。 测试代码作者也有给出,这里我们简单测试即可,进行了一些删减及增加了一些注释:includememmalloc。hcharmemid〔10〕{0};10块内存块voidtestmalloc(inti,intsize){printf(testmalloc);memid〔i〕memmalloc(size);if(memid〔i〕0){printf(mallocfail);printf(sized,size);}else{charpmembuffer(memid〔i〕);memset(p,i,size);printf(p0xx,id,idd,sized,(int)p,i,memid〔i〕,size);}printmemhex(MEMSIZE);}voidtestbuffer(inti,intsize){printf(testbuffer);printf(id,idd,sized,i,memid〔i〕,size);charpmembuffer(memid〔i〕);if(p!NULL){memset(p,0xf0i,size);printmemhex(MEMSIZE);}else{printf(testbufferfail);}}voidtestrealloc(inti,intsize){printf(testrealloc);printf(id,idd,sized,i,memid〔i〕,size);intretmemrealloc(memid〔i〕,size);if(ret){charpmembuffer(memid〔i〕);memset(p,0xa0i,size);printmemhex(MEMSIZE);}else{printf(testreallocfail);}}voidtestfree(inti){printf(testfree);printf(id,idd,i,memid〔i〕);if(memfree(memid〔i〕))printmemhex(MEMSIZE);}voidmain(void){printmeminfo();打印内存信息testmalloc(1,10);给申请一块10个字节的内存,标记内存块id为1testmalloc(2,8);给申请一块8个字节的内存,标记内存块id为2testmalloc(3,20);给申请一块20个字节的内存,标记内存块id为2testfree(2);释放id为2的内存块的内存testmalloc(4,70);申请一块70个字节的内存testfree(1);释放id为1的内存块内存testbuffer(3,20);获取id为3的内存块地址,并往这个内存块重新写入0xf0i的数据testrealloc(3,10);重新分配内存,并往这个内存块重新写入0xa0i的数据for(inti0;i10;i)释放所有内存块内存,已释放的不再重新释放testfree(i);} 运行结果及解析: 这里设定一个128字节的数组作为堆空间使用。其中数组前面存放的是申请到的内存块的信息,包括内存块地址、大小、索引信息,这三个数据各占4个字节,共12个字节。这里有设计到一个大小端模式的问题,STM32平台为小端模式,即数据的低位存储在内存的低地址中。 申请的内存块从128字节的尾部开始分配,再次申请的内存块依次往前移,释放的内存,则整体内存块往后移动,内存块之前不留空隙,即不产生内存碎片。 以上就是本次的分享,如有错误,欢迎指出,谢谢! 猜你喜欢: 手把手教你编写你的第一个上位机 你的单片机裸机程序框架是怎样的? 分享一种简单、实用的测量程序运行时间的方法 1024G嵌入式资源大放送!包括但不限于CC、单片机、Linux等。私信回复1024,即可免费获取!