umm_malloc,微控制器内存分配神器,让你的嵌入式 Heap 管理秒变简单!

嘿,最近在折腾 ARM7 这种微控制器,突然发现一个超酷的内存管理库——umm_malloc。真心觉得,嵌入式里要搞点动态内存分配,用系统自带的 malloc/free 不仅大,而且不一定可用。umm_malloc 这家伙小巧、可靠,还专门针对 8/16/32 位芯片优化,简直是写裸机、RTOS、甚至大项目里管理一堆小对象的救星。

是什么
umm_malloc,全称 “Memory Manager For Small(ish) Microprocessors”。
– 纯 C 实现,几乎不依赖系统,直接把堆当成一个块数组来玩;
– 用 15 位 block 索引替代 32 位指针,头部开销只有 8 字节;
– 分配的块体只需 4 字节管理空间。
换句话说,整个管理模块不到十几 KB,开销超低,还能配置多个独立 heap。

解决了哪些问题和痛点

  1. 1. 嵌入式环境里系统堆可能不存在,或者没办法调试。

  2. 2. 大项目里想在一个进程中管理 N 个小对象,系统 malloc 频繁碎片化;

  3. 3. 资源受限平台,32 位指针链表太“奢侈”,内存头部开销大;

  4. 4. 想随时 dump heap、检查完整性、防写越界……系统库根本没有。
    umm_malloc 就凭这些特性,把大部分痛点都对号入座、拿出来解决了。

主要 API 一览

函数

功能

void umm_init()

在链接时根据符号初始化堆

void umm_init_heap(void *ptr, size_t size)

运行时手动初始化堆

void *umm_malloc(size_t size)

申请一块内存

void umm_free(void *ptr)

释放内存

void *umm_realloc(void *ptr, size_t size)

调整已分配块大小

如果你需要多堆管理,就用一套 umm_multi_* 接口,第一参数传 umm_heap*。很灵活。

代码示例

#include "umm_malloc_cfgport.h"
#include "umm_malloc.h"

// 链接时定义堆地址和大小
#define UMM_MALLOC_CFG_HEAP_ADDR    my_heap_start
#define UMM_MALLOC_CFG_HEAP_SIZE    (16*1024)

extern uint8_t my_heap_start[];// 在 linker script 里分配

int main(void){
   umm_init();// 或者 umm_init_heap(ptr, size);

   char *buf1 =(char*)umm_malloc(64);
   if (buf1){
      strcpy(buf1,"Hello, umm_malloc!");
      printf("%s\n", buf1);
   }

    buf1 =(char*)umm_realloc(buf1,128);
    umm_free(buf1);

    return 0;
}

要启用更丰富的调试(dump、完整性检查、poison 检测),在 config 里打开 UMM_INFO、UMM_INTEGRITY_CHECK、UMM_POISON_CHECK,然后调用对应接口就行。

优缺点

优点

缺点

头部开销仅 8 字节,块对齐灵活

默认不带多线程/中断安全,需要自己加锁

用 block 索引替代指针,节省 50% 元数据空间

对齐、堆地址/大小要手动通过宏或 API 设置

支持多堆管理,API 同步,切换简单

不支持内置垃圾回收,只有基础 malloc/free

可选开启 heap dump、完整性、边界溢出检测

适用于小内存场景,大堆时效率未必最佳

测试用例齐全,CMock + Ceedling 一键跑

需要一个 umm_malloc_cfgport.h(可空)

总结
好了,大致聊完了。umm_malloc 虽然算不上新概念,但把“嵌入式专用”做到了极致:最小化头部开销、简单可移植、测试驱动、多堆支持,还能按需打开各种调试选项。对比传统的 malloc/free,你会发现它更接地气、更透明,也更好调试。要是你的项目里真有动态分配需求,不妨拉下来折腾一下。

项目地址:https://github.com/rhempel/umm_malloc

发表评论