Choco OS  V.0.16.9.0
Join to the chocolate world
oc_memman.c
Go to the documentation of this file.
1 
27 #include <oc_memman.h>
28 #include <oc_intman.h>
29 #include <oc_mem_lld.h>
30 #include <oc_sys_lld.h>
31 #include <oc_bits.h>
32 #include <oc_memory_cfg.h>
33 #include <oc_threadman.h>
34 #include <oc_array.h>
35 #include <oc_null.h>
36 #include <oc_ktime.h>
37 #include <oc_ifnot.h>
38 #include <oc_debug.h>
39 #include <string.h>
40 
46 #define _________________________________________LOCAL_DEFINITIONS_SECTION_________________________________________________________________
47 
48 //==========================================================================================================================================
53 //==========================================================================================================================================
54 #define OVERFLOW_PROTECTION_MAGIC_NUMBER ((oC_UInt_t)0xfeedface)
55 
56 //==========================================================================================================================================
75 //==========================================================================================================================================
76 #define foreach_block(block) for(Block_t * block = BlockListHead; (block != NULL); block = block->Next)
77 
78 //==========================================================================================================================================
94 //==========================================================================================================================================
95 #define LAST_WORD_OF_BUFFER(Buffer,Size) ((oC_UInt_t*)Buffer)[ALIGN_SIZE(Size,oC_MEM_LLD_MEMORY_ALIGNMENT)/sizeof(oC_UInt_t)]
96 
97 //==========================================================================================================================================
101 //==========================================================================================================================================
102 #define ALIGN_SIZE(SIZE,ALIGNMENT) ((((oC_UInt_t)SIZE) + ALIGNMENT - 1) & ~(ALIGNMENT-1))
103 
104 #undef _________________________________________LOCAL_DEFINITIONS_SECTION_________________________________________________________________
105 
111 #define _________________________________________LOCAL_TYPES_SECTION________________________________________________________________________
112 
113 //==========================================================================================================================================
117 //==========================================================================================================================================
118 typedef struct _Block_t
119 {
120  struct _Block_t * Next;
122  void * Address;
123  oC_UInt_t Size;
124  const char * Function;
125  uint32_t LineNumber;
126  AllocationFlags_t AllocationFlags;
127 } Block_t;
128 
129 //==========================================================================================================================================
133 //==========================================================================================================================================
134 typedef enum
135 {
138 } HeapState_t;
139 
140 //==========================================================================================================================================
154 //==========================================================================================================================================
155 typedef struct _HeapMap_t
156 {
157  struct _HeapMap_t * Self;
158  uint8_t * BitMapStart;
159  uint8_t * BitMapEnd;
160  oC_UInt_t * HeapStart;
161  oC_UInt_t * HeapEnd;
162 } HeapMap_t;
163 
164 #undef _________________________________________LOCAL_TYPES_SECTION________________________________________________________________________
165 
171 #define _________________________________________LOCAL_FUNCTIONS_PROTOTYPES_SECTION_________________________________________________________
172 
173 static bool BlockModule ( AllocationFlags_t Flags );
174 static bool UnblockModule ( void );
175 static bool WaitForMemory ( HeapMap_t * Map , oC_UInt_t Size , oC_UInt_t Alignment , AllocationFlags_t Flags );
176 static oC_ErrorCode_t InitializePointers ( bool FillZero );
177 static oC_ErrorCode_t InitializeHeapMap ( HeapMap_t * Map , void * HeapStartPointer , void * HeapEndPointer , oC_UInt_t HeapSize , bool FillZero );
178 static Block_t * FindBlockOfAddress ( const void * Address );
179 static Block_t * FindBlockContainsAddress ( const void * Address );
180 static oC_UInt_t GetIndexOfHeapPointer ( HeapMap_t * Map , oC_UInt_t * HeapPointer );
181 static inline bool IsAddressOfHeapMap ( HeapMap_t * Map , const void * Address );
182 static inline bool IsBlockCorrect ( Block_t * Block );
183 static inline bool IsHeapUsed ( HeapMap_t * Map , oC_UInt_t * HeapPointer );
184 static void DumpHeapMap ( HeapMap_t * Map , oC_MemMan_DumpFunction_t DumpFunction);
185 static inline bool IsHeapMapInitialized ( HeapMap_t * Map );
186 static inline void SetHeapState ( HeapMap_t * Map , oC_UInt_t * HeapPointer , HeapState_t HeapState );
187 static bool CheckIfHeapInRangeIsInState ( HeapMap_t * Map , oC_UInt_t * HeapFrom , oC_UInt_t * HeapTo , HeapState_t HeapState );
188 static inline void SetHeapStateInRange ( HeapMap_t * Map , oC_UInt_t * HeapFrom , oC_UInt_t * HeapTo , HeapState_t HeapState );
189 static oC_UInt_t * FindNextHeapPointerInState ( HeapMap_t * Map , oC_UInt_t * HeapPointer , oC_UInt_t * HeapEndLimit , HeapState_t HeapState );
190 static oC_UInt_t GetSizeOfHeapInState ( HeapMap_t * Map , HeapState_t HeapState );
191 static oC_UInt_t GetSizeOfHeap ( HeapMap_t * Map );
192 static void * FindFreeHeap ( HeapMap_t * Map , oC_UInt_t Size , oC_UInt_t Alignment );
193 static void * RawAlloc ( HeapMap_t * Map , oC_UInt_t Size , oC_UInt_t Alignment );
194 static bool RawFree ( HeapMap_t * Map , void * Address , oC_UInt_t Size);
195 static bool IsMemoryValid ( void * Start , oC_UInt_t Size );
196 static void CallAllocatorEvent ( Allocator_t Allocator , void * Address , MemoryEventFlags_t EventFlags , const char * Function, uint32_t LineNumber );
197 static void CallEvent ( void * Address , MemoryEventFlags_t EventFlags , const char * Function, uint32_t LineNumber );
198 static void MemoryFaultInterrupt ( void );
199 static void BusFaultInterrupt ( void );
200 static bool CanReleaseMemory ( Block_t * Block );
201 
202 #undef _________________________________________LOCAL_FUNCTIONS_PROTOTYPES_SECTION_________________________________________________________
203 
208 #define _________________________________________LOCAL_VARIABLES_SECTION____________________________________________________________________
209 
210 static bool ModuleTestModeEnabledFlag = false;
211 static bool ModuleEnabledFlag = false;
212 static uint32_t ModuleBusyFlag = false;
213 static bool FirstPowerOn = false;
214 static uint32_t * DataOverflowProtection = NULL;
217 static MemoryEventHandler_t ModuleEventHandler = NULL;
221 static float PanicMemoryExhaustedLimit = CFG_PERCENT_PANIC_MEMORY_EXHAUSTED_LIMIT;
222 static float DefaultMemoryExhaustedLimit = CFG_PERCENT_DEFAULT_MEMORY_EXHAUSTED_LIMIT;
223 
224 #undef _________________________________________LOCAL_VARIABLES_SECTION____________________________________________________________________
225 
231 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
232 
235 //==========================================================================================================================================
250 //==========================================================================================================================================
251 oC_ErrorCode_t oC_MemMan_TurnOn( void )
252 {
253  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
254 
255  if(!ModuleEnabledFlag)
256  {
258  {
259  errorCode = oC_MEM_LLD_TurnOnDriver();
260 
261  if(errorCode == oC_ErrorCode_None || errorCode == oC_ErrorCode_ModuleIsTurnedOn)
262  {
263  if(
264  oC_AssignErrorCode(&errorCode , InitializePointers(!FirstPowerOn)) &&
265  oC_AssignErrorCode(&errorCode , oC_MEM_LLD_SetBusFaultInterrupt(BusFaultInterrupt)) &&
266  oC_AssignErrorCode(&errorCode , oC_MEM_LLD_TurnOnBusFaultInterrupt()) &&
267  oC_AssignErrorCode(&errorCode , oC_MEM_LLD_SetMemoryFaultInterrupt(MemoryFaultInterrupt)) &&
268  oC_AssignErrorCode(&errorCode , oC_MEM_LLD_TurnOnMemoryFaultInterrupt())
269  )
270  {
271  ModuleBusyFlag = false;
272  ModuleEnabledFlag = true;
274  FirstPowerOn = false;
275 
276  errorCode = oC_ErrorCode_None;
277  }
278  }
279  }
280  else
281  {
282  errorCode = oC_ErrorCode_ModuleIsTestedAlready;
283  }
284  }
285  else
286  {
287  errorCode = oC_ErrorCode_ModuleIsTurnedOn;
288  }
289 
290  return errorCode;
291 }
292 
293 //==========================================================================================================================================
312 //==========================================================================================================================================
313 oC_ErrorCode_t oC_MemMan_TurnOff( void )
314 {
315  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
316 
318  {
320  {
321  ModuleEnabledFlag = false;
322 
323  foreach_block(block)
324  {
325  CallAllocatorEvent(block->Allocator, block->Address, MemoryEventFlags_MemoryReleased, block->Function, block->LineNumber);
326  }
327 
328  CallEvent(NULL,MemoryEventFlags_ModuleTurningOff,"",0);
329 
331  errorCode = oC_MEM_LLD_TurnOffDriver();
332  }
333  else
334  {
335  errorCode = oC_ErrorCode_ModuleIsTestedAlready;
336  }
337  }
338  else
339  {
340  errorCode = oC_ErrorCode_ModuleNotStartedYet;
341  }
342 
343  return errorCode;
344 }
345 
346 //==========================================================================================================================================
354 //==========================================================================================================================================
356 {
358  {
360  {
361  CallEvent(NULL,MemoryEventFlags_DataSectionOverflow,"",0);
362  }
363 
364  foreach_block(block)
365  {
366  if(LAST_WORD_OF_BUFFER(block->Address,block->Size) != OVERFLOW_PROTECTION_MAGIC_NUMBER)
367  {
368  LAST_WORD_OF_BUFFER(block->Address,block->Size) = OVERFLOW_PROTECTION_MAGIC_NUMBER;
369  CallAllocatorEvent(block->Allocator,block->Address,MemoryEventFlags_BufferOverflow,block->Function,block->LineNumber);
370  CallEvent(block->Address,MemoryEventFlags_BufferOverflow,block->Function,block->LineNumber);
371  }
372  }
373  }
374 }
375 
376 //==========================================================================================================================================
384 //==========================================================================================================================================
386 {
388  {
389  float freeSize = (float)GetSizeOfHeapInState(&HeapMap,HeapState_NotUsed);
390  float size = (float)GetSizeOfHeap(&HeapMap);
391 
392  if((freeSize/size) < PanicMemoryExhaustedLimit)
393  {
394  CallEvent(NULL,MemoryEventFlags_PanicMemoryExhausted,"",0);
395  }
396  else if((freeSize/size) < DefaultMemoryExhaustedLimit)
397  {
398  CallEvent(NULL,MemoryEventFlags_MemoryExhausted,"",0);
399  }
401  {
402  float externalFreeSize = (float)GetSizeOfHeapInState(&ExternalHeapMap,HeapState_NotUsed);
403  float externalSize = (float)GetSizeOfHeap(&ExternalHeapMap);
404 
405  if((externalFreeSize/externalSize) < PanicMemoryExhaustedLimit)
406  {
407  CallEvent(NULL,MemoryEventFlags_PanicExternalMemoryExhausted,"",0);
408  }
409  else if((externalFreeSize/externalSize) < DefaultMemoryExhaustedLimit)
410  {
411  CallEvent(NULL,MemoryEventFlags_ExternalMemoryExhausted,"",0);
412  }
413  }
414  }
415 }
416 
417 //==========================================================================================================================================
424 //==========================================================================================================================================
426 {
428  {
429 
430  }
431 }
432 
433 //==========================================================================================================================================
448 //==========================================================================================================================================
450 {
451  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
452 
454  {
455  BlockModule(AllocationFlags_ForceBlock);
456  MemoryEventHandler_t EventHandlerBackup = ModuleEventHandler;
457  Block_t * BlockHeadBackup = BlockListHead;
459  errorCode = InitializePointers(false);
460 
461  if(errorCode == oC_ErrorCode_None)
462  {
463  ModuleEventHandler = EventHandlerBackup;
464 
465  for(Block_t * block=BlockHeadBackup;IsAddressOfHeapMap(&HeapMap,block);block = block->Next)
466  {
467  if(IsBlockCorrect(block))
468  {
469  if(BlockListTail)
470  {
471  BlockListTail->Next = block;
472  }
473  if(BlockListHead == NULL)
474  {
475  BlockListHead = block;
476  }
477  BlockListTail = block;
478  }
479  else
480  {
481  errorCode = oC_ErrorCode_SomeDataLost;
482  CallAllocatorEvent(block->Allocator, block->Address, MemoryEventFlags_MemoryFault,block->Function, block->LineNumber);
483  CallAllocatorEvent(block->Allocator, block->Address, MemoryEventFlags_MemoryReleased, block->Function, block->LineNumber);
484  }
485  }
486 
487 
488  if( errorCode == oC_ErrorCode_ModuleNeedRestart || errorCode == oC_ErrorCode_SomeDataLost )
489  {
490  DumpHeapMap(&HeapMap,DumpFunction);
491  }
492 
493  if ( errorCode == oC_ErrorCode_None || errorCode == oC_ErrorCode_SomeDataLost)
494  {
495  for(uint8_t * bitMapPointer = HeapMap.BitMapStart;bitMapPointer<HeapMap.BitMapEnd;bitMapPointer++)
496  {
497  *bitMapPointer = 0;
498  }
499 
500  foreach_block(block)
501  {
502  SetHeapStateInRange(&HeapMap,(oC_UInt_t*)block,(oC_UInt_t*)block+sizeof(Block_t),HeapState_Used);
503  SetHeapStateInRange(&HeapMap,block->Address,block->Address+block->Size+sizeof(uint32_t),HeapState_Used);
504  }
505  }
506  }
507  else
508  {
509  DumpHeapMap(&HeapMap,DumpFunction);
510  }
511 
513  UnblockModule();
514  }
515  else
516  {
517  errorCode = oC_ErrorCode_ModuleNotStartedYet;
518  }
519 
520  return errorCode;
521 }
522 
523 //==========================================================================================================================================
542 //==========================================================================================================================================
543 oC_HeapMap_t oC_MemMan_AllocateHeapMap( oC_UInt_t Size , Allocator_t Allocator , const char * Function, uint32_t LineNumber , AllocationFlags_t Flags )
544 {
545  oC_HeapMap_t heapMap = NULL;
546 
547  if(ModuleEnabledFlag && !ModuleTestModeEnabledFlag && (Size > 0) && oC_MemMan_IsAllocatorCorrect(Allocator) && (LineNumber > 0))
548  {
549  void * heapBuffer = oC_MemMan_Allocate(Size , Allocator , Function, LineNumber , Flags , oC_MEM_LLD_MEMORY_ALIGNMENT );
550 
551  if(heapBuffer != NULL)
552  {
553  heapMap = oC_MemMan_Allocate(sizeof(HeapMap_t) , Allocator , Function, LineNumber , Flags , oC_MEM_LLD_MEMORY_ALIGNMENT );
554  void * heapBufferEnd = heapBuffer + Size;
555 
556  if(heapMap != NULL)
557  {
558  if(oC_ErrorOccur( InitializeHeapMap(heapMap , heapBuffer , heapBufferEnd , Size , true) ))
559  {
560  oC_MemMan_Free(heapBuffer,Flags);
561  oC_MemMan_Free(heapMap,Flags);
562 
563  heapMap = NULL;
564  }
565  }
566  else
567  {
568  oC_MemMan_Free(heapBuffer,Flags);
569  }
570  }
571  }
572 
573  return heapMap;
574 }
575 
576 //==========================================================================================================================================
595 //==========================================================================================================================================
596 bool oC_MemMan_FreeHeapMap( oC_HeapMap_t * MapPointer , AllocationFlags_t Flags)
597 {
598  bool allMemoryReleased = false;
599  HeapMap_t* heapMap = IsAddressOfHeapMap(&HeapMap,*MapPointer) ? &HeapMap : IsAddressOfHeapMap(&ExternalHeapMap,*MapPointer) ? &ExternalHeapMap : NULL;
600 
601  if(ModuleEnabledFlag && !ModuleTestModeEnabledFlag && heapMap != NULL && IsHeapMapInitialized(*MapPointer))
602  {
603  HeapMap_t * HeapMap = *MapPointer;
604  void * heapBuffer = HeapMap->BitMapStart;
605 
606  allMemoryReleased = true;
607 
608  if(!oC_MemMan_Free(heapBuffer,Flags))
609  {
610  allMemoryReleased = false;
611  }
612 
613  if(!oC_MemMan_Free(HeapMap,Flags))
614  {
615  allMemoryReleased = false;
616  }
617  *MapPointer = NULL;
618  }
619 
620  return allMemoryReleased;
621 }
622 
623 
624 //==========================================================================================================================================
642 //==========================================================================================================================================
643 void * oC_MemMan_RawAllocate( oC_HeapMap_t Map , oC_UInt_t Size , const char * Function, uint32_t LineNumber , AllocationFlags_t Flags )
644 {
645  void * Address = NULL;
647 
648  if(ModuleEnabledFlag && !ModuleTestModeEnabledFlag && (Size > 0) && heapMap != NULL && IsHeapMapInitialized(Map) && BlockModule(Flags))
649  {
650  Block_t * block = FindBlockOfAddress( Map );
651 
652  if(block)
653  {
654  Address = RawAlloc( Map , Size , oC_MEM_LLD_MEMORY_ALIGNMENT );
655 
656  if(Address)
657  {
658  block->AllocationFlags = Flags;
659 
660  CallAllocatorEvent( block->Allocator,Address , MemoryEventFlags_RawMemoryAllocated, Function, LineNumber );
661  }
662  else
663  {
664  CallAllocatorEvent( block->Allocator,Address , MemoryEventFlags_AllocationError , Function, LineNumber );
665  }
666 
667  }
668 
669  UnblockModule();
670  }
671 
672  return Address;
673 }
674 
675 //==========================================================================================================================================
691 //==========================================================================================================================================
692 bool oC_MemMan_RawFree( oC_HeapMap_t Map , void * Address , oC_UInt_t Size )
693 {
694  bool result = false;
696 
697  if(ModuleEnabledFlag && !ModuleTestModeEnabledFlag && (Size > 0) && heapMap != NULL && IsHeapMapInitialized(Map) && IsAddressOfHeapMap(Map,Address))
698  {
699  Block_t * block = FindBlockOfAddress(Map);
700 
701  if(block && CanReleaseMemory(block))
702  {
703  BlockModule(AllocationFlags_Default);
704  if(RawFree( Map , Address , Size))
705  {
706  result = true;
707  CallAllocatorEvent(block->Allocator,Address , MemoryEventFlags_RawMemoryReleased , block->Function, block->LineNumber);
708  }
709  else
710  {
711  CallAllocatorEvent(block->Allocator,Address , MemoryEventFlags_ReleaseError , block->Function, block->LineNumber);
712  }
713  UnblockModule();
714  }
715  }
716 
717  return result;
718 }
719 
720 //==========================================================================================================================================
769 //==========================================================================================================================================
770 void * oC_MemMan_Allocate( oC_UInt_t Size , Allocator_t Allocator , const char * Function, uint32_t LineNumber , AllocationFlags_t Flags , oC_UInt_t Alignment )
771 {
772  void * Address = NULL;
773 
774  if(Alignment == 0)
775  {
776  Alignment = oC_MEM_LLD_MEMORY_ALIGNMENT;
777  }
778 
779  if( ModuleEnabledFlag && !ModuleTestModeEnabledFlag && (Size > 0) && ((Alignment % oC_MEM_LLD_MEMORY_ALIGNMENT) == 0) && oC_MemMan_IsAllocatorCorrect(Allocator) && (LineNumber > 0))
780  {
781  HeapMap_t * heapMap = NULL;
782 
783  /* If none of flags is set, then use both RAM - internal and external */
784  ifnot(Flags & (AllocationFlags_UseExternalRam | AllocationFlags_UseInternalRam | AllocationFlags_UseDmaRam))
785  {
786  Flags |= AllocationFlags_UseExternalRam | AllocationFlags_UseInternalRam;
787  }
788 
789 
790  do
791  {
792  if(Allocator->Limit != 0 && Allocator->Limit < oC_MemMan_GetMemoryOfAllocatorSize(Allocator))
793  {
794  CallAllocatorEvent(Allocator, NULL, MemoryEventFlags_MemoryExhausted, Function, LineNumber);
795  kdebuglog(oC_LogType_Error, "MemMan::Allocate - Allocator named '%s' has exhausted the limit\n", Allocator->Name);
796  break;
797  }
798 
799  if(oC_Bits_AreBitsSetU32(Flags, AllocationFlags_UseDmaRam) && IsHeapMapInitialized(&DmaHeapMap))
800  {
801  if(WaitForMemory(&DmaHeapMap, Size + sizeof(oC_UInt_t) + sizeof(Block_t) , Alignment ,Flags))
802  {
803  heapMap = &DmaHeapMap;
804  break;
805  }
806  }
807 
808  if(oC_Bits_AreBitsSetU32(Flags , AllocationFlags_UseExternalRam | AllocationFlags_ExternalRamFirst) && IsHeapMapInitialized(&ExternalHeapMap))
809  {
810  if(WaitForMemory(&ExternalHeapMap, Size + sizeof(oC_UInt_t) + sizeof(Block_t) , Alignment ,Flags))
811  {
812  heapMap = &ExternalHeapMap;
813  break;
814  }
815  }
816 
817  if((Flags & AllocationFlags_UseInternalRam) && IsHeapMapInitialized(&HeapMap))
818  {
819  if(WaitForMemory(&HeapMap, Size + sizeof(oC_UInt_t) + sizeof(Block_t) , Alignment ,Flags))
820  {
821  heapMap = &HeapMap;
822  break;
823  }
824  }
825 
826  if((Flags & AllocationFlags_UseExternalRam) && IsHeapMapInitialized(&ExternalHeapMap))
827  {
828  if(WaitForMemory(&ExternalHeapMap, Size + sizeof(oC_UInt_t) + sizeof(Block_t) , Alignment ,Flags))
829  {
830  heapMap = &ExternalHeapMap;
831  break;
832  }
833  }
834  } while(0);
835 
836  if(heapMap != NULL && BlockModule(Flags))
837  {
838  Address = RawAlloc(heapMap , Size + sizeof(oC_UInt_t) , Alignment );
839 
840  if(IsAddressOfHeapMap(heapMap,Address))
841  {
842  Block_t * block = RawAlloc(heapMap , sizeof(Block_t) , oC_MEM_LLD_MEMORY_ALIGNMENT);
843 
844  if(IsAddressOfHeapMap(heapMap,block))
845  {
846  block->Address = Address;
847  block->Allocator = Allocator;
848  block->Function = Function;
849  block->LineNumber = LineNumber;
850  block->Next = NULL;
851  block->Size = Size;
852  block->AllocationFlags = Flags;
853 
854  if(Flags & AllocationFlags_ZeroFill)
855  {
856  for(oC_UInt_t BufferIndex = 0 ; BufferIndex < Size ; BufferIndex++ )
857  {
858  ((uint8_t*)Address)[BufferIndex] = 0;
859  }
860  }
861 
862  // write a magic number at the end of the buffer for protection agains overflow
864 
865  if(BlockListHead == NULL && BlockListTail == NULL)
866  {
867  BlockListHead = block;
868  BlockListTail = block;
869  }
870  else
871  {
872  BlockListTail->Next = block;
873  BlockListTail = block;
874  }
875  }
876  else
877  {
878  RawFree(heapMap,Address,Size);
879  }
880  }
881 
882  UnblockModule();
883  }
884  }
885 
886  return Address;
887 }
888 
889 //==========================================================================================================================================
907 //==========================================================================================================================================
908 bool oC_MemMan_Free( void * Address , AllocationFlags_t Flags)
909 {
910  bool memoryReleased = false;
912 
913  if(ModuleEnabledFlag && !ModuleTestModeEnabledFlag && heapMap != NULL && BlockModule(Flags))
914  {
915  Block_t * previousBlock = BlockListHead;
916 
917  foreach_block(block)
918  {
919  if(block->Address == Address && CanReleaseMemory(block))
920  {
921  CallAllocatorEvent(block->Allocator , Address , MemoryEventFlags_MemoryReleased , block->Function, block->LineNumber );
922 
923  if(block != BlockListHead)
924  {
925  // this is not the first block
926  previousBlock->Next = block->Next;
927 
928  if(block == BlockListTail)
929  {
930  // this is not the first block but the last
931  BlockListTail = previousBlock;
932  }
933  }
934  else
935  {
936  // this is the first block
937  BlockListHead = block->Next;
938 
939  if(block == BlockListTail)
940  {
941  // this is the first and the last block
943  }
944  }
945 
946  memoryReleased = true;
947 
948  if(!RawFree(heapMap , Address , block->Size + sizeof(oC_UInt_t)))
949  {
950  memoryReleased = false;
951  }
952 
953  if(!RawFree(heapMap , block , sizeof(Block_t)))
954  {
955  memoryReleased = false;
956  }
957 
958  if(memoryReleased == false)
959  {
960  CallAllocatorEvent(block->Allocator, Address, MemoryEventFlags_ReleaseError, block->Function, block->LineNumber);
961  }
962 
963  break;
964  }
965  previousBlock = block;
966  }
967  UnblockModule();
968  }
969 
970  return memoryReleased;
971 }
972 
973 //==========================================================================================================================================
984 //==========================================================================================================================================
986 {
987  bool result = false;
988 
990  {
991  bool found_block;
992 
993  result = true;
994 
995  do
996  {
997  found_block = false;
998 
999  foreach_block(block)
1000  {
1001  if(block->Allocator == Allocator)
1002  {
1003  found_block = true;
1004 
1005  if(!oC_MemMan_Free(block->Address,AllocationFlags_CanWaitForever))
1006  {
1007  result = false;
1008  }
1009  break;
1010  }
1011  }
1012  } while(found_block);
1013  }
1014 
1015  return result;
1016 }
1017 
1018 //==========================================================================================================================================
1034 //==========================================================================================================================================
1035 oC_ErrorCode_t oC_MemMan_SetEventHandler( MemoryEventHandler_t EventHandler )
1036 {
1037  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1038 
1039  if(
1040  oC_AssignErrorCodeIfFalse(&errorCode, ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet) &&
1041  oC_AssignErrorCodeIfFalse(&errorCode, !ModuleTestModeEnabledFlag , oC_ErrorCode_ModuleIsTestedAlready) &&
1042  oC_AssignErrorCodeIfFalse(&errorCode, oC_MemMan_IsAddressCorrect(EventHandler) , oC_ErrorCode_WrongAddress) &&
1043  oC_AssignErrorCodeIfFalse(&errorCode, ModuleEventHandler == NULL , oC_ErrorCode_InterruptHandlerAlreadySet)
1044  )
1045  {
1046  ModuleEventHandler = EventHandler;
1047  errorCode = oC_ErrorCode_None;
1048  }
1049 
1050  return errorCode;
1051 }
1052 
1053 //==========================================================================================================================================
1097 //==========================================================================================================================================
1099 {
1100  Allocator_t allocator = NULL;
1101 
1103  {
1104  Block_t * block = FindBlockOfAddress(Address);
1105 
1106  if(block == NULL)
1107  {
1108  block = FindBlockContainsAddress(Address);
1109  }
1110 
1111  if(block)
1112  {
1113  allocator = block->Allocator;
1114  }
1115  }
1116 
1117  return allocator;
1118 }
1119 
1120 //==========================================================================================================================================
1132 //==========================================================================================================================================
1133 oC_UInt_t oC_MemMan_GetSizeOfAllocation( const void * Address )
1134 {
1135  oC_UInt_t size = 0;
1136 
1138  {
1139  Block_t * block = FindBlockOfAddress(Address);
1140 
1141  if(block)
1142  {
1143  size = block->Size;
1144  }
1145  }
1146 
1147  return size;
1148 }
1149 
1150 //==========================================================================================================================================
1158 //==========================================================================================================================================
1159 void * oC_MemMan_AlignAddress( const void * Address )
1160 {
1161  return (void*)ALIGN_SIZE(Address,oC_MEM_LLD_MEMORY_ALIGNMENT);
1162 }
1163 
1164 //==========================================================================================================================================
1173 //==========================================================================================================================================
1174 void * oC_MemMan_AlignAddressTo( const void * Address , oC_UInt_t Alignment )
1175 {
1176  return (void*)ALIGN_SIZE(Address,Alignment);
1177 }
1178 
1179 //==========================================================================================================================================
1189 //==========================================================================================================================================
1190 bool oC_MemMan_IsAddressAligned( const void * Address )
1191 {
1192  return ((void*)ALIGN_SIZE(Address,oC_MEM_LLD_MEMORY_ALIGNMENT) == Address);
1193 }
1194 
1195 //==========================================================================================================================================
1205 //==========================================================================================================================================
1206 bool oC_MemMan_IsAddressAlignedTo( const void * Address , oC_UInt_t Alignment )
1207 {
1208  return ((void*)ALIGN_SIZE(Address,Alignment) == Address);
1209 }
1210 
1211 //==========================================================================================================================================
1221 //==========================================================================================================================================
1222 oC_UInt_t oC_MemMan_AlignSize( oC_UInt_t Size )
1223 {
1225 }
1226 
1227 //==========================================================================================================================================
1238 //==========================================================================================================================================
1239 oC_UInt_t oC_MemMan_AlignSizeTo( oC_UInt_t Size , oC_UInt_t Alignment )
1240 {
1241  return ALIGN_SIZE(Size,Alignment);
1242 }
1243 
1244 //==========================================================================================================================================
1254 //==========================================================================================================================================
1255 bool oC_MemMan_IsSizeAligned(oC_UInt_t Size)
1256 {
1257  return ALIGN_SIZE(Size,oC_MEM_LLD_MEMORY_ALIGNMENT) == Size;
1258 }
1259 
1260 //==========================================================================================================================================
1268 //==========================================================================================================================================
1270 {
1271  oC_UInt_t maximumAllocationSize = 0;
1272 
1274  {
1275  oC_UInt_t * heapPointer = HeapMap.HeapStart;
1276  oC_UInt_t size = 0;
1277  HeapMap_t * heapMaps[] = {
1278  &HeapMap ,
1279  &ExternalHeapMap,
1280  &DmaHeapMap,
1281  };
1282 
1283  oC_ARRAY_FOREACH_IN_ARRAY(heapMaps,heapMap)
1284  {
1285  do
1286  {
1287  if(IsHeapMapInitialized(*heapMap) == false)
1288  {
1289  break;
1290  }
1291 
1292  heapPointer = FindNextHeapPointerInState(*heapMap,heapPointer,NULL,HeapState_NotUsed);
1293  size = 0;
1294 
1295  for(;(heapPointer < (*heapMap)->HeapEnd) && !IsHeapUsed(*heapMap,heapPointer);heapPointer++)
1296  {
1297  size += sizeof(oC_UInt_t);
1298  }
1299 
1300  if(size > sizeof(Block_t))
1301  {
1302  size -= sizeof(Block_t);
1303 
1304  if(size > maximumAllocationSize)
1305  {
1306  maximumAllocationSize = size;
1307  }
1308  }
1309  } while(heapPointer < (*heapMap)->HeapEnd);
1310  }
1311  }
1312 
1313  return maximumAllocationSize;
1314 }
1315 
1316 //==========================================================================================================================================
1322 //==========================================================================================================================================
1323 oC_UInt_t oC_MemMan_GetFlashSize( void )
1324 {
1325  return oC_MEM_LLD_GetFlashSize();
1326 }
1327 
1328 //==========================================================================================================================================
1334 //==========================================================================================================================================
1335 oC_UInt_t oC_MemMan_GetRamSize( void )
1336 {
1337  oC_UInt_t ramSize = oC_MEM_LLD_GetRamSize();
1338 
1340  {
1341  ramSize += GetSizeOfHeap(&ExternalHeapMap);
1342  }
1343 
1345  {
1346  ramSize += GetSizeOfHeap(&DmaHeapMap);
1347  }
1348 
1349  return ramSize;
1350 }
1351 
1352 //==========================================================================================================================================
1358 //==========================================================================================================================================
1360 {
1362 }
1363 
1364 //==========================================================================================================================================
1370 //==========================================================================================================================================
1371 oC_UInt_t oC_MemMan_GetFreeRamSize( void )
1372 {
1373  oC_UInt_t freeRamSize = 0;
1374 
1376  {
1378 
1380  {
1382  }
1383 
1385  {
1387  }
1388  }
1389 
1390  return freeRamSize;
1391 }
1392 
1393 //==========================================================================================================================================
1399 //==========================================================================================================================================
1401 {
1402  oC_UInt_t externalSize = 0;
1403 
1405  {
1406  externalSize += GetSizeOfHeap(&ExternalHeapMap);
1407  }
1408 
1409  return externalSize;
1410 }
1411 
1412 //==========================================================================================================================================
1418 //==========================================================================================================================================
1420 {
1421  oC_UInt_t dmaSize = 0;
1422 
1424  {
1425  dmaSize += GetSizeOfHeap(&DmaHeapMap);
1426  }
1427 
1428  return dmaSize;
1429 }
1430 
1431 //==========================================================================================================================================
1438 //==========================================================================================================================================
1440 {
1441  oC_UInt_t size = 0;
1442 
1444  {
1445  foreach_block(block)
1446  {
1447  if(block->Allocator == Allocator)
1448  {
1449  size += sizeof(Block_t) + block->Size;
1450  }
1451  }
1452  }
1453 
1454  return size;
1455 }
1456 
1457 //==========================================================================================================================================
1465 //==========================================================================================================================================
1467 {
1468  return sizeof(Block_t);
1469 }
1470 
1471 
1472 //==========================================================================================================================================
1481 //==========================================================================================================================================
1482 oC_UInt_t oC_MemMan_GetHeapMapSize( oC_HeapMap_t Map )\
1483 {
1484  oC_UInt_t size = 0;
1486 
1488  {
1489  size = GetSizeOfHeap(Map);
1490  }
1491 
1492  return size;
1493 }
1494 
1495 //==========================================================================================================================================
1503 //==========================================================================================================================================
1504 oC_UInt_t oC_MemMan_GetFreeHeapMapSize( oC_HeapMap_t Map )
1505 {
1506  oC_UInt_t size = 0;
1508 
1510  {
1512  }
1513 
1514  return size;
1515 }
1516 
1517 //==========================================================================================================================================
1521 //==========================================================================================================================================
1522 bool oC_MemMan_IsFlashAddress( const void * Address )
1523 {
1524  return oC_MEM_LLD_IsFlashAddress(Address);
1525 }
1526 
1527 //==========================================================================================================================================
1531 //==========================================================================================================================================
1532 bool oC_MemMan_IsUsedFlashAddress( const void * Address )
1533 {
1534  return oC_MEM_LLD_IsUsedFlashAddress(Address);
1535 }
1536 
1537 //==========================================================================================================================================
1541 //==========================================================================================================================================
1542 bool oC_MemMan_IsRamAddress( const void * Address )
1543 {
1544  return oC_MEM_LLD_IsRamAddress(Address);
1545 }
1546 
1547 //==========================================================================================================================================
1551 //==========================================================================================================================================
1552 bool oC_MemMan_IsDynamicAllocatedAddress( const void * Address )
1553 {
1554  bool dynamicAllocatedAddress = IsAddressOfHeapMap(&HeapMap , Address);
1555  if(!dynamicAllocatedAddress && IsHeapMapInitialized(&ExternalHeapMap))
1556  {
1557  dynamicAllocatedAddress = IsAddressOfHeapMap(&ExternalHeapMap,Address);
1558  }
1559  return dynamicAllocatedAddress;
1560 }
1561 
1562 //==========================================================================================================================================
1566 //==========================================================================================================================================
1567 bool oC_MemMan_IsStaticRamAddress( const void * Address )
1568 {
1569  return Address >= oC_MEM_LLD_GetDataStartAddress() && Address < oC_MEM_LLD_GetDataEndAddress();
1570 }
1571 
1572 //==========================================================================================================================================
1576 //==========================================================================================================================================
1577 bool oC_MemMan_IsAddressCorrect( const void * Address )
1578 {
1579  return oC_MEM_LLD_IsRamAddress(Address) || oC_MEM_LLD_IsFlashAddress(Address);
1580 }
1581 
1582 //==========================================================================================================================================
1586 //==========================================================================================================================================
1588 {
1589  return oC_MemMan_IsAddressCorrect(Allocator) && oC_MemMan_IsAddressCorrect(Allocator->Name);
1590 }
1591 
1592 //==========================================================================================================================================
1603 //==========================================================================================================================================
1604 oC_ErrorCode_t oC_MemMan_ReadAllocatorsStats( oC_MemMan_AllocatorsStats_t * outAllocatorsArray , oC_UInt_t * Size )
1605 {
1606  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1607 
1608  if(
1609  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet) &&
1610  oC_AssignErrorCodeIfFalse(&errorCode , oC_MemMan_IsRamAddress(outAllocatorsArray) , oC_ErrorCode_OutputAddressNotInRAM) &&
1611  oC_AssignErrorCodeIfFalse(&errorCode , isram(Size) , oC_ErrorCode_AddressNotInRam) &&
1612  oC_AssignErrorCodeIfFalse(&errorCode , (*Size) > 0 , oC_ErrorCode_SizeNotCorrect)
1613  )
1614  {
1615  oC_UInt_t arrayIndex = 0;
1616 
1617  BlockModule(AllocationFlags_Default);
1618 
1619  errorCode = oC_ErrorCode_None;
1620 
1621  foreach_block(block)
1622  {
1623  bool existOnArray = false;
1624 
1625  oC_ARRAY_FOREACH_IN_ARRAY_WITH_SIZE(outAllocatorsArray,arrayIndex,stats)
1626  {
1627  if(stats->Allocator == block->Allocator)
1628  {
1629  existOnArray = true;
1630  break;
1631  }
1632  }
1633 
1634  if(!existOnArray)
1635  {
1636  if(arrayIndex < *Size)
1637  {
1638  outAllocatorsArray[arrayIndex].Allocator = block->Allocator;
1639  outAllocatorsArray[arrayIndex].Size = oC_MemMan_GetMemoryOfAllocatorSize(block->Allocator);
1640  arrayIndex++;
1641  }
1642  else
1643  {
1644  errorCode = oC_ErrorCode_OutputArrayToSmall;
1645  }
1646  }
1647  }
1648 
1649  UnblockModule();
1650 
1651  *Size = arrayIndex;
1652  }
1653 
1654  return errorCode;
1655 }
1656 
1657 //==========================================================================================================================================
1670 //==========================================================================================================================================
1671 oC_ErrorCode_t oC_MemMan_ReadAllocationsStats( Allocator_t Allocator , oC_MemMan_AllocationStats_t * outAllocationsArray , oC_UInt_t * Size , bool JoinSimilar )
1672 {
1673  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1674 
1675  if(
1676  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet) &&
1677  oC_AssignErrorCodeIfFalse(&errorCode , oC_MemMan_IsRamAddress(outAllocationsArray) , oC_ErrorCode_OutputAddressNotInRAM) &&
1678  oC_AssignErrorCodeIfFalse(&errorCode , isram(Size) , oC_ErrorCode_AddressNotInRam) &&
1679  oC_AssignErrorCodeIfFalse(&errorCode , (*Size) > 0 , oC_ErrorCode_SizeNotCorrect)
1680  )
1681  {
1682  oC_UInt_t arrayIndex = 0;
1683 
1684  BlockModule(AllocationFlags_Default);
1685 
1686  errorCode = oC_ErrorCode_None;
1687 
1688  foreach_block(block)
1689  {
1690  if(block->Allocator == Allocator)
1691  {
1692  bool found = false;
1693 
1694  if(JoinSimilar == true)
1695  {
1696  oC_ARRAY_FOREACH_IN_ARRAY_WITH_SIZE(outAllocationsArray,arrayIndex,stat)
1697  {
1698  if(stat->Function == block->Function && stat->LineNumber == block->LineNumber)
1699  {
1700  stat->Size += block->Size;
1701  found = true;
1702  }
1703  }
1704  }
1705  if(found == false)
1706  {
1707  outAllocationsArray[arrayIndex].Address = block->Address;
1708  outAllocationsArray[arrayIndex].Function = block->Function;
1709  outAllocationsArray[arrayIndex].LineNumber = block->LineNumber;
1710  outAllocationsArray[arrayIndex].Size = block->Size;
1711  outAllocationsArray[arrayIndex].Overflowed = LAST_WORD_OF_BUFFER(block->Address,block->Size) != OVERFLOW_PROTECTION_MAGIC_NUMBER;
1712 
1713  arrayIndex++;
1714  }
1715 
1716  if(arrayIndex >= (*Size))
1717  {
1718  break;
1719  }
1720  }
1721  }
1722 
1723  *Size = arrayIndex;
1724 
1725  UnblockModule();
1726  }
1727 
1728  return errorCode;
1729 }
1730 
1731 //==========================================================================================================================================
1742 //==========================================================================================================================================
1744 {
1745  bool found = false;
1746 
1747  if(ModuleEnabledFlag && isram(outAllocationStat))
1748  {
1749  foreach_block(block)
1750  {
1751  if(block->Allocator == Allocator || Allocator == NULL)
1752  {
1753  if(LAST_WORD_OF_BUFFER(block->Address,block->Size) != OVERFLOW_PROTECTION_MAGIC_NUMBER)
1754  {
1755  outAllocationStat->Address = block->Address;
1756  outAllocationStat->Function = block->Function;
1757  outAllocationStat->LineNumber = block->LineNumber;
1758  outAllocationStat->Overflowed = true;
1759  outAllocationStat->Size = block->Size;
1760  found = true;
1761  break;
1762  }
1763  }
1764  }
1765  }
1766 
1767  return found;
1768 }
1769 
1770 //==========================================================================================================================================
1781 //==========================================================================================================================================
1782 oC_ErrorCode_t oC_MemMan_ConfigureExternalHeapMap( void * StartAddress , oC_UInt_t Size )
1783 {
1784  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1785 
1786  if(
1787  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet ) &&
1788  oC_AssignErrorCodeIfFalse(&errorCode , oC_MEM_LLD_IsExternalAddress(StartAddress) , oC_ErrorCode_AddressNotInExternalMemory ) &&
1789  oC_AssignErrorCodeIfFalse(&errorCode , Size > 0 , oC_ErrorCode_SizeNotCorrect ) &&
1790  oC_AssignErrorCodeIfFalse(&errorCode , IsHeapMapInitialized(&ExternalHeapMap) == false , oC_ErrorCode_HeapMapAlreadyConfigured ) &&
1791  oC_AssignErrorCodeIfFalse(&errorCode , IsMemoryValid(StartAddress,Size) , oC_ErrorCode_CannotAccessMemory )
1792  )
1793  {
1794  errorCode = InitializeHeapMap(&ExternalHeapMap , StartAddress , StartAddress + Size , Size , true);
1795  }
1796 
1797  return errorCode;
1798 }
1799 
1800 //==========================================================================================================================================
1808 //==========================================================================================================================================
1810 {
1811  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1812 
1813  if(
1814  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet ) &&
1815  oC_AssignErrorCodeIfFalse(&errorCode , IsHeapMapInitialized(&ExternalHeapMap) == true , oC_ErrorCode_HeapMapNotConfigured )
1816  )
1817  {
1818  errorCode = oC_ErrorCode_None;
1819 
1820  foreach_block(block)
1821  {
1822  if(IsAddressOfHeapMap(&ExternalHeapMap,block->Address))
1823  {
1824  ErrorCondition(oC_MemMan_Free(block->Address,AllocationFlags_CanWaitForever),oC_ErrorCode_ReleaseError);
1825  }
1826  }
1827 
1828  memset(&ExternalHeapMap,0,sizeof(ExternalHeapMap));
1829  }
1830 
1831  return errorCode;
1832 }
1833 
1834 //==========================================================================================================================================
1839 //==========================================================================================================================================
1841 {
1842  return DefaultMemoryExhaustedLimit * 100;
1843 }
1844 
1845 //==========================================================================================================================================
1850 //==========================================================================================================================================
1852 {
1853  return PanicMemoryExhaustedLimit * 100;
1854 }
1855 
1856 //==========================================================================================================================================
1864 //==========================================================================================================================================
1865 oC_ErrorCode_t oC_MemMan_SetMemoryExhaustedLimit( float LimitPercent )
1866 {
1867  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1868 
1869  if(
1870  ErrorCondition(ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet) &&
1871  ErrorCondition(LimitPercent >= 0 && LimitPercent <= 100 , oC_ErrorCode_WrongParameters)
1872  )
1873  {
1874  DefaultMemoryExhaustedLimit = LimitPercent / 100;
1875  errorCode = oC_ErrorCode_None;
1876  }
1877 
1878  return errorCode;
1879 }
1880 
1881 //==========================================================================================================================================
1889 //==========================================================================================================================================
1890 oC_ErrorCode_t oC_MemMan_SetPanicMemoryExhaustedLimit( float LimitPercent )
1891 {
1892  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1893 
1894  if(
1895  ErrorCondition(ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet) &&
1896  ErrorCondition(LimitPercent >= 0 && LimitPercent <= 100 , oC_ErrorCode_WrongParameters)
1897  )
1898  {
1899  PanicMemoryExhaustedLimit = LimitPercent / 100;
1900  errorCode = oC_ErrorCode_None;
1901  }
1902 
1903  return errorCode;
1904 }
1905 
1906 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
1907 
1914 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
1915 
1916 //==========================================================================================================================================
1922 //==========================================================================================================================================
1923 static bool BlockModule(AllocationFlags_t Flags)
1924 {
1925  bool success = false;
1926 
1927  if(Flags & AllocationFlags_ForceBlock)
1928  {
1929  oC_IntMan_EnterCriticalSection();
1930  ModuleBusyFlag = true;
1931  success = true;
1932  oC_IntMan_ExitCriticalSection();
1933  }
1934  else if(Flags & AllocationFlags_NoWait)
1935  {
1936  oC_IntMan_EnterCriticalSection();
1937  if(ModuleBusyFlag == false)
1938  {
1939  ModuleBusyFlag = true;
1940  success = true;
1941  }
1942  oC_IntMan_ExitCriticalSection();
1943  }
1944  else
1945  {
1946  oC_IntMan_EnterCriticalSection();
1947  if(ModuleBusyFlag)
1948  {
1949  oC_IntMan_ExitCriticalSection();
1950 
1951  oC_Thread_t currentThread = oC_ThreadMan_GetCurrentThread();
1952 
1953  if(currentThread)
1954  {
1955  oC_Time_t timeout = 0;
1956 
1957  if(Flags & AllocationFlags_CanWaitForever)
1958  {
1959  timeout = oC_hour(1);
1960  }
1961  else if(Flags & AllocationFlags_CanWait1Second)
1962  {
1963  timeout = oC_s(1);
1964  }
1965  else
1966  {
1967  timeout = oC_ms(500);
1968  }
1969 
1970  if(oC_Thread_SetBlocked(currentThread,(uint32_t*)&ModuleBusyFlag,oC_Thread_Unblock_WhenEqual,false,oC_Thread_UnblockMask_All,timeout))
1971  {
1972  while(oC_Thread_IsBlocked(currentThread));
1973 
1974  oC_Thread_SetUnblocked(currentThread);
1975 
1976  oC_IntMan_EnterCriticalSection();
1977  success = true;
1978  ModuleBusyFlag = true;
1979  oC_IntMan_ExitCriticalSection();
1980  }
1981  }
1982  }
1983  else
1984  {
1985 
1986  ModuleBusyFlag = true;
1987  success = true;
1988  oC_IntMan_ExitCriticalSection();
1989  }
1990  }
1991 
1992  return success;
1993 }
1994 
1995 //==========================================================================================================================================
2001 //==========================================================================================================================================
2002 static bool UnblockModule(void)
2003 {
2004  bool success = false;
2005 
2006  oC_IntMan_EnterCriticalSection();
2007  if(ModuleBusyFlag)
2008  {
2009  ModuleBusyFlag = false;
2010  success = true;
2011  }
2012  oC_IntMan_ExitCriticalSection();
2013 
2014  return success;
2015 }
2016 
2017 //==========================================================================================================================================
2021 //==========================================================================================================================================
2022 static bool WaitForMemory( HeapMap_t * Map , oC_UInt_t Size , oC_UInt_t Alignment , AllocationFlags_t Flags )
2023 {
2024  bool memoryAvailable = false;
2025  oC_Thread_t thread = oC_ThreadMan_GetCurrentThread();
2026 
2027  if(thread)
2028  {
2029  oC_Time_t timeout = 0;
2030  oC_Time_t checkingTimeStep = 0;
2031  oC_Time_t startTime = oC_KTime_GetTimestamp();
2032  oC_Time_t currentTime = startTime;
2033 
2034  if(Flags & AllocationFlags_CanWaitForever)
2035  {
2036  timeout = startTime + oC_hour(1);
2037  checkingTimeStep = oC_min(1);
2038  }
2039  else if(Flags & AllocationFlags_CanWait1Second)
2040  {
2041  timeout = startTime + oC_s(1);
2042  checkingTimeStep = oC_ms(100);
2043  }
2044  else if(Flags & AllocationFlags_NoWait)
2045  {
2046  timeout = startTime;
2047  checkingTimeStep = 0;
2048  }
2049  else
2050  {
2051  timeout = startTime + oC_ms(500);
2052  checkingTimeStep = oC_ms(100);
2053  }
2054 
2055  do
2056  {
2057  memoryAvailable = FindFreeHeap(Map,Size,Alignment) != NULL;
2058 
2059  if(!memoryAvailable)
2060  {
2061  oC_Thread_Sleep(thread,checkingTimeStep);
2062  }
2063 
2064  currentTime = oC_KTime_GetTimestamp();
2065  } while(currentTime < timeout && memoryAvailable == false);
2066  }
2067  else
2068  {
2069  memoryAvailable = FindFreeHeap(Map,Size,Alignment) != NULL;
2070  }
2071 
2072  return memoryAvailable;
2073 }
2074 
2075 //==========================================================================================================================================
2083 //==========================================================================================================================================
2084 static oC_ErrorCode_t InitializePointers( bool FillZero )
2085 {
2086  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
2087  void * heapPointer = oC_MEM_LLD_GetHeapStartAddress();
2088  oC_UInt_t heapSize = oC_MEM_LLD_GetHeapSize() - sizeof(oC_UInt_t);
2089  void * heapEndPointer = oC_MEM_LLD_GetHeapEndAddress();
2090  void * dmaRamStart = oC_MEM_LLD_GetDmaRamStartAddress();
2091  oC_UInt_t dmaRamSize = oC_MEM_LLD_GetDmaRamSize();
2092  void * dmaRamEnd = oC_MEM_LLD_GetDmaRamEndAddress();
2093 
2094  if(ErrorCondition( oC_MEM_LLD_IsHeapAddress(heapPointer) , oC_ErrorCode_MachineHeapError ))
2095  {
2096  DataOverflowProtection = heapPointer;
2097  heapPointer += sizeof(uint32_t);
2098  BlockListHead = NULL;
2099  BlockListTail = NULL;
2102 
2103  if(ErrorCode( InitializeHeapMap( &HeapMap, heapPointer, heapEndPointer, heapSize, FillZero )) )
2104  {
2105  if(dmaRamStart == NULL)
2106  {
2107  errorCode = oC_ErrorCode_None;
2108  }
2109  else if(
2110  ErrorCondition( oC_MEM_LLD_IsDmaRamAddress(dmaRamStart) , oC_ErrorCode_NotDmaAddress )
2111  && ErrorCondition( dmaRamSize > 0 , oC_ErrorCode_SizeNotCorrect )
2112  )
2113  {
2114  errorCode = InitializeHeapMap( &DmaHeapMap, dmaRamStart, dmaRamEnd, dmaRamSize, FillZero );
2115  }
2116  }
2117  }
2118 
2119  return errorCode;
2120 }
2121 
2122 //==========================================================================================================================================
2134 //==========================================================================================================================================
2135 static oC_ErrorCode_t InitializeHeapMap( HeapMap_t * Map , void * HeapStartPointer , void * HeapEndPointer , oC_UInt_t HeapSize , bool FillZero )
2136 {
2137  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
2138 
2139 
2140  if(oC_MEM_LLD_IsHeapAddress(HeapStartPointer) || oC_MEM_LLD_IsExternalAddress(HeapStartPointer) || oC_MEM_LLD_IsDmaRamAddress(HeapStartPointer))
2141  {
2142  Map->BitMapStart = HeapStartPointer;
2143  Map->BitMapEnd = Map->BitMapStart + ALIGN_SIZE( HeapSize / ( sizeof(oC_UInt_t) * 8 ) , oC_MEM_LLD_MEMORY_ALIGNMENT);
2144  Map->HeapStart = (oC_UInt_t*)Map->BitMapEnd;
2145  Map->HeapEnd = HeapEndPointer;
2146  Map->Self = Map;
2147 
2148  for(uint8_t * heapPointer = Map->BitMapStart; heapPointer < (uint8_t*)Map->BitMapEnd;heapPointer++)
2149  {
2150  *heapPointer = 0;
2151  }
2152 
2153  if(FillZero)
2154  {
2155  for(uint8_t * heapPointer = HeapStartPointer;heapPointer < (uint8_t*)HeapEndPointer; heapPointer++)
2156  {
2157  *heapPointer = 0;
2158  }
2159  }
2160 
2161  errorCode = oC_ErrorCode_None;
2162  }
2163  else
2164  {
2165  errorCode = oC_ErrorCode_MachineHeapError;
2166  }
2167 
2168  return errorCode;
2169 }
2170 
2171 //==========================================================================================================================================
2179 //==========================================================================================================================================
2180 static Block_t * FindBlockOfAddress(const void * Address )
2181 {
2182  Block_t * blockToReturn = NULL;
2183 
2184  oC_IntMan_EnterCriticalSection();
2185 
2186  foreach_block(block)
2187  {
2188  if(block->Address == Address)
2189  {
2190  blockToReturn = block;
2191  break;
2192  }
2193  }
2194 
2195  oC_IntMan_ExitCriticalSection();
2196 
2197  return blockToReturn;
2198 }
2199 
2200 //==========================================================================================================================================
2208 //==========================================================================================================================================
2209 static Block_t * FindBlockContainsAddress(const void * Address)
2210 {
2211  Block_t * blockToReturn = NULL;
2212 
2213  foreach_block(block)
2214  {
2215  if( (Address >= block->Address) && (Address < (block->Address + block->Size)))
2216  {
2217  blockToReturn = block;
2218  break;
2219  }
2220  }
2221 
2222  return blockToReturn;
2223 }
2224 
2225 //==========================================================================================================================================
2234 //==========================================================================================================================================
2235 static oC_UInt_t GetIndexOfHeapPointer( HeapMap_t * Map , oC_UInt_t * HeapPointer )
2236 {
2237  oC_ASSERT(Map->HeapStart <= HeapPointer);
2238  return (oC_UInt_t)(HeapPointer - Map->HeapStart);
2239 }
2240 
2241 //==========================================================================================================================================
2250 //==========================================================================================================================================
2251 static inline bool IsAddressOfHeapMap( HeapMap_t * Map , const void * Address )
2252 {
2253  return (Address >= ((void*)Map->HeapStart)) && (Address < ((void*)Map->HeapEnd));
2254 }
2255 
2256 //==========================================================================================================================================
2260 //==========================================================================================================================================
2261 static inline bool IsBlockCorrect( Block_t * Block )
2262 {
2263  return IsAddressOfHeapMap(&HeapMap,Block) &&
2264  oC_MemMan_IsAllocatorCorrect(Block->Allocator) &&
2265  IsAddressOfHeapMap(&HeapMap,Block->Address) &&
2266  CheckIfHeapInRangeIsInState(&HeapMap,Block->Address,(Block->Address + Block->Size),HeapState_Used);
2267 }
2268 
2269 //==========================================================================================================================================
2273 //==========================================================================================================================================
2274 static inline bool IsHeapUsed( HeapMap_t * Map , oC_UInt_t * HeapPointer )
2275 {
2276  oC_UInt_t heapIndex = GetIndexOfHeapPointer(Map,HeapPointer);
2277  oC_UInt_t bitMapIndex= heapIndex / 8;
2278  oC_UInt_t bitIndex = heapIndex % 8;
2279  return oC_Bits_IsBitSetU8( Map->BitMapStart[bitMapIndex] , bitIndex );
2280 }
2281 //==========================================================================================================================================
2285 //==========================================================================================================================================
2286 static inline bool IsHeapMapInitialized( HeapMap_t * Map )
2287 {
2288  return (Map->Self == Map );
2289 }
2290 
2291 //==========================================================================================================================================
2295 //==========================================================================================================================================
2296 static void DumpHeapMap(HeapMap_t * Map , oC_MemMan_DumpFunction_t DumpFunction)
2297 {
2298  if(oC_MemMan_IsAddressCorrect(DumpFunction))
2299  {
2300  for(oC_UInt_t * heapPointer = Map->HeapStart ; heapPointer < Map->HeapEnd ; heapPointer++ )
2301  {
2302  DumpFunction(*heapPointer);
2303  }
2304  }
2305 }
2306 
2307 //==========================================================================================================================================
2311 //==========================================================================================================================================
2312 static inline void SetHeapState( HeapMap_t * Map , oC_UInt_t * HeapPointer , HeapState_t HeapState )
2313 {
2314  oC_UInt_t heapIndex = GetIndexOfHeapPointer(Map,HeapPointer);
2315  oC_UInt_t bitMapIndex= heapIndex / 8;
2316  oC_UInt_t bitIndex = heapIndex % 8;
2317 
2318  if(HeapState == HeapState_Used)
2319  {
2320  oC_Bits_SetBitU8(&Map->BitMapStart[bitMapIndex] , bitIndex);
2321  }
2322  else
2323  {
2324  oC_Bits_ClearBitU8(&Map->BitMapStart[bitMapIndex] , bitIndex);
2325  }
2326 }
2327 
2328 //==========================================================================================================================================
2332 //==========================================================================================================================================
2333 static bool CheckIfHeapInRangeIsInState( HeapMap_t * Map , oC_UInt_t * HeapFrom , oC_UInt_t * HeapTo , HeapState_t HeapState )
2334 {
2335  bool stateCorrect = true;
2336 
2337  for(oC_UInt_t * heapPointer = HeapFrom; heapPointer < HeapTo ; heapPointer++)
2338  {
2339  if(HeapState != IsHeapUsed(Map,heapPointer))
2340  {
2341  stateCorrect = false;
2342  break;
2343  }
2344  }
2345 
2346  return stateCorrect;
2347 }
2348 
2349 //==========================================================================================================================================
2353 //==========================================================================================================================================
2354 static inline void SetHeapStateInRange( HeapMap_t * Map , oC_UInt_t * HeapFrom , oC_UInt_t * HeapTo , HeapState_t HeapState )
2355 {
2356  for(oC_UInt_t * heapPointer = HeapFrom; (heapPointer < HeapTo) && (heapPointer < Map->HeapEnd) ; heapPointer++)
2357  {
2358  SetHeapState( Map, heapPointer , HeapState);
2359  }
2360 }
2361 
2362 //==========================================================================================================================================
2366 //==========================================================================================================================================
2367 static oC_UInt_t * FindNextHeapPointerInState( HeapMap_t * Map , oC_UInt_t * HeapPointer , oC_UInt_t * HeapEndLimit , HeapState_t HeapState )
2368 {
2369  if(HeapEndLimit == NULL)
2370  {
2371  HeapEndLimit = Map->HeapEnd;
2372  }
2373 
2374  while((HeapPointer < Map->HeapEnd) && (HeapPointer < HeapEndLimit) && (HeapState != IsHeapUsed( Map , HeapPointer)))
2375  {
2376  HeapPointer++;
2377  }
2378 
2379  return HeapPointer;
2380 }
2381 
2382 //==========================================================================================================================================
2386 //==========================================================================================================================================
2387 static oC_UInt_t GetSizeOfHeapInState( HeapMap_t * Map , HeapState_t HeapState )
2388 {
2389  oC_UInt_t size = 0;
2390 
2391  for(oC_UInt_t * heapPointer = Map->HeapStart;heapPointer<Map->HeapEnd;heapPointer++)
2392  {
2393  if(HeapState == IsHeapUsed(Map,heapPointer))
2394  {
2395  size += sizeof(oC_UInt_t);
2396  }
2397  }
2398 
2399  return size;
2400 }
2401 
2402 //==========================================================================================================================================
2406 //==========================================================================================================================================
2407 static oC_UInt_t GetSizeOfHeap( HeapMap_t * Map )
2408 {
2409  return ((oC_UInt_t)Map->HeapEnd) - ((oC_UInt_t)Map->HeapStart);
2410 }
2411 
2412 //==========================================================================================================================================
2416 //==========================================================================================================================================
2417 static void * FindFreeHeap( HeapMap_t * Map , oC_UInt_t Size , oC_UInt_t Alignment )
2418 {
2419  void * address = NULL;
2420  void * heapFrom = Map->HeapStart;
2421  void * heapTo = NULL;
2422  void * heapToLimit = NULL;
2423  oC_UInt_t foundSize = 0;
2424 
2425  while((heapFrom < ((void*)Map->HeapEnd)) && (heapToLimit < ((void*)Map->HeapEnd)) && (address == NULL))
2426  {
2427  heapFrom = FindNextHeapPointerInState( Map , heapFrom , NULL , HeapState_NotUsed);
2428 
2429  if(oC_MemMan_IsAddressAlignedTo(heapFrom,Alignment))
2430  {
2431  heapToLimit = heapFrom + ALIGN_SIZE(Size,Alignment) + sizeof(oC_UInt_t);
2432  heapTo = FindNextHeapPointerInState( Map , heapFrom , heapToLimit , HeapState_Used);
2433 
2434  /* If not found used heap, set it to the end of the heap map */
2435  if(heapTo == Map->HeapEnd || heapTo == heapToLimit)
2436  {
2437  heapTo-= sizeof(oC_UInt_t);
2438  }
2439 
2440  foundSize = (oC_UInt_t)(heapTo - heapFrom);
2441 
2442  if(foundSize >= ALIGN_SIZE(Size,Alignment))
2443  {
2444  address = heapFrom;
2445  break;
2446  }
2447  else
2448  {
2449  heapFrom = heapTo;
2450  }
2451  }
2452  else
2453  {
2454  heapFrom += sizeof(oC_UInt_t);
2455  }
2456  }
2457 
2458  return address;
2459 }
2460 
2461 //==========================================================================================================================================
2465 //==========================================================================================================================================
2466 static void * RawAlloc( HeapMap_t * Map , oC_UInt_t Size , oC_UInt_t Alignment )
2467 {
2468  void * address = FindFreeHeap(Map,Size,Alignment);
2469  void * heapFrom = address;
2470  void * heapTo = address + ALIGN_SIZE(Size,Alignment);
2471 
2472  if(address != NULL && CheckIfHeapInRangeIsInState( Map , heapFrom, heapTo , HeapState_NotUsed))
2473  {
2474  SetHeapStateInRange( Map , heapFrom , heapTo , HeapState_Used );
2475  }
2476 
2477  return address;
2478 }
2479 
2480 //==========================================================================================================================================
2484 //==========================================================================================================================================
2485 static bool RawFree( HeapMap_t * Map , void * Address , oC_UInt_t Size)
2486 {
2487  bool memoryReleased = false;
2488  void * endAddress = Address + ALIGN_SIZE(Size,oC_MEM_LLD_MEMORY_ALIGNMENT);
2489 
2490  if(IsAddressOfHeapMap(Map,Address))
2491  {
2492  SetHeapStateInRange(Map , Address , endAddress , HeapState_NotUsed);
2493 
2494  if(IsAddressOfHeapMap(Map,endAddress))
2495  {
2496  memoryReleased = true;
2497  }
2498  }
2499 
2500  return memoryReleased;
2501 }
2502 
2503 //==========================================================================================================================================
2507 //==========================================================================================================================================
2508 static bool IsMemoryValid( void * Start , oC_UInt_t Size )
2509 {
2510  bool memoryOk = true;
2511  uint8_t* memoryArray = Start;
2512  oC_UInt_t sizeStepIndex = 0;
2513  uint8_t valueToWrite = 0;
2514  bool writeFF = false;
2515  oC_UInt_t sizeSteps[] = {
2516  kB(100) ,
2517  B(1) ,
2518  B(1) ,
2519  B(1) ,
2520  B(1) ,
2521  B(4) ,
2522  B(4) ,
2523  B(40) ,
2524  };
2525 
2526  for(uint32_t i = 0 ; i < Size ; i+= sizeSteps[sizeStepIndex++])
2527  {
2528  valueToWrite = writeFF ? 0xFF : (uint8_t)(i & 0xFF);
2529  memoryArray[i] = valueToWrite;
2530 
2531  if(sizeStepIndex >= oC_ARRAY_SIZE(sizeSteps))
2532  {
2533  sizeStepIndex = 0;
2534  writeFF = !writeFF;
2535  }
2536  }
2537 
2538  sizeStepIndex = 0;
2539  writeFF = false;
2540 
2541  for(uint32_t i = 0 ; i < Size ; i+= sizeSteps[sizeStepIndex++])
2542  {
2543  valueToWrite = writeFF ? 0xFF : (uint8_t)(i & 0xFF);
2544 
2545  if(memoryArray[i] != valueToWrite)
2546  {
2547  kdebuglog(oC_LogType_Error,"MemMan: External memory access error - (%p) %u != %u\n", &memoryArray[i] , (unsigned int)memoryArray[i] , valueToWrite );
2548  memoryOk = false;
2549  break;
2550  }
2551 
2552  if(sizeStepIndex >= oC_ARRAY_SIZE(sizeSteps))
2553  {
2554  sizeStepIndex = 0;
2555  writeFF = !writeFF;
2556  }
2557  }
2558 
2559  return memoryOk;
2560 }
2561 
2562 //==========================================================================================================================================
2566 //==========================================================================================================================================
2567 static void CallAllocatorEvent( Allocator_t Allocator , void * Address , MemoryEventFlags_t EventFlags , const char * Function, uint32_t LineNumber )
2568 {
2569  if(
2570  oC_MemMan_IsAllocatorCorrect(Allocator) &&
2572  (oC_Bits_AreBitsSetU32(Allocator->EventFlags , EventFlags))
2573  )
2574  {
2575  Allocator->EventHandler( Address, EventFlags ,Function ,LineNumber );
2576  }
2577 }
2578 
2579 //==========================================================================================================================================
2583 //==========================================================================================================================================
2584 static void CallEvent(void * Address , MemoryEventFlags_t EventFlags , const char * Function, uint32_t LineNumber)
2585 {
2586  if(ModuleEventHandler)
2587  {
2588  ModuleEventHandler( Address, EventFlags, Function, LineNumber );
2589  }
2590 }
2591 
2592 //==========================================================================================================================================
2596 //==========================================================================================================================================
2597 static void MemoryFaultInterrupt(void)
2598 {
2599  CallEvent(NULL,MemoryEventFlags_MemoryFault,"",0);
2600 }
2601 
2602 //==========================================================================================================================================
2606 //==========================================================================================================================================
2607 static void BusFaultInterrupt(void)
2608 {
2609  CallEvent(NULL,MemoryEventFlags_BusFault,"",0);
2610 }
2611 
2612 //==========================================================================================================================================
2616 //==========================================================================================================================================
2617 static bool CanReleaseMemory( Block_t * Block )
2618 {
2619  bool releaseAllowed = false;
2620 
2621  if(Block->AllocationFlags & AllocationFlags_ReleaseOnlyInCore)
2622  {
2624  }
2625  else
2626  {
2627  releaseAllowed = true;
2628  }
2629 
2630  return releaseAllowed;
2631 }
2632 
2633 
2634 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
bool oC_MemMan_IsAllocatorCorrect(Allocator_t Allocator)
checks if allocator is correct
Definition: oc_memman.c:1587
#define ALIGN_SIZE(SIZE, ALIGNMENT)
Definition: oc_memman.c:102
static bool oC_Bits_AreBitsSetU32(uint32_t BitMask, uint32_t BitsToCheck)
checks if all bits in field are set
Definition: oc_bits.h:884
FILE__DESCRIPTION
static bool ModuleEnabledFlag
Definition: oc_memman.c:211
bool oC_MEM_LLD_IsUsedFlashAddress(const void *Address)
checks if the pointer is in used flash section
Definition: oc_mem_lld.c:444
static bool WaitForMemory(HeapMap_t *Map, oC_UInt_t Size, oC_UInt_t Alignment, AllocationFlags_t Flags)
Definition: oc_memman.c:2022
#define oC_ARRAY_SIZE(ARRAY)
returns size of static array
Definition: oc_array.h:36
static void * RawAlloc(HeapMap_t *Map, oC_UInt_t Size, oC_UInt_t Alignment)
Definition: oc_memman.c:2466
bool oC_MemMan_FreeHeapMap(oC_HeapMap_t *Map, AllocationFlags_t Flags)
release heap map
Definition: oc_memman.c:596
const char * Name
Definition: oc_stdlib.h:161
void(* oC_MemMan_DumpFunction_t)(oC_UInt_t Data)
stores pointer to function for dumping data
Definition: oc_memman.h:156
void * oC_MemMan_AlignAddressTo(const void *Address, oC_UInt_t Alignment)
returns address aligned to the given alignment.
Definition: oc_memman.c:1174
oC_ErrorCode_t oC_MemMan_TurnOff(void)
turns off the module
Definition: oc_memman.c:313
void * oC_MEM_LLD_GetDataEndAddress(void)
returns end address of the data section
Definition: oc_mem_lld.c:301
static HeapMap_t ExternalHeapMap
Definition: oc_memman.c:219
struct _HeapMap_t HeapMap_t
static HeapMap_t HeapMap
Definition: oc_memman.c:218
oC_ErrorCode_t oC_MEM_LLD_SetBusFaultInterrupt(oC_MEM_LLD_Interrupt_t Interrupt)
sets interrupt handler for bus fault
Definition: oc_mem_lld.c:498
float oC_MemMan_GetPanicMemoryExhaustedLimit(void)
Definition: oc_memman.c:1851
oC_UInt_t oC_MemMan_GetFreeFlashSize(void)
returns size of the machine not used flash
Definition: oc_memman.c:1359
bool oC_MemMan_IsRamAddress(const void *Address)
checks if address is in ram section
Definition: oc_memman.c:1542
identifier for allocations
Definition: oc_stdlib.h:159
oC_ErrorCode_t oC_MemMan_UnconfigureExternalHeapMap(void)
unconfigures external heap
Definition: oc_memman.c:1809
#define LAST_WORD_OF_BUFFER(Buffer, Size)
Definition: oc_memman.c:95
oC_UInt_t oC_MemMan_AlignSizeTo(oC_UInt_t Size, oC_UInt_t Alignment)
returns size aligned to the given alignment
Definition: oc_memman.c:1239
oC_MemorySize_t Limit
Definition: oc_stdlib.h:164
oC_UInt_t oC_MemMan_GetMaximumAllocationSize(void)
returns maximum size of allocation
Definition: oc_memman.c:1269
static void DumpHeapMap(HeapMap_t *Map, oC_MemMan_DumpFunction_t DumpFunction)
Definition: oc_memman.c:2296
With ifnot definition.
static uint32_t ModuleBusyFlag
Definition: oc_memman.c:212
bool oC_MemMan_FreeAllMemoryOfAllocator(Allocator_t Allocator)
release all memory of allocator
Definition: oc_memman.c:985
void * oC_MemMan_RawAllocate(oC_HeapMap_t Map, oC_UInt_t Size, const char *Function, uint32_t LineNumber, AllocationFlags_t Flags)
allow to allocate memory in heap map
Definition: oc_memman.c:643
#define foreach_block(block)
Definition: oc_memman.c:76
bool oC_MemMan_IsStaticRamAddress(const void *Address)
checks if address is in static used ram section (data section)
Definition: oc_memman.c:1567
oC_ErrorCode_t oC_MEM_LLD_TurnOffDriver(void)
release the driver
Definition: oc_mem_lld.c:92
static void SetHeapState(HeapMap_t *Map, oC_UInt_t *HeapPointer, HeapState_t HeapState)
Definition: oc_memman.c:2312
#define OVERFLOW_PROTECTION_MAGIC_NUMBER
Definition: oc_memman.c:54
oC_UInt_t oC_MemMan_GetSizeOfAllocation(const void *Address)
returns size of allocation
Definition: oc_memman.c:1133
static oC_UInt_t GetSizeOfHeapInState(HeapMap_t *Map, HeapState_t HeapState)
Definition: oc_memman.c:2387
bool oC_MEM_LLD_IsExternalAddress(const void *Address)
checks if the pointer is in external section
Definition: oc_mem_lld.c:411
oC_ErrorCode_t oC_MemMan_SetPanicMemoryExhaustedLimit(float LimitPercent)
Definition: oc_memman.c:1890
void * oC_MEM_LLD_GetDmaRamStartAddress(void)
returns start address of the DMA RAM
Definition: oc_mem_lld.c:158
float oC_MemMan_GetMemoryExhaustedLimit(void)
Definition: oc_memman.c:1840
bool oC_MemMan_RawFree(oC_HeapMap_t Map, void *Address, oC_UInt_t Size)
release memory in heap map
Definition: oc_memman.c:692
oC_UInt_t oC_MemMan_GetHeapMapSize(oC_HeapMap_t Map)
returns size of heap map
Definition: oc_memman.c:1482
static void SetHeapStateInRange(HeapMap_t *Map, oC_UInt_t *HeapFrom, oC_UInt_t *HeapTo, HeapState_t HeapState)
Definition: oc_memman.c:2354
struct _Block_t Block_t
static bool IsAddressOfHeapMap(HeapMap_t *Map, const void *Address)
Definition: oc_memman.c:2251
heap is not used
Definition: oc_memman.c:136
oC_UInt_t oC_MemMan_GetExternalHeapSize(void)
returns size of external ram
Definition: oc_memman.c:1400
static bool UnblockModule(void)
Definition: oc_memman.c:2002
bool oC_MEM_LLD_IsFlashAddress(const void *Address)
checks if the pointer is in flash section
Definition: oc_mem_lld.c:433
#define B(Bytes)
Number of bytes.
Definition: oc_cfg.h:73
oC_ErrorCode_t oC_MEM_LLD_TurnOnBusFaultInterrupt(void)
turns on bus fault interrupt
Definition: oc_mem_lld.c:551
The file with LLD interface for the MEM driver.
static uint8_t oC_Bits_ClearBitU8(uint8_t *outVariable, uint8_t BitIndex)
clear selected bit
Definition: oc_bits.h:778
static oC_UInt_t GetSizeOfHeap(HeapMap_t *Map)
Definition: oc_memman.c:2407
MemoryEventHandler_t EventHandler
Definition: oc_stdlib.h:162
oC_ErrorCode_t oC_MEM_LLD_TurnOnDriver(void)
initializes the driver to work
Definition: oc_mem_lld.c:63
static void CallAllocatorEvent(Allocator_t Allocator, void *Address, MemoryEventFlags_t EventFlags, const char *Function, uint32_t LineNumber)
Definition: oc_memman.c:2567
void * oC_MEM_LLD_GetHeapEndAddress(void)
returns end address of the heap
Definition: oc_mem_lld.c:235
oC_UInt_t oC_MemMan_GetFreeHeapMapSize(oC_HeapMap_t Map)
returns size of free memory in heap map
Definition: oc_memman.c:1504
static bool BlockModule(AllocationFlags_t Flags)
Definition: oc_memman.c:1923
static bool oC_Bits_IsBitSetU8(uint8_t BitMask, uint8_t BitIndex)
checks if bit is set
Definition: oc_bits.h:645
oC_ErrorCode_t oC_MemMan_TurnOn(void)
turns on memory manager
Definition: oc_memman.c:251
oC_ErrorCode_t oC_MemMan_ConfigureExternalHeapMap(void *StartAddress, oC_UInt_t Size)
prepares HeapMap stored in external RAM
Definition: oc_memman.c:1782
oC_MEM_LLD_Size_t oC_MEM_LLD_GetUsedFlashSize(void)
returns size of the used flash section
Definition: oc_mem_lld.c:378
HeapState_t
Definition: oc_memman.c:134
void * oC_MemMan_Allocate(oC_UInt_t Size, Allocator_t Allocator, const char *Function, uint32_t LineNumber, AllocationFlags_t Flags, oC_UInt_t Alignment)
allocates memory on heap
Definition: oc_memman.c:770
oC_MEM_LLD_Size_t oC_MEM_LLD_GetDmaRamSize(void)
returns size of the DMA ram
Definition: oc_mem_lld.c:180
oC_UInt_t oC_MemMan_GetAllocationBlockSize(void)
returns size of block needed for allocation
Definition: oc_memman.c:1466
bool oC_MemMan_IsDynamicAllocatedAddress(const void *Address)
checks if address is in dynamic allocated section
Definition: oc_memman.c:1552
bool oC_MemMan_IsAddressCorrect(const void *Address)
checks if address is correct - in RAM or in FLASH
Definition: oc_memman.c:1577
oC_UInt_t oC_MemMan_GetFlashSize(void)
returns size of the machine flash
Definition: oc_memman.c:1323
bool oC_MemMan_IsAddressAlignedTo(const void *Address, oC_UInt_t Alignment)
checks if address is aligned to given alignment
Definition: oc_memman.c:1206
oC_ErrorCode_t oC_MemMan_ReadAllocatorsStats(oC_MemMan_AllocatorsStats_t *outAllocatorsArray, oC_UInt_t *Size)
Reads allocators statistics array.
Definition: oc_memman.c:1604
static bool IsHeapUsed(HeapMap_t *Map, oC_UInt_t *HeapPointer)
Definition: oc_memman.c:2274
Allocator_t oC_MemMan_GetAllocatorOfAddress(const void *Address)
returns allocator of address
Definition: oc_memman.c:1098
static bool ModuleTestModeEnabledFlag
Definition: oc_memman.c:210
Memory controller is configured to allow for memory access for regions that can be accessible by a pr...
Definition: oc_mem_lld.h:137
bool oC_MemMan_IsAddressAligned(const void *Address)
checks if address is aligned
Definition: oc_memman.c:1190
bool oC_MEM_LLD_IsHeapAddress(const void *Address)
checks if the pointer is in heap section
Definition: oc_mem_lld.c:455
bool oC_MemMan_FindOverflowedAllocation(Allocator_t Allocator, oC_MemMan_AllocationStats_t *outAllocationStat)
searches for a overflowed buffer
Definition: oc_memman.c:1743
static MemoryEventHandler_t ModuleEventHandler
Definition: oc_memman.c:217
The file with interface for interrupt manager.
void oC_MemMan_CheckMemoryLeak(void)
checks if memory is not leaking
Definition: oc_memman.c:425
oC_ErrorCode_t oC_MemMan_ReadAllocationsStats(Allocator_t Allocator, oC_MemMan_AllocationStats_t *outAllocationsArray, oC_UInt_t *Size, bool JoinSimilar)
Reads allocations statistics of the allocator.
Definition: oc_memman.c:1671
oC_UInt_t oC_MemMan_GetFreeRamSize(void)
returns size of free ram
Definition: oc_memman.c:1371
static uint32_t * DataOverflowProtection
Definition: oc_memman.c:214
oC_UInt_t oC_MemMan_AlignSize(oC_UInt_t Size)
returns size aligned to the machine alignment
Definition: oc_memman.c:1222
static bool IsBlockCorrect(Block_t *Block)
Definition: oc_memman.c:2261
oC_UInt_t oC_MemMan_GetMemoryOfAllocatorSize(Allocator_t Allocator)
returns size of allocations per allocator
Definition: oc_memman.c:1439
bool oC_MemMan_Free(void *Address, AllocationFlags_t Flags)
release allocated memory
Definition: oc_memman.c:908
oC_UInt_t oC_MemMan_GetDmaRamHeapSize(void)
returns size of external ram
Definition: oc_memman.c:1419
static void * FindFreeHeap(HeapMap_t *Map, oC_UInt_t Size, oC_UInt_t Alignment)
Definition: oc_memman.c:2417
static Block_t * BlockListHead
Definition: oc_memman.c:215
oC_MEM_LLD_Size_t oC_MEM_LLD_GetRamSize(void)
returns size of the ram
Definition: oc_mem_lld.c:147
oC_MEM_LLD_Size_t oC_MEM_LLD_GetHeapSize(void)
returns size of the heap
Definition: oc_mem_lld.c:246
oC_MEM_LLD_Size_t oC_MEM_LLD_GetFlashSize(void)
returns size of the flash section
Definition: oc_mem_lld.c:213
The file with functions for the bits operation.
oC_ErrorCode_t oC_MemMan_SetMemoryExhaustedLimit(float LimitPercent)
Definition: oc_memman.c:1865
oC_UInt_t oC_MemMan_GetRamSize(void)
returns size of the machine ram
Definition: oc_memman.c:1335
static oC_ErrorCode_t InitializePointers(bool FillZero)
Definition: oc_memman.c:2084
static oC_UInt_t GetIndexOfHeapPointer(HeapMap_t *Map, oC_UInt_t *HeapPointer)
Definition: oc_memman.c:2235
bool oC_MemMan_IsUsedFlashAddress(const void *Address)
checks if address is in used flash section
Definition: oc_memman.c:1532
Static array definitions.
oC_ErrorCode_t oC_MemMan_TestAndRepairMainHeap(oC_MemMan_DumpFunction_t DumpFunction)
diagnoses main heap
Definition: oc_memman.c:449
#define oC_MEM_LLD_MEMORY_ALIGNMENT
number of bytes in memory alignment
Definition: oc_mem_lld.h:97
static Block_t * FindBlockContainsAddress(const void *Address)
Definition: oc_memman.c:2209
void * oC_MEM_LLD_GetHeapStartAddress(void)
returns start address of the heap
Definition: oc_mem_lld.c:224
The file with memory manager interface.
bool oC_MemMan_IsSizeAligned(oC_UInt_t Size)
checks if a size is aligned
Definition: oc_memman.c:1255
void * oC_MemMan_AlignAddress(const void *Address)
returns address aligned to the machine alignment.
Definition: oc_memman.c:1159
static void CallEvent(void *Address, MemoryEventFlags_t EventFlags, const char *Function, uint32_t LineNumber)
Definition: oc_memman.c:2584
oC_MEM_LLD_MemoryAccessMode_t oC_MEM_LLD_GetMemoryAccessMode(void)
returns currently configured memory access mode
Definition: oc_mem_lld.c:665
static void BusFaultInterrupt(void)
Definition: oc_memman.c:2607
Definition of the null pointer.
static const oC_Allocator_t Allocator
Definition: oc_eth.c:152
oC_ErrorCode_t oC_MEM_LLD_SetMemoryFaultInterrupt(oC_MEM_LLD_Interrupt_t Interrupt)
sets interrupt handler for memory fault
Definition: oc_mem_lld.c:466
static bool RawFree(HeapMap_t *Map, void *Address, oC_UInt_t Size)
Definition: oc_memman.c:2485
bool oC_MEM_LLD_IsDmaRamAddress(const void *Address)
checks if the pointer is in DMA RAM section
Definition: oc_mem_lld.c:422
MemoryEventFlags_t EventFlags
Definition: oc_stdlib.h:163
The file with LLD interface for the SYS driver.
oC_ErrorCode_t oC_MEM_LLD_TurnOnMemoryFaultInterrupt(void)
turns on memory fault interrupt
Definition: oc_mem_lld.c:529
static bool IsHeapMapInitialized(HeapMap_t *Map)
Definition: oc_memman.c:2286
void oC_MemMan_CheckMemoryExhausted(void)
checks if memory exhausted event not occurs.
Definition: oc_memman.c:385
#define kB(kBytes)
Number of kB.
Definition: oc_cfg.h:78
void * oC_MEM_LLD_GetDmaRamEndAddress(void)
returns end address of the DMA RAM
Definition: oc_mem_lld.c:169
oC_ErrorCode_t oC_MemMan_SetEventHandler(MemoryEventHandler_t EventHandler)
sets event handler function
Definition: oc_memman.c:1035
oC_HeapMap_t oC_MemMan_AllocateHeapMap(oC_UInt_t Size, Allocator_t Allocator, const char *Function, uint32_t LineNumber, AllocationFlags_t Flags)
allocates memory for new heap map
Definition: oc_memman.c:543
static HeapMap_t DmaHeapMap
Definition: oc_memman.c:220
The file with interface for Thread Manager.
static bool FirstPowerOn
Definition: oc_memman.c:213
bool oC_MemMan_IsFlashAddress(const void *Address)
checks if address is placed in the flash section
Definition: oc_memman.c:1522
void oC_MemMan_CheckOverflow(void)
scan each block to check if the overflow event not occurs.
Definition: oc_memman.c:355
static Block_t * FindBlockOfAddress(const void *Address)
Definition: oc_memman.c:2180
static oC_ErrorCode_t InitializeHeapMap(HeapMap_t *Map, void *HeapStartPointer, void *HeapEndPointer, oC_UInt_t HeapSize, bool FillZero)
Definition: oc_memman.c:2135
static bool CheckIfHeapInRangeIsInState(HeapMap_t *Map, oC_UInt_t *HeapFrom, oC_UInt_t *HeapTo, HeapState_t HeapState)
Definition: oc_memman.c:2333
static bool IsMemoryValid(void *Start, oC_UInt_t Size)
tests memory for the heap usage
Definition: oc_memman.c:2508
static void MemoryFaultInterrupt(void)
Definition: oc_memman.c:2597
static Block_t * BlockListTail
Definition: oc_memman.c:216
static bool CanReleaseMemory(Block_t *Block)
Definition: oc_memman.c:2617
static uint8_t oC_Bits_SetBitU8(uint8_t *outVariable, uint8_t BitIndex)
sets bit in the variable
Definition: oc_bits.h:711
The file with interface of kernel time module.
heap is used
Definition: oc_memman.c:137
bool oC_MEM_LLD_IsRamAddress(const void *Address)
checks if the pointer is in ram section
Definition: oc_mem_lld.c:400
#define NULL
pointer to a zero
Definition: oc_null.h:37
static oC_UInt_t * FindNextHeapPointerInState(HeapMap_t *Map, oC_UInt_t *HeapPointer, oC_UInt_t *HeapEndLimit, HeapState_t HeapState)
Definition: oc_memman.c:2367
void * oC_MEM_LLD_GetDataStartAddress(void)
returns start address of the data section
Definition: oc_mem_lld.c:290