⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynmem.c

📁 本程序为ST公司开发的源代码
💻 C
字号:
/************************************************** * * dynmem.c * * CVS ID:   $Id: dynmem.c,v 1.12 2007/02/09 12:14:36 belardi Exp $ * Author:   Ondrej Trubac [OT] - STM * Date:     $Date: 2007/02/09 12:14:36 $ * Revision: $Revision: 1.12 $ *  * Description: *  *   Dynamic memory allocation. * *************************************************** *  * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * *************************************************** * * STM CVS Log: * * $Log: dynmem.c,v $ * Revision 1.12  2007/02/09 12:14:36  belardi * First integration of iPod pass-through * * Revision 1.11  2006/12/07 13:19:37  longauer * MUSB_DestroySystem() repaired - HUB everytime recognized *  after usb reinitialization; SFF redirected to SCSI; * * Revision 1.10  2006/12/04 16:30:38  longauer * CheckEnumeration can not be executed during BSR is pending. * * Revision 1.9  2006/10/17 10:07:44  trubac * new gendef.h include * * Revision 1.8  2006/09/18 09:55:26  belardi * Corrected CVS keyword usage * * Revision 1.7  2006/09/18 09:25:56  belardi * Added Log CVS keyword into file header * * ***************************************************///#define _DYN_DEBUG#include "debug.h"#include "gendef.h"#include "dynmem.h"#ifdef _DYN_DEBUG#include "string.h"#endif/* defined in usb.c *///extern uint8 bIsUsbInterrupt;/**************************** FORWARDS ****************************/void* DYN_do_malloc(uint16 size);GRESULT DYN_FindFreeCluster(uint8** st,uint16 sz);GRESULT DYN_ClusterSize(uint8 *stamp);GRESULT DYN_IsFreeCluster(uint8 *clust);GRESULT DYN_SkipCluster(uint8 **clust);void DYN_SetAlocated(uint8 *start, uint16 size);#if 0GRESULT DYN_ClusterOffset(uint8 *stamp);#endif/*************************** DEBUGGING ****************************/#ifdef _DYN_DEBUGtypedef struct {	uint32 start;	uint32 end;	uint32 size;	uint8 used;} t_dyn_malloc_array_debug;typedef struct{	t_dyn_malloc_array_debug dyn_malloc_array_debug[5];	uint32 buffer_size_max_debug;	uint32 buffer_size_actual_debug;	uint32 buffer_size_tmp_debug;} DYN_DEBUG;DYN_DEBUG DYN_debug;#endif /*_DYN_DEBUG*//**************************** GLOBALS *****************************/#pragma arm section zidata = "dyn_malloc_buffer"uint8 MYBUF[MY_HEAP_SIZE];#pragma arm section zidatatypedef struct dyn_result{	int result;	int operation;}t_dyn_result;t_dyn_result dyn_result;/*************************** FUNCTIONS ****************************/void* DYN_malloc(uint16 size){	uint8 *address;	size = 4*((size+3)>>2);	address = DYN_do_malloc(size);#ifdef _DYN_DEBUG	DBG_PRINTF("dynmem: loc - 0x%x(%d)\r\n", address, size);#endif /*_DYN_DEBUG*/#ifdef _DYN_DEBUG	if ((uint32)address>0)	{		DYN_debug.buffer_size_actual_debug += (size+4);		DYN_debug.buffer_size_tmp_debug = address-MYBUF+size;		if (DYN_debug.buffer_size_max_debug < DYN_debug.buffer_size_tmp_debug)			DYN_debug.buffer_size_max_debug = DYN_debug.buffer_size_tmp_debug;	}#endif /*_DYN_DEBUG*/	return address;}void* DYN_do_malloc(uint16 size){	uint8 *start;	GRESULT res;	if((size>(32*1024-4)) || (size==0))	{		dyn_result.result = E_PARAMETER_OUT_OF_RANGE;		dyn_result.operation = OP_DYN_MALLOC;		return NULL;	}      	start = MYBUF;	res = DYN_FindFreeCluster(&start,size);	if( res<0)	{		dyn_result.result = res;		dyn_result.operation = OP_FIND_FREE_CLUSTER;		return NULL;	}	DYN_SetAlocated(start,size);	return start+4;    }GRESULT DYN_FindFreeCluster(uint8** st,uint16 sz){	GRESULT len;	GRESULT res;        	if( *st > &MYBUF[MY_HEAP_SIZE-4])		return E_INSUFFICIENT_MEMORY;//if(0>(len=DYN_ClusterSize(*st))//    return len;     // INCONSISTENCY FOUND;	while(1)	{		len=DYN_ClusterSize(*st);		if(0>len)			return len;     // INCONSISTENCY FOUND;		if(len>=sz)		{			if(DYN_IsFreeCluster(*st))			{				//DYN_SetAllocated(*st,sz);				return S_OK;			}		}		if(0>(res=DYN_SkipCluster(st)))			return res;	}}GRESULT DYN_ClusterSize(uint8 *stamp){	uint16 offs,size;//	if(stamp==NULL)//		return E_WRONG_PARAMETER;       	offs = *(uint16*)stamp;	offs &= 0x7FFF;    	if((stamp)!=&MYBUF[offs])        // offs should be index of stamp in MYBUF 		return E_WRONG_CLUSTER_STAMP;   	size = *(uint16*)(stamp+2);   	if((stamp+size+4)>(MYBUF+MY_HEAP_SIZE))		return E_WRONG_CLUSTER_STAMP;   	return size;}GRESULT DYN_IsFreeCluster(uint8 *clust){	uint16 offs;	offs = *(uint16*)clust;	return (offs&0x8000) ? S_FALSE:S_TRUE;}GRESULT DYN_SkipCluster(uint8 **clust){	uint16 size;	size = *(uint16*)(*clust+2);   	if((*clust+size+4)>=(MYBUF+MY_HEAP_SIZE))		return E_NO_FREE_MEMORY;   	*clust = (*clust+size+4);   	return S_OK;}void DYN_SetAlocated(uint8 *start, uint16 size){	uint16 old_size,old_offs;	old_offs = *(uint16*)start;	*(uint16*)start = old_offs|0x8000;	old_size = *(uint16*)(start+2);	*(uint16*)(start+2)=size;	if((4+size)<=old_size)	{		start+=(4+size);		*(uint16*)start=(start-MYBUF);		*(uint16*)(start+2) = old_size-size-4;	}    }void DYN_Init(void){	int i;	for(i=0;i<MY_HEAP_SIZE;i++)	MYBUF[i]=0;#ifdef _DYN_DEBUG	memset(&DYN_debug, 0, sizeof(DYN_debug));	/* debug */#endif /*_DYN_DEBUG*/	*(uint16*)(MYBUF+2)=MY_HEAP_SIZE-4;}GRESULT DYN_free(void *mem){	GRESULT res,size;//,lastsz;	uint8 *ptr,*next,*prev=(uint8*)NULL;#ifdef _DYN_DEBUG	DBG_PRINTF("dynmem: FREE: loc - 0x%x\r\n", mem);#endif /*_DYN_DEBUG*/	if (mem==NULL)		return E_FREE_NULL;       	size=DYN_ClusterSize(((uint8*)mem)-4);	if(0>size)		return size;          // wrong stamp found   	ptr = MYBUF;	while(1)	{    		if((ptr+4)==mem)			break;       		if((ptr+4)>(uint8*)mem)			return E_FAIL;           		prev = ptr;       //		lastsz=res;		res=DYN_SkipCluster(&ptr);		if(0>res)			return E_MEMORY_ERROR;				res=DYN_ClusterSize(ptr);		if(0>res)			return res;          // wrong stamp found    	}             	next = ((uint8*)mem)-4;	res=DYN_SkipCluster(&next);	if(0>res)		next=(uint8*)NULL;   	if(prev!=NULL)	{		if(DYN_IsFreeCluster(prev))		{			*(uint16*)(prev+2) += (size + 4);			*(uint16*)(((uint8*)mem)-4) = 0;           		}      		else		{			prev=((uint8*)mem)-4;			*(uint16*)prev &= 0x7fff;		}	}	else	{		prev=MYBUF;    		*(uint16*)MYBUF = 0;	}      	do   	{		if(next==NULL)			break; //return S_OK;		res = DYN_ClusterSize(next);		if(0>res)			return E_MEMORY_ERROR;      		if(!DYN_IsFreeCluster(next))			break; //return S_OK;       		*(uint16*)(prev+2) += (res+4);		*(uint16*)next = 0;	} while(0);#ifdef _DYN_DEBUG	DYN_debug.buffer_size_actual_debug -= size+4;#endif /*_DYN_DEBUG*/	return S_OK;}#if 0GRESULT DYN_ClusterOffset(uint8 *stamp){	uint16 offs,size,offset;//	if(stamp==NULL)//		return E_WRONG_PARAMETER;       	offs = *(uint16*)stamp;	offset = offs;	offs &= 0x7FFF;    	if((stamp)!=&MYBUF[offs])        // offs should be index of stamp in MYBUF 		return E_WRONG_CLUSTER_STAMP;   	size = *(uint16*)(stamp+2);   	if((stamp+size+4)>(MYBUF+MY_HEAP_SIZE))		return E_WRONG_CLUSTER_STAMP;   	return offset;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -