STM32CubeIDE 使用正点原子的内存管理MALLOC
在正点原子开发板stm32F767igt6 平台。
一 keil原代码
1.1 malloc.h
#ifndef _MALLOC_H
#define _MALLOC_H
#include "sys.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F7开发板
//内存管理 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2015/12/12
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//
#ifndef NULL
#define NULL 0
#endif
//定义三个内存池
#define SRAMIN 0 //内部内存池
#define SRAMEX 1 //外部内存池(SDRAM)
#define SRAMDTCM 2 //DTCM内存池(此部分SRAM仅仅CPU可以访问!!!)
#define SRAMBANK 3 //定义支持的SRAM块数.
//mem1内存参数设定.mem1完全处于内部SRAM里面.
#define MEM1_BLOCK_SIZE 64 //内存块大小为64字节
#define MEM1_MAX_SIZE 160*1024 //最大管理内存 160K
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //内存表大小
//mem2内存参数设定.mem2的内存池处于外部SDRAM里面
#define MEM2_BLOCK_SIZE 64 //内存块大小为64字节
#define MEM2_MAX_SIZE 28912 *1024 //最大管理内存28912K
#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //内存表大小
//mem3内存参数设定.mem3处于CCM,用于管理DTCM(特别注意,这部分SRAM,仅CPU可以访问!!)
#define MEM3_BLOCK_SIZE 64 //内存块大小为64字节
#define MEM3_MAX_SIZE 60 *1024 //最大管理内存60K
#define MEM3_ALLOC_TABLE_SIZE MEM3_MAX_SIZE/MEM3_BLOCK_SIZE //内存表大小
//内存管理控制器
struct _m_mallco_dev
{
void (*init)(u8); //初始化
u16 (*perused)(u8); //内存使用率
u8 *membase[SRAMBANK]; //内存池 管理SRAMBANK个区域的内存
u32 *memmap[SRAMBANK]; //内存管理状态表
u8 memrdy[SRAMBANK]; //内存管理是否就绪
};
extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义
void mymemset(void *s,u8 c,u32 count); //设置内存
void mymemcpy(void *des,void *src,u32 n);//复制内存
void my_mem_init(u8 memx); //内存管理初始化函数(外/内部调用)
u32 my_mem_malloc(u8 memx,u32 size); //内存分配(内部调用)
u8 my_mem_free(u8 memx,u32 offset); //内存释放(内部调用)
u16 my_mem_perused(u8 memx) ; //获得内存使用率(外/内部调用)
//用户调用函数
void myfree(u8 memx,void *ptr); //内存释放(外部调用)
void *mymalloc(u8 memx,u32 size); //内存分配(外部调用)
void *myrealloc(u8 memx,void *ptr,u32 size);//重新分配内存(外部调用)
#endif
1.2 malloc.C
#include "malloc.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F7开发板
//内存管理 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2015/12/12
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//
//内存池(32字节对齐)
__align(32) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
__align(32) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0XC01F4000))); //外部SDRAM内存池,前面2M给LTDC用了(1280*800*2)
__align(32) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0X20000000))); //内部DTCM内存池
//内存管理表
u32 mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
u32 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0XC01F4000+MEM2_MAX_SIZE))); //外部SRAM内存池MAP
u32 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X20000000+MEM3_MAX_SIZE))); //内部DTCM内存池MAP
//内存管理参数
const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE}; //内存表大小
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE}; //内存分块大小
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE}; //内存总大小
//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
my_mem_init, //内存初始化
my_mem_perused, //内存使用率
mem1base,mem2base,mem3base, //内存池
mem1mapbase,mem2mapbase,mem3mapbase,//内存管理状态表
0,0,0, //内存管理未就绪
};
//复制内存
//*des:目的地址
//*src:源地址
//n:需要复制的内存长度(字节为单位)
void mymemcpy(void *des,void *src,u32 n)
{
u8 *xdes=des;
u8 *xsrc=src;
while(n--)*xdes++=*xsrc++;
}
//设置内存
//*s:内存首地址
//c :要设置的值
//count:需要设置的内存大小(字节为单位)
void mymemset(void *s,u8 c,u32 count)
{
u8 *xs = s;
while(count--)*xs++=c;
}
//内存管理初始化
//memx:所属内存块
void my_mem_init(u8 memx)
{
mymemset(mallco_dev.memmap[memx],0,memtblsize[memx]*4); //内存状态表数据清零
mallco_dev.memrdy[memx]=1; //内存管理初始化OK
}
//获取内存使用率
//memx:所属内存块
//返回值:使用率(扩大了10倍,0~1000,代表0.0%~100.0%)
u16 my_mem_perused(u8 memx)
{
u32 used=0;
u32 i;
for(i=0;i<memtblsize[memx];i++)
{
if(mallco_dev.memmap[memx][i])used++;
}
return (used*1000)/(memtblsize[memx]);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
u32 my_mem_malloc(u8 memx,u32 size)
{
signed long offset=0;
u32 nmemb; //需要的内存块数
u32 cmemb=0;//连续空内存块数
u32 i;
if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先执行初始化
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/memblksize[memx]; //获取需要分配的连续内存块数
if(size%memblksize[memx])nmemb++;
for(offset=memtblsize[memx]-1;offset>=0;offset--)//搜索整个内存控制区
{
if(!mallco_dev.memmap[memx][offset])cmemb++;//连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
mallco_dev.memmap[memx][offset+i]=nmemb;
}
return (offset*memblksize[memx]);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
u8 my_mem_free(u8 memx,u32 offset)
{
int i;
if(!mallco_dev.memrdy[memx])//未初始化,先执行初始化
{
mallco_dev.init(memx);
return 1;//未初始化
}
if(offset<memsize[memx])//偏移在内存池内.
{
int index=offset/memblksize[memx]; //偏移所在内存块号码
int nmemb=mallco_dev.memmap[memx][index]; //内存块数量
for(i=0;i<nmemb;i++) //内存块清零
{
mallco_dev.memmap[memx][index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
//释放内存(外部调用)
//memx:所属内存块
//ptr:内存首地址
void myfree(u8 memx,void *ptr)
{
u32 offset;
if(ptr==NULL)return;//地址为0.
offset=(u32)ptr-(u32)mallco_dev.membase[memx];
my_mem_free(memx,offset); //释放内存
}
//分配内存(外部调用)
//memx:所属内存块
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u8 memx,u32 size)
{
u32 offset;
offset=my_mem_malloc(memx,size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)mallco_dev.membase[memx]+offset);
}
//重新分配内存(外部调用)
//memx:所属内存块
//*ptr:旧内存首地址
//size:要分配的内存大小(字节)
//返回值:新分配到的内存首地址.
void *myrealloc(u8 memx,void *ptr,u32 size)
{
u32 offset;
offset=my_mem_malloc(memx,size);
if(offset==0XFFFFFFFF)return NULL;
else
{
mymemcpy((void*)((u32)mallco_dev.membase[memx]+offset),ptr,size); //拷贝旧内存内容到新内存
myfree(memx,ptr); //释放旧内存
return (void*)((u32)mallco_dev.membase[memx]+offset); //返回新内存首地址
}
}
二 STM32CubeIDE 修改好的代码
2.1 malloc.h
#ifndef _MYMALLOC_H
#define _MYMALLOC_H
#include "stm32f7xx_hal.h"
//
//������ֻ��ѧϰʹ�ã�δ��������ɣ��������������κ���;
//ALIENTEK STM32F7������
//�ڴ���� ��������
//����ԭ��@ALIENTEK
//������̳:www.openedv.com
//��������:2015/12/12
//�汾��V1.0
//��Ȩ���У�����ؾ���
//Copyright(C) ������������ӿƼ�����˾ 2014-2024
//All rights reserved
//
#ifndef NULL
#define NULL 0
#endif
//���������ڴ��
#define SRAMIN 0 //�ڲ��ڴ��
#define SRAMEX 1 //�ⲿ�ڴ��(SDRAM)
#define SRAMDTCM 2 //DTCM�ڴ��(�˲���SRAM����CPU���Է���!!!)
#define SRAMBANK 3 //����֧�ֵ�SRAM����.
//mem1�ڴ�����趨.mem1��ȫ�����ڲ�SRAM����.
#define MEM1_BLOCK_SIZE 64 //�ڴ���СΪ64�ֽ�
#define MEM1_MAX_SIZE 160*1024 //�������ڴ� 160K
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //�ڴ���С
//mem2�ڴ�����趨.mem2���ڴ�ش����ⲿSDRAM����
#define MEM2_BLOCK_SIZE 1 //�ڴ���СΪ64�ֽ�
#define MEM2_MAX_SIZE 1*1024 //�������ڴ�28912K
#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //�ڴ���С
//mem3�ڴ�����趨.mem3����CCM,���ڹ���DTCM(�ر�ע��,�ⲿ��SRAM,��CPU���Է���!!)
#define MEM3_BLOCK_SIZE 64 //�ڴ���СΪ64�ֽ�
#define MEM3_MAX_SIZE 60 *1024 //�������ڴ�60K
#define MEM3_ALLOC_TABLE_SIZE MEM3_MAX_SIZE/MEM3_BLOCK_SIZE //�ڴ���С
//�ڴ���������
struct _m_mallco_dev
{
void (*init)(u8); //��ʼ��
u16 (*perused)(u8); //�ڴ�ʹ����
u8 *membase[SRAMBANK]; //�ڴ�� ����SRAMBANK��������ڴ�
u32 *memmap[SRAMBANK]; //�ڴ����״̬��
u8 memrdy[SRAMBANK]; //�ڴ�����Ƿ����
};
extern struct _m_mallco_dev mallco_dev; //��mallco.c���涨��
void mymemset(void *s,u8 c,u32 count); //�����ڴ�
void my_mem_init(u8 memx); //�ڴ�����ʼ������(��/�ڲ�����)
u32 my_mem_malloc(u8 memx,u32 size); //�ڴ����(�ڲ�����)
u8 my_mem_free(u8 memx,u32 offset); //�ڴ��ͷ�(�ڲ�����)
u16 my_mem_perused(u8 memx) ; //����ڴ�ʹ����(��/�ڲ�����)
//�û����ú���
void myfree(u8 memx,void *ptr); //�ڴ��ͷ�(�ⲿ����)
void *mymalloc(u8 memx,u32 size); //�ڴ����(�ⲿ����)
void *myrealloc(u8 memx,void *ptr,u32 size);//���·����ڴ�(�ⲿ����)
#endif
2.2 malloc.C
#include "malloc.h"
//
//������ֻ��ѧϰʹ�ã�δ��������ɣ��������������κ���;
//ALIENTEK STM32F7������
//�ڴ���� ��������
//����ԭ��@ALIENTEK
//������̳:www.openedv.com
//��������:2015/12/12
//�汾��V1.0
//��Ȩ���У�����ؾ���
//Copyright(C) ������������ӿƼ�����˾ 2014-2024
//All rights reserved
//
//�ڴ��(32�ֽڶ���)
__attribute__ ((aligned (32))) u8 mem1base[MEM1_MAX_SIZE];
__attribute__ ((aligned (32))) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0XC01F4000))); //�ⲿSDRAM�ڴ��,ǰ��2M��LTDC����(1280*800*2)
__attribute__ ((aligned (32))) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0X20000000)));
//�ڴ�����
__attribute__ ((aligned (32))) u32 mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //�ڲ�SRAM�ڴ��MAP
//u32 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((section (0XC01F4000+MEM2_MAX_SIZE))); //�ⲿSRAM�ڴ��MAP
//u32 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((section (0X20000000+MEM3_MAX_SIZE))); //�ڲ�DTCM�ڴ��MAP
__attribute__ ((aligned (32))) u32 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__ ((at(0XC01F4000+MEM2_MAX_SIZE))); //�ⲿSRAM�ڴ��MAP
__attribute__ ((aligned (32))) u32 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__ ((at(0X20000000+MEM3_MAX_SIZE)));
//�ڴ�������
const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE}; //�ڴ���С
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE}; //�ڴ�ֿ��С
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE}; //�ڴ��ܴ�С
//�ڴ���������
struct _m_mallco_dev mallco_dev=
{
my_mem_init, //�ڴ��ʼ��
my_mem_perused, //�ڴ�ʹ����
mem1base,mem2base,mem3base, //�ڴ��
mem1mapbase,mem2mapbase,mem3mapbase,//�ڴ����״̬��
0,0,0, //�ڴ����δ����
};
//�����ڴ�
//*des:Ŀ�ĵ�ַ
//*src:Դ��ַ
//n:��Ҫ���Ƶ��ڴ泤��(�ֽ�Ϊ��λ)
void mymemcpy(void *des,void *src,u32 n)
{
u8 *xdes=des;
u8 *xsrc=src;
while(n--)*xdes++=*xsrc++;
}
//�����ڴ�
//*s:�ڴ���ַ
//c :Ҫ���õ�ֵ
//count:��Ҫ���õ��ڴ��С(�ֽ�Ϊ��λ)
void mymemset(void *s,u8 c,u32 count)
{
u8 *xs = s;
while(count--)*xs++=c;
}
//�ڴ�����ʼ��
//memx:�����ڴ��
void my_mem_init(u8 memx)
{
mymemset(mallco_dev.memmap[memx],0,memtblsize[memx]*4); //�ڴ�״̬����������
mallco_dev.memrdy[memx]=1; //�ڴ�����ʼ��OK
}
//��ȡ�ڴ�ʹ����
//memx:�����ڴ��
//����ֵ:ʹ����(������10��,0~1000,����0.0%~100.0%)
u16 my_mem_perused(u8 memx)
{
u32 used=0;
u32 i;
for(i=0;i<memtblsize[memx];i++)
{
if(mallco_dev.memmap[memx][i])used++;
}
return (used*1000)/(memtblsize[memx]);
}
//�ڴ����(�ڲ�����)
//memx:�����ڴ��
//size:Ҫ������ڴ��С(�ֽ�)
//����ֵ:0XFFFFFFFF,�������;����,�ڴ�ƫ�Ƶ�ַ
u32 my_mem_malloc(u8 memx,u32 size)
{
signed long offset=0;
u32 nmemb; //��Ҫ���ڴ����
u32 cmemb=0;//�������ڴ����
u32 i;
if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//δ��ʼ��,��ִ�г�ʼ��
if(size==0)return 0XFFFFFFFF;//����Ҫ����
nmemb=size/memblksize[memx]; //��ȡ��Ҫ����������ڴ����
if(size%memblksize[memx])nmemb++;
for(offset=memtblsize[memx]-1;offset>=0;offset--)//���������ڴ������
{
if(!mallco_dev.memmap[memx][offset])cmemb++;//�������ڴ��������
else cmemb=0; //�����ڴ������
if(cmemb==nmemb) //�ҵ�������nmemb�����ڴ��
{
for(i=0;i<nmemb;i++) //��ע�ڴ��ǿ�
{
mallco_dev.memmap[memx][offset+i]=nmemb;
}
return (offset*memblksize[memx]);//����ƫ�Ƶ�ַ
}
}
return 0XFFFFFFFF;//δ�ҵ����Ϸ����������ڴ��
}
//�ͷ��ڴ�(�ڲ�����)
//memx:�����ڴ��
//offset:�ڴ��ַƫ��
//����ֵ:0,�ͷųɹ�;1,�ͷ�ʧ��;
u8 my_mem_free(u8 memx,u32 offset)
{
int i;
if(!mallco_dev.memrdy[memx])//δ��ʼ��,��ִ�г�ʼ��
{
mallco_dev.init(memx);
return 1;//δ��ʼ��
}
if(offset<memsize[memx])//ƫ�����ڴ����.
{
int index=offset/memblksize[memx]; //ƫ�������ڴ�����
int nmemb=mallco_dev.memmap[memx][index]; //�ڴ������
for(i=0;i<nmemb;i++) //�ڴ������
{
mallco_dev.memmap[memx][index+i]=0;
}
return 0;
}else return 2;//ƫ�Ƴ�����.
}
//�ͷ��ڴ�(�ⲿ����)
//memx:�����ڴ��
//ptr:�ڴ���ַ
void myfree(u8 memx,void *ptr)
{
u32 offset;
if(ptr==NULL)return;//��ַΪ0.
offset=(u32)ptr-(u32)mallco_dev.membase[memx];
my_mem_free(memx,offset); //�ͷ��ڴ�
}
//�����ڴ�(�ⲿ����)
//memx:�����ڴ��
//size:�ڴ��С(�ֽ�)
//����ֵ:���䵽���ڴ���ַ.
void *mymalloc(u8 memx,u32 size)
{
u32 offset;
offset=my_mem_malloc(memx,size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)mallco_dev.membase[memx]+offset);
}
//���·����ڴ�(�ⲿ����)
//memx:�����ڴ��
//*ptr:���ڴ���ַ
//size:Ҫ������ڴ��С(�ֽ�)
//����ֵ:�·��䵽���ڴ���ַ.
void *myrealloc(u8 memx,void *ptr,u32 size)
{
u32 offset;
offset=my_mem_malloc(memx,size);
if(offset==0XFFFFFFFF)return NULL;
else
{
mymemcpy((void*)((u32)mallco_dev.membase[memx]+offset),ptr,size); //�������ڴ����ݵ����ڴ�
myfree(memx,ptr); //�ͷž��ڴ�
return (void*)((u32)mallco_dev.membase[memx]+offset); //�������ڴ���ַ
}
}