summaryrefslogtreecommitdiff
path: root/rtos/FreeRTOS/Source/portable/MemMang/heap_4.c
diff options
context:
space:
mode:
Diffstat (limited to 'rtos/FreeRTOS/Source/portable/MemMang/heap_4.c')
-rw-r--r--rtos/FreeRTOS/Source/portable/MemMang/heap_4.c135
1 files changed, 77 insertions, 58 deletions
diff --git a/rtos/FreeRTOS/Source/portable/MemMang/heap_4.c b/rtos/FreeRTOS/Source/portable/MemMang/heap_4.c
index 64d9622..97855c4 100644
--- a/rtos/FreeRTOS/Source/portable/MemMang/heap_4.c
+++ b/rtos/FreeRTOS/Source/portable/MemMang/heap_4.c
@@ -1,60 +1,64 @@
/*
- FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
+ FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
- ***************************************************************************
- * *
- * FreeRTOS provides completely free yet professionally developed, *
- * robust, strictly quality controlled, supported, and cross *
- * platform software that has become a de facto standard. *
- * *
- * Help yourself get started quickly and support the FreeRTOS *
- * project by purchasing a FreeRTOS tutorial book, reference *
- * manual, or both from: http://www.FreeRTOS.org/Documentation *
- * *
- * Thank you! *
- * *
- ***************************************************************************
-
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+ Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
- >>! NOTE: The modification to the GPL is included to allow you to distribute
- >>! a combined work that includes FreeRTOS without being obliged to provide
- >>! the source code for proprietary components outside of the FreeRTOS
- >>! kernel.
+ ***************************************************************************
+ >>! NOTE: The modification to the GPL is included to allow you to !<<
+ >>! distribute a combined work that includes FreeRTOS without being !<<
+ >>! obliged to provide the source code for proprietary components !<<
+ >>! outside of the FreeRTOS kernel. !<<
+ ***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. Full license text is available from the following
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
- 1 tab == 4 spaces!
-
***************************************************************************
* *
- * Having a problem? Start by reading the FAQ "My application does *
- * not run, what could be wrong?" *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
* *
- * http://www.FreeRTOS.org/FAQHelp.html *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
- http://www.FreeRTOS.org - Documentation, books, training, latest versions,
- license and Real Time Engineers Ltd. contact details.
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
- http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
- Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
- licenses offer ticketed support, indemnification and middleware.
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
@@ -84,16 +88,19 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Block sizes must not get too small. */
-#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
+#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Assumes 8bit bytes! */
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
-/* A few bytes might be lost to byte aligning the heap start address. */
-#define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
-
/* Allocate the memory for the heap. */
-static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
+#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
+ /* The application writer has already defined the array used for the RTOS
+ heap - probably so it can be placed in a special segment or address. */
+ extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
+#else
+ static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
+#endif /* configAPPLICATION_ALLOCATED_HEAP */
/* Define the linked list structure. This is used to link free blocks in order
of their memory address. */
@@ -123,18 +130,15 @@ static void prvHeapInit( void );
/* The size of the structure placed at the beginning of each allocated memory
block must by correctly byte aligned. */
-static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
-
-/* Ensure the pxEnd pointer will end up on the correct byte alignment. */
-static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
+static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, *pxEnd = NULL;
/* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */
-static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
-static size_t xMinimumEverFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
+static size_t xFreeBytesRemaining = 0U;
+static size_t xMinimumEverFreeBytesRemaining = 0U;
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an BlockLink_t structure is set then the block belongs to the
@@ -172,7 +176,7 @@ void *pvReturn = NULL;
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
- xWantedSize += heapSTRUCT_SIZE;
+ xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number
of bytes. */
@@ -180,6 +184,7 @@ void *pvReturn = NULL;
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
+ configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
}
else
{
@@ -209,7 +214,7 @@ void *pvReturn = NULL;
{
/* Return the memory space pointed to - jumping over the
BlockLink_t structure at its start. */
- pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
+ pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out
of the list of free blocks. */
@@ -224,6 +229,7 @@ void *pvReturn = NULL;
cast is used to prevent byte alignment warnings from the
compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
+ configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the
single block. */
@@ -231,7 +237,7 @@ void *pvReturn = NULL;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
- prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
+ prvInsertBlockIntoFreeList( pxNewBlockLink );
}
else
{
@@ -271,7 +277,7 @@ void *pvReturn = NULL;
traceMALLOC( pvReturn, xWantedSize );
}
- xTaskResumeAll();
+ ( void ) xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
@@ -287,6 +293,7 @@ void *pvReturn = NULL;
}
#endif
+ configASSERT( ( ( ( uint32_t ) pvReturn ) & portBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn;
}
/*-----------------------------------------------------------*/
@@ -300,7 +307,7 @@ BlockLink_t *pxLink;
{
/* The memory being freed will have an BlockLink_t structure immediately
before it. */
- puc -= heapSTRUCT_SIZE;
+ puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
@@ -322,9 +329,9 @@ BlockLink_t *pxLink;
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
- prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
+ prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
}
- xTaskResumeAll();
+ ( void ) xTaskResumeAll();
}
else
{
@@ -360,10 +367,21 @@ void vPortInitialiseBlocks( void )
static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
-uint8_t *pucHeapEnd, *pucAlignedHeap;
+uint8_t *pucAlignedHeap;
+size_t uxAddress;
+size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */
- pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );
+ uxAddress = ( size_t ) ucHeap;
+
+ if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
+ {
+ uxAddress += ( portBYTE_ALIGNMENT - 1 );
+ uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
+ xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
+ }
+
+ pucAlignedHeap = ( uint8_t * ) uxAddress;
/* xStart is used to hold a pointer to the first item in the list of free
blocks. The void cast is used to prevent compiler warnings. */
@@ -372,21 +390,22 @@ uint8_t *pucHeapEnd, *pucAlignedHeap;
/* pxEnd is used to mark the end of the list of free blocks and is inserted
at the end of the heap space. */
- pucHeapEnd = pucAlignedHeap + xTotalHeapSize;
- pucHeapEnd -= heapSTRUCT_SIZE;
- pxEnd = ( void * ) pucHeapEnd;
- configASSERT( ( ( ( uint32_t ) pxEnd ) & ( ( uint32_t ) portBYTE_ALIGNMENT_MASK ) ) == 0UL );
+ uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
+ uxAddress -= xHeapStructSize;
+ uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
+ pxEnd = ( void * ) uxAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
- pxFirstFreeBlock->xBlockSize = xTotalHeapSize - heapSTRUCT_SIZE;
+ pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
- /* The heap now contains pxEnd. */
- xFreeBytesRemaining -= heapSTRUCT_SIZE;
+ /* Only one block exists - and it covers the entire usable heap space. */
+ xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
+ xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );