📄 dynmem.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 + -