stm32 内存管理
分块式内存管理
举例
#define MEM1 0 //内部SRAM
#define MEM2 1 //外部SRAM
#define MEM1_BLOCK_SIZE 32 //内存块大小 32字节
#define MEM2_BLOCK_SIZE 32
#define MEM1_MAX_SIZE 10 * 1024 //10K
#define MEM2_MAX_SIZE 40 * 1024
#define MEM1_TABLE_SIZE MEM1_MAX_SIZE / MEM1_BLOCK_SIZE
#define MEM2_TABLE_SIZE MEM2_MAX_SIZE / MEM2_BLOCK_SIZE
u8 mem1_pool_base[MEM1_MAX_SIZE];
u8 mem2_pool_base[MEM2_MAX_SIZE] __attribute__((at(0x68000000)));
u8 mem1_table_base[MEM1_TABLE_SIZE];
u8 mem2_table_base[MEM2_TABLE_SIZE];
typedef struct
{
u8 block_size;
u16 table_size;
u8 *mem_pool; //内存池
u8 *mem_table; //内存管理表
}malloc_t;
malloc_t mal[2] =
{
{MEM1_BLOCK_SIZE, MEM1_TABLE_SIZE, mem1_pool_base, mem1_table_base},
{MEM2_BLOCK_SIZE, MEM2_TABLE_SIZE, mem2_pool_base, mem2_table_base}
};
void *memset(void *s, u8 c, u32 n) //清0
{
u32 i = 0;
u8 *p = s;
for(i = 0; i < n; i++)
{
*(p + i) = c;
}
return s;
}
void mem_init(u8 i)
{
memset(&mal[i].mem_pool, 0, sizeof(mal[i].mem_pool));
memset(&mal[i].mem_table, 0, sizeof(mal[i].mem_table));
}
u32 mem_malloc(u8 i, u32 size)
{
u16 num = 0;
u16 tmp = 0;
int o = 0;
u16 j = 0;
num = size / mal[i].block_size; //整块数量
if(size % mal[i].block_size > 0)
{
num++;
}
for(o = mal[i].table_size - 1; o >= 0; o--)
{
if(mal[i].mem_table[o] == 0) //连续空内存块
{
tmp++;
}
else
{
tmp = 0;
}
if(tmp == num)
{
for(j = 0; j < num; j++)
{
mal[i].mem_table[o + j] = num; //标记非空块
}
return (o * mal[i].block_size); //返回偏移地址
}
}
return 0xFF;
}
void* malloc(u8 i, u32 size)
{
u32 offset;
offset = mem_malloc(i, size);
if(offset != 0xFF)
{
return (void*)((u32)mal[i].mem_pool + offset);
}
else
{
return NULL;
}
}
void mem_free(u8 i, u32 offset)
{
u16 num = 0;
u16 o = 0;
u16 j = 0;
o = offset / mal[i].block_size; //首块偏移
num = mal[i].mem_table[o];
for(j = 0; j < num; j++)
{
mal[i].mem_table[o + j] = 0; //块标记清0
}
}
void free(u8 i, void *addr)
{
u32 offset = 0;
offset = (u32)addr - (u32)mal[i].mem_pool;
mem_free(i, offset);
}
u8 mem_used(u8 i) //内存块使用率
{
u16 used = 0;
u16 j = 0;
for(j = 0; j < mal[i].table_size; j++)
{
if(mal[i].mem_table[j] != 0)
{
used++;
}
}
return (used * 100 / mal[i].table_size);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!