内存管理模块

/*
 * Wos_Malloc.c
 *
 *  Created on: 2023/12/5
 *      Author: WZX
 */
 
 
#include "Wos_Malloc.h"


//内存池(32字节对齐)
__align(32) uint8_t mem1base[WOS_MEM1_MAX_SIZE];													//内部SRAM内存池
__align(32) uint8_t mem2base[WOS_MEM2_MAX_SIZE] __attribute__((at(0xD0000000)));					//外部SRAM内存池

//内存管理表
uint16_t mem1mapbase[WOS_MEM1_ALLOC_TABLE_SIZE];													//内部SRAM内存池MAP
uint16_t mem2mapbase[WOS_MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0xD0000000+WOS_MEM2_MAX_SIZE)));	//外部SRAM内存池MAP

//内存管理参数	   
const uint32_t memtblsize[WOS_SRAMBANK]={WOS_MEM1_ALLOC_TABLE_SIZE, WOS_MEM2_ALLOC_TABLE_SIZE};		//内存表大小
const uint32_t memblksize[WOS_SRAMBANK]={WOS_MEM1_BLOCK_SIZE, WOS_MEM2_BLOCK_SIZE};					//内存分块大小
const uint32_t memsize[WOS_SRAMBANK]={WOS_MEM1_MAX_SIZE, WOS_MEM2_MAX_SIZE};						//内存总大小

//内存管理控制器
struct Wos_mallco_dev Wos_mallco = 
{
	Wos_Meminit,
	Wos_Memperused,
	mem1base, mem2base,
	mem1mapbase, mem2mapbase,
	0, 0,
};


/*********************************************************************
 * @fn      Wos_Memcpy
 *
 * @brief   内存复制.
 *
 * @param   des:目标地址
 *
 * @param	src:源地址
 *
 * @param	size:复制长度
 *
 * @return  none
 */
void Wos_Memcpy(void *des, void *src, uint32_t size)  
{  
	uint8_t *xdes = des;
	uint8_t *xsrc = src; 
	
	while(size--)
	{
		*xdes++ = *xsrc++;  
	}
} 


/*********************************************************************
 * @fn      Wos_Memset
 *
 * @brief   内存设置.
 *
 * @param   source:内存首地址
 *
 * @param	val:设置的值
 *
 * @param	size:设置长度
 *
 * @return  none
 */
void Wos_Memset(void *source, uint8_t val, uint32_t size)  
{  
	uint8_t *xs = source; 
	
	while(size--)
	{
		*xs++ = val;  
	}
} 


/*********************************************************************
 * @fn      Wos_Meminit
 *
 * @brief   内存初始化.
 *
 * @param   index:初始化内存
 *
 * @return  none
 */
void Wos_Meminit(uint8_t index)  
{  
	Wos_Memset(Wos_mallco.Memmap[index], 0, memtblsize[index]*2);	//内存状态表数据清零  
	Wos_Memset(Wos_mallco.Membase[index], 0, memsize[index]);		//内存池所有数据清零  
	Wos_mallco.Memrdy[index] = 1;									//内存管理初始化OK  
} 


/*********************************************************************
 * @fn      Wos_Meminit
 *
 * @brief   内存初始化.
 *
 * @param   index:初始化内存
 *
 * @return  内存使用率
 */
uint8_t Wos_Memperused(uint8_t index)
{
	uint32_t used = 0;  
	
	for(uint32_t i = 0; i < memtblsize[index]; i++)  
	{  
		if(Wos_mallco.Memmap[index][i])
		{
			used++; 
		}
	} 
	
	return (used*100)/(memtblsize[index]); 
}


/*********************************************************************
 * @fn      Wos_Mem_Malloc
 *
 * @brief   内存分配.
 *
 * @param   index:初始化内存
 *
 * @param	size:需要内存大小
 *
 * @return  内存偏移地址,0XFFFFFFFF代表出错
 */
uint32_t Wos_Mem_Malloc(uint8_t index, uint32_t size)
{
	signed long offset = 0;  
	uint32_t nmemb;				//需要的内存块数  
	uint32_t cmemb = 0;			//连续空内存块数
	uint32_t i;  
	
	
	if(!Wos_mallco.Memrdy[index])	//未初始化,先执行初始化 
	{
		Wos_mallco.Init(index);
	}
	
	if(size == 0)
	{
		return 0XFFFFFFFF;
	}
	
	nmemb = size/memblksize[index];  	//获取需要分配的连续内存块数
	if(size % memblksize[index])
	{
		nmemb++; 
	}
	
	for(offset = memtblsize[index]-1; offset >= 0; offset--)	//搜索整个内存控制区  
	{     
		if(!Wos_mallco.Memmap[index][offset])	//连续空内存块数增加
		{
			cmemb++;
		}
		else	//连续内存块清零
		{
			cmemb = 0;
		}			
		
		if(cmemb == nmemb)	//找到了连续nmemb个空内存块
		{
			for(i = 0; i < nmemb; i++)	//标注内存块非空 
			{  
				Wos_mallco.Memmap[index][offset+i] = nmemb;  
			}  
			return (offset*memblksize[index]);//返回偏移地址  
		}
	}  
	return 0XFFFFFFFF;//未找到符合分配条件的内存块
}


/*********************************************************************
 * @fn      Wos_Mem_Free
 *
 * @brief   内存释放.
 *
 * @param   index:初始化内存
 *
 * @param	offset:释放内存偏移地址
 *
 * @return  0--正确,1--未初始化,2--偏移地址超出范围
 */
uint8_t Wos_Mem_Free(uint8_t index, uint32_t offset)
{
	int i;  
	
	if(!Wos_mallco.Memrdy[index])//未初始化,先执行初始化
	{
		Wos_mallco.Init(index);    
		return 1;		//未初始化  
	}  
	
	if(offset < memsize[index])//偏移在内存池内. 
	{  
		int memx = offset/memblksize[index];		//偏移所在内存块号码  
		int nmemb = Wos_mallco.Memmap[index][memx];//内存块数量
		for(i = 0; i < nmemb; i++)  				//内存块清零
		{  
			Wos_mallco.Memmap[index][memx+i]=0;  
		}  
		return 0;  
	}
	else 
	{
		return 2;//偏移超区了.  
	}
}


/*********************************************************************
 * @fn      Wos_malloc
 *
 * @brief   内存分配.
 *
 * @param   index:初始化内存
 *
 * @param	size:释放内存偏移地址
 *
 * @return  内存分配首地址
 */
void *Wos_malloc(uint8_t index, uint32_t size)
{
	uint32_t offset;
	
	offset = Wos_Mem_Malloc(index, size); 
	if(offset == 0XFFFFFFFF)
	{
		return NULL;
	}
	else
	{
		return (void *)((uint32_t)Wos_mallco.Membase[index] + offset);
	}
}


/*********************************************************************
 * @fn      Wos_free
 *
 * @brief   内存释放.
 *
 * @param   index:初始化内存
 *
 * @param	ptr:释放内存首地址
 *
 * @return  none
 */
void Wos_free(uint8_t index, void *ptr)
{
	uint32_t offset;   
	
	if(ptr == NULL)
		return;//地址为0.  
	
	offset = (uint32_t)ptr-(uint32_t)Wos_mallco.Membase[index];     
	Wos_Mem_Free(index, offset);	//释放内存 
}


/*********************************************************************
 * @fn      Wos_realloc
 *
 * @brief   内存重新分配.
 *
 * @param   index:初始化内存
 *
 * @param	ptr:释放内存首地址
 *
 * @param	size:数据大小
 *
 * @return  内存分配首地址
 */
void *Wos_realloc(uint8_t index, void *ptr, uint32_t size)
{
	uint32_t offset;    
	
	offset = Wos_Mem_Malloc(index, size);   	
	if(offset == 0XFFFFFFFF)
		return NULL;     
	else  
	{  									   
		Wos_Memcpy((void*)((uint32_t)Wos_mallco.Membase[index]+offset),ptr,size);	//拷贝旧内存内容到新内存   
		Wos_free(index, ptr);  											  			//释放旧内存
		return (void*)((uint32_t)Wos_mallco.Membase[index]+offset);  				//返回新内存首地址
	}  
}


/*
 * Wos_Malloc.h
 *
 *  Created on: 2023/12/5
 *      Author: WZX
 */
 
 
#ifndef _WOS_MALLOC_H_
#define _WOS_MALLOC_H_


#include <stdint.h>
#include <stddef.h>


#ifndef NULL
#define NULL 0
#endif


#define WOS_SRAMIN						0	//内部内存池
#define WOS_SRAMEX   					1	//外部内存池 
#define WOS_SRAMBANK 					2	//定义支持的SRAM块数.

//mem1内存参数设定.mem1完全处于内部SRAM里面.
#define WOS_MEM1_BLOCK_SIZE				32										//内存块大小为32字节
#define WOS_MEM1_MAX_SIZE			  	40*1024									//最大管理内存 40K
#define WOS_MEM1_ALLOC_TABLE_SIZE		WOS_MEM1_MAX_SIZE/WOS_MEM1_BLOCK_SIZE	//内存表大小


//mem2内存参数设定.mem2的内存池处于外部SRAM里面
#define WOS_MEM2_BLOCK_SIZE				32										//内存块大小为32字节
#define WOS_MEM2_MAX_SIZE			  	960 *1024								//最大管理内存960K
#define WOS_MEM2_ALLOC_TABLE_SIZE		WOS_MEM2_MAX_SIZE/WOS_MEM2_BLOCK_SIZE 	//内存表大小 


//内存管理控制器
typedef struct Wos_mallco_dev
{
	void (*Init)(uint8_t );				//初始化
	uint8_t (*Perused)(uint8_t );		//内存使用率
	uint8_t  *Membase[WOS_SRAMBANK];	//内存池 管理SRAMBANK个区域的内存
	uint16_t *Memmap[WOS_SRAMBANK];		//内存管理状态表
	uint8_t Memrdy[WOS_SRAMBANK];		//内存管理是否就绪
} Wos_mallco_dev_t;


void Wos_Meminit(uint8_t index);
uint8_t Wos_Memperused(uint8_t index);
uint32_t Wos_Mem_Malloc(uint8_t index, uint32_t size);
uint8_t Wos_Mem_Free(uint8_t index, uint32_t offset);


void Wos_Memcpy(void *des, void *src, uint32_t size);
void Wos_Memset(void *source, uint8_t val, uint32_t size);
void *Wos_malloc(uint8_t index, uint32_t size);
void Wos_free(uint8_t index, void *ptr);
void *Wos_realloc(uint8_t index, void *ptr, uint32_t size);


#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值