feat(system): Provide more heap region (16KB+)

1. Change cache size from 32KB to 16KB, reverse this 16KB region as heap;
2. New heap to support seperate heap region;
3. Modify pvPortMalloc, support to choose malloc in iram;
4. Add new macro os_malloc_iram to malloc in iram;
5. Default malloc will malloc in iram firstly;

Limitation:
1. Don't malloc task stack in iram;
2. Dont't use iram buffer as wifi tx buffer;

If possible, use all of iram heap region firstly.

internal : 2d3fbebb
This commit is contained in:
Espressif Systems
2017-12-08 14:02:57 +08:00
parent b6ddeca472
commit 2e89983282
24 changed files with 909 additions and 725 deletions

22
VERSION
View File

@ -1,14 +1,20 @@
gwen:
espnow: 1aafc07
main: caff253
mesh: 1aafc07
net80211: caff253
pp: caff253
wpa: caff253
wps: 1aafc07
crypto: a8c4880
espnow: a8c4880
main: a8c4880
mesh: a8c4880
minic: a8c4880
net80211: a8c4880
pp: a8c4880
pwm: a8c4880
smartconfig:a8c4880
wpa: a8c4880
wps: a8c4880
gitlab:
espconn: 3a998034
lwip: 2235ad17
freertos: ac047746
lwip: ac047746
driver: 7bee5263
mbedtls: 1ac9f1f4
ssl: eefb383a

View File

@ -126,7 +126,15 @@ do{\
#define os_malloc(s) \
({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__); \
pvPortMalloc(s, mem_debug_file, __LINE__, false); \
})
#endif
#ifndef os_malloc_iram
#define os_malloc_iram(s) \
({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__, true); \
})
#endif

View File

@ -368,7 +368,7 @@ extern "C" {
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
#else
void *pvPortMalloc( size_t xSize, const char *file, unsigned line) PRIVILEGED_FUNCTION;
void *pvPortMalloc( size_t xSize, const char *file, unsigned line, bool use_iram) PRIVILEGED_FUNCTION;
void vPortFree( void *pv, const char * file, unsigned line) PRIVILEGED_FUNCTION;
#endif

View File

@ -81,7 +81,7 @@ typedef size_t mem_size_t;
}while(0)
#endif
#ifndef mem_malloc
#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);})
#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__, false);})
#endif
#ifndef mem_calloc
#define mem_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);})

View File

@ -25,14 +25,14 @@
#ifdef MEMLEAK_DEBUG
extern void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line);
extern void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line, bool use_iram);
extern void *pvPortZalloc( size_t xWantedSize, const char * file, unsigned line);
extern void vPortFree(void *pv, const char * file, unsigned line);
#define ssl_mem_malloc(s) \
({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__); \
pvPortMalloc(s, mem_debug_file, __LINE__, false); \
})
#define ssl_mem_zalloc(s) \

View File

@ -94,6 +94,7 @@ SECTIONS
*(.init.literal)
*(.init)
*libfreertos.a:(.literal .text .literal.* .text.*)
*libmain.a:spi_flash.o(.literal .text .literal.* .text.*)
*(.literal .text .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
*(.fini)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,6 @@
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@ -23,10 +24,10 @@
the terms of the GNU General Public License (version 2) as published by the
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
@ -63,15 +64,48 @@
*/
/*
* A sample implementation of pvPortMalloc() and vPortFree() that combines
* (coalescences) adjacent memory blocks as they are freed, and in so doing
* limits memory fragmentation.
* A sample implementation of pvPortMalloc() that allows the heap to be defined
* across multiple non-contigous blocks and combines (coalescences) adjacent
* memory blocks as they are freed.
*
* See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative
* implementations, and the memory management pages of http://www.FreeRTOS.org
* for more information.
*
* Usage notes:
*
* vPortDefineHeapRegions() ***must*** be called before pvPortMalloc().
* pvPortMalloc() will be called if any task objects (tasks, queues, event
* groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be
* called before any other objects are defined.
*
* vPortDefineHeapRegions() takes a single parameter. The parameter is an array
* of HeapRegion_t structures. HeapRegion_t is defined in portable.h as
*
* typedef struct HeapRegion
* {
* uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap.
* size_t xSizeInBytes; << Size of the block of memory.
* } HeapRegion_t;
*
* The array is terminated using a NULL zero sized region definition, and the
* memory regions defined in the array ***must*** appear in address order from
* low address to high address. So the following is a valid example of how
* to use the function.
*
* HeapRegion_t xHeapRegions[] =
* {
* { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000
* { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000
* { NULL, 0 } << Terminates the array.
* };
*
* vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions().
*
* Note 0x80000000 is the lower address so appears in the array first.
*
* See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information.
*/
#include <stdlib.h>
#include <string.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
@ -85,23 +119,22 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#define mtCOVERAGE_TEST_MARKER()
#define traceFREE(...)
#define traceMALLOC(...)
#if 1
#define mem_printf(fmt, args...) ets_printf(fmt,## args)
#else
#define mem_printf(fmt, args...)
#endif
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0x40000000 - (uint32)&_heap_start ) )
/* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( uxHeapStructSize << 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 )
/* Define the linked list structure. This is used to link free blocks in order
of their memory address. */
typedef struct A_BLOCK_LINK
@ -109,10 +142,18 @@ typedef struct A_BLOCK_LINK
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
#ifdef MEMLEAK_DEBUG
const char *file;
unsigned line;
const char *file;
unsigned line;
#endif
} xBlockLink;
} BlockLink_t;
/* Used by heap_5.c. */
typedef struct HeapRegion
{
uint8_t *pucStartAddress;
size_t xSizeInBytes;
} HeapRegion_t;
/*-----------------------------------------------------------*/
@ -122,51 +163,43 @@ typedef struct A_BLOCK_LINK
* the block in front it and/or the block behind it if the memory blocks are
* adjacent to each other.
*/
static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert );
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
/*
* Called automatically to setup the required heap structures the first time
* pvPortMalloc() is called.
*/
static void prvHeapInit( void );
extern char _heap_start;
/*-----------------------------------------------------------*/
/* Allocate the memory for the heap. */
//static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
static unsigned char *ucHeap;
/* The size of the structure placed at the beginning of each allocated memory
block must by correctly byte aligned. */
static unsigned short heapSTRUCT_SIZE;// = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
static unsigned short portBYTE_ALIGNMENT_MASK_v;
static unsigned short portBYTE_ALIGNMENT_v;
static const uint32_t uxHeapStructSize = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
/* Create a couple of list links to mark the start and end of the list. */
static xBlockLink xStart, *pxEnd = NULL;
static BlockLink_t xStart, *pxEnd = NULL;
#ifdef MEMLEAK_DEBUG
//add by jjj, we Link the used blocks here
static xBlockLink yStart;
static BlockLink_t yStart;
static size_t yFreeBytesRemaining;
#endif
/* 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 size_t xTotalHeapSize;
/* 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 xFreeBytesRemaining;
static size_t xFreeBytesRemaining = 0;
static size_t xMinimumEverFreeBytesRemaining = 0;
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an xBlockLink structure is set then the block belongs to the
member of an BlockLink_t structure is set then the block belongs to the
application. When the bit is free the block is still part of the free heap
space. */
static size_t xBlockAllocatedBit = 0;
extern char _heap_start;
extern char _lit4_end;
static HeapRegion_t xHeapRegions[] =
{
{ NULL, 0 },
{ NULL, 0 },
{ NULL, 0 }
};
/*-----------------------------------------------------------*/
#ifdef MEMLEAK_DEBUG
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = "user_app";
#endif
@ -181,9 +214,9 @@ check_memleak_debug_enable()
#include "spi_flash.h"
//extern SpiFlashChip *flashchip;
extern SpiFlashChip flashchip;
void prvInsertBlockIntoUsedList(xBlockLink *pxBlockToInsert)
void prvInsertBlockIntoUsedList(BlockLink_t *pxBlockToInsert)
{
xBlockLink *pxIterator;
BlockLink_t *pxIterator;
for( pxIterator = &yStart; pxIterator->pxNextFreeBlock < pxBlockToInsert && pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock)
{
/* Nothing to do here. */
@ -214,9 +247,9 @@ vGetFileName(char *file_name_out, const char *file_name_in)
void pvShowMalloc()
{
xBlockLink *pxIterator;
//ets_printf("sh0:%d,%d,",heapSTRUCT_SIZE,sizeof( xBlockLink ));
if(heapSTRUCT_SIZE < sizeof( xBlockLink ))
BlockLink_t *pxIterator;
//ets_printf("sh0:%d,%d,",uxHeapStructSize,sizeof( BlockLink_t ));
if(uxHeapStructSize < sizeof( BlockLink_t ))
return;
ETS_INTR_LOCK();
Wait_SPI_Idle(&flashchip);
@ -228,7 +261,7 @@ void pvShowMalloc()
const char *file_name_printf;
//ets_printf("sh2,");
file_name_printf = vGetFileName(file_name, pxIterator->pxNextFreeBlock->file);
os_printf("F:%s\tL:%u\tmalloc %u\t@ %x\n", file_name_printf, pxIterator->pxNextFreeBlock->line, pxIterator->pxNextFreeBlock->xBlockSize, ( void * ) ( ( ( unsigned char * ) pxIterator->pxNextFreeBlock ) + heapSTRUCT_SIZE));
os_printf("F:%s\tL:%u\tmalloc %d\t@ %x\n", file_name_printf, pxIterator->pxNextFreeBlock->line, pxIterator->pxNextFreeBlock->xBlockSize - 0x80000000, ( void * ) ( ( ( unsigned char * ) pxIterator->pxNextFreeBlock ) + uxHeapStructSize));
//ets_printf("sh3,");
// ets_delay_us(2000);
system_soft_wdt_feed();
@ -268,9 +301,9 @@ void pvShowMalloc()
void system_show_malloc(void) __attribute__((alias("pvShowMalloc")));
int prvRemoveBlockFromUsedList(xBlockLink *pxBlockToRemove)
int prvRemoveBlockFromUsedList(BlockLink_t *pxBlockToRemove)
{
xBlockLink *pxIterator;
BlockLink_t *pxIterator;
for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != pxBlockToRemove && pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock)
{
/* Nothing to do here. */
@ -283,55 +316,89 @@ int prvRemoveBlockFromUsedList(xBlockLink *pxBlockToRemove)
return 0;
}
#endif
size_t xPortWantedSizeAlign(size_t xWantedSize)
{
xWantedSize += heapSTRUCT_SIZE;
/* Ensure that blocks are always aligned to the required number
of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK_v ) != 0x00 )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT_v - ( xWantedSize & portBYTE_ALIGNMENT_MASK_v ) );
}
return xWantedSize;
}
#ifndef MEMLEAK_DEBUG
void *pvPortMalloc( size_t xWantedSize )
#else
void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line)
void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line, bool use_iram)
#endif
{
xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;
static bool is_inited = false;
// printf("%s %d %d\n", __func__, xWantedSize, xFreeBytesRemaining);
if (!is_inited) {
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions );
xHeapRegions[0].pucStartAddress = ( uint8_t * )&_heap_start;
xHeapRegions[0].xSizeInBytes = (( size_t)( 0x40000000 - (uint32)&_heap_start));
xHeapRegions[1].pucStartAddress = ( uint8_t * )&_lit4_end;
xHeapRegions[1].xSizeInBytes = (( size_t)( 0x4010C000 - (uint32)&_lit4_end));
is_inited = true;
vPortDefineHeapRegions(xHeapRegions);
}
/* The heap must be initialised before the first call to
prvPortMalloc(). */
configASSERT( pxEnd );
// vTaskSuspendAll();
ETS_INTR_LOCK();
{
/* If this is the first call to malloc then the heap will require
initialisation to setup the list of free blocks. */
if( pxEnd == NULL )
/* Check the requested block size is not so large that the top bit is
set. The top bit of the block size member of the BlockLink_t structure
is used to determine who owns the block - the application or the
kernel, so it must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
prvHeapInit();
}
/* The wanted size is increased so it can contain a BlockLink_t
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize = xPortWantedSizeAlign(xWantedSize);
xWantedSize += uxHeapStructSize;
/* Ensure that blocks are always aligned to the required number
of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( ( xWantedSize > 0 ) && ( xWantedSize < xFreeBytesRemaining ) )
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
/* Traverse the list from the start (lowest address) block until
one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
BlockLink_t *pxIterator;
/* Iterate through the list until a block is found that has a higher address
than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock != 0; pxIterator = pxIterator->pxNextFreeBlock )
{
if ((line == 0 || use_iram == true) && (uint32)pxIterator->pxNextFreeBlock > 0x40000000 && pxIterator->pxNextFreeBlock->xBlockSize > xWantedSize) {
pxPreviousBlock = pxIterator;
pxBlock = pxIterator->pxNextFreeBlock;
break;
}
}
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
@ -343,8 +410,8 @@ void *pvReturn = NULL;
if( pxBlock != pxEnd )
{
/* Return the memory space pointed to - jumping over the
xBlockLink structure at its start. */
pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + uxHeapStructSize );
/* This block is being returned for use so must be taken out
of the list of free blocks. */
@ -358,97 +425,147 @@ void *pvReturn = NULL;
block following the number of bytes requested. The void
cast is used to prevent byte alignment warnings from the
compiler. */
pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize );
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
/* Calculate the sizes of two blocks split from the
single block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
//Insert the new block into the list of free blocks.
//ETS_INTR_LOCK();
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
//ETS_INTR_UNLOCK();
}
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* The block is being returned - it is allocated and owned
by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
#ifdef MEMLEAK_DEBUG
pxBlock->pxNextFreeBlock = NULL;
#endif
xFreeBytesRemaining -= pxBlock->xBlockSize;
#ifdef MEMLEAK_DEBUG
if(heapSTRUCT_SIZE >= sizeof( xBlockLink )){
if(uxHeapStructSize >= sizeof( BlockLink_t )){
pxBlock->file = file;
pxBlock->line = line;
}
//link the use block
prvInsertBlockIntoUsedList(pxBlock);
#endif
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceMALLOC( pvReturn, xWantedSize );
}
// xTaskResumeAll();
ETS_INTR_UNLOCK();
// ( void ) xTaskResumeAll();
ETS_INTR_UNLOCK();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
//extern void vApplicationMallocFailedHook( void );
//vApplicationMallocFailedHook();
ets_printf("E:M %d\n", xWantedSize);
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif
//mem_printf("%s %x\n", __func__, pvReturn);
// printf("%s %x %x\n", __func__, pvReturn, pxBlock);
return pvReturn;
}
//void *malloc(size_t nbytes) __attribute__((alias("pvPortMalloc")));
/*-----------------------------------------------------------*/
#ifndef MEMLEAK_DEBUG
void vPortFree( void *pv )
#else
void vPortFree(void *pv, const char * file, unsigned line)
#endif
{
unsigned char *puc = ( unsigned char * ) pv;
xBlockLink *pxLink;
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;
// printf("%s\n", __func__);
if( pv != NULL )
{
/* The memory being freed will have an xBlockLink structure immediately
/* The memory being freed will have an BlockLink_t structure immediately
before it. */
puc -= heapSTRUCT_SIZE;
puc -= uxHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
// vTaskSuspendAll();
ETS_INTR_LOCK();
{
#ifdef MEMLEAK_DEBUG
if(prvRemoveBlockFromUsedList(pxLink) < 0){
ets_printf("%x already freed\n", pv);
}
else
/* Check the block is actually allocated. */
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
configASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
#ifndef MEMLEAK_DEBUG
if( pxLink->pxNextFreeBlock == NULL )
#endif
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) );
}
{
/* The block is being returned to the heap - it is no longer
allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
//vTaskSuspendAll();
ETS_INTR_LOCK();
#ifdef MEMLEAK_DEBUG
if(prvRemoveBlockFromUsedList(pxLink) < 0){
ets_printf("%x already freed\n", pv);
}
// xTaskResumeAll();
ETS_INTR_UNLOCK();
else
#endif
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
}
// ( void ) xTaskResumeAll();
ETS_INTR_UNLOCK();
}
#ifndef MEMLEAK_DEBUG
else
{
mtCOVERAGE_TEST_MARKER();
}
#endif
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
// printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining);
//mem_printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining);
}
//void free(void *ptr) __attribute__((alias("vPortFree")));
/*-----------------------------------------------------------*/
#ifndef MEMLEAK_DEBUG
void *malloc(size_t nbytes) __attribute__((alias("pvPortMalloc")));
@ -512,7 +629,7 @@ void *pvPortCalloc(size_t count, size_t size, const char * file, unsigned line)
void *p;
//ets_printf("1,");
/* allocate 'count' objects of size 'size' */
p = pvPortMalloc(count * size, file, line);
p = pvPortMalloc(count * size, file, line, false);
//ets_printf("2,");
if (p) {
/* zero the memory */
@ -537,7 +654,7 @@ void *pvPortRealloc(void *mem, size_t newsize, const char *file, unsigned line)
}
void *p;
p = pvPortMalloc(newsize, file, line);
p = pvPortMalloc(newsize, file, line, false);
if (p) {
/* zero the memory */
if (mem != NULL) {
@ -552,7 +669,7 @@ void *pvPortRealloc(void *mem, size_t newsize, const char *file, unsigned line)
void *malloc(size_t nbytes)
{
//ets_printf("u_m\n");
return pvPortMalloc( nbytes, mem_debug_file, 0);
return pvPortMalloc( nbytes, mem_debug_file, 0, false);
}
void free(void *ptr)
@ -585,81 +702,25 @@ void *realloc(void *ptr, size_t nbytes) __attribute__((alias("realloc1")));
*/
#endif
size_t ICACHE_FLASH_ATTR
xPortGetFreeHeapSize( void )
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
void ICACHE_FLASH_ATTR
vPortInitialiseBlocks( void )
size_t xPortGetMinimumEverFreeHeapSize( void )
{
/* This just exists to keep the linker quiet. */
return xMinimumEverFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
static void prvHeapInit( void )
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
{
xBlockLink *pxFirstFreeBlock;
unsigned char *pucHeapEnd, *pucAlignedHeap;
BlockLink_t *pxIterator;
uint8_t *puc;
if( check_memleak_debug_enable() ){
portBYTE_ALIGNMENT_MASK_v = 0xf;
portBYTE_ALIGNMENT_v = 16;
heapSTRUCT_SIZE = ( (sizeof( xBlockLink ) + portBYTE_ALIGNMENT_MASK_v)& ~portBYTE_ALIGNMENT_MASK_v);
} else {
portBYTE_ALIGNMENT_MASK_v = 0x7;
portBYTE_ALIGNMENT_v = 8;
heapSTRUCT_SIZE = 8;
}
xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK_v );
xTotalHeapSize = xFreeBytesRemaining ;
ucHeap = &_heap_start;
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( unsigned char * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT_MASK_v ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK_v ) );
/* 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. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
/* 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( ( ( ( unsigned long ) pxEnd ) & ( ( unsigned long ) portBYTE_ALIGNMENT_MASK ) ) == 0UL );
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->pxNextFreeBlock = pxEnd;
/* The heap now contains pxEnd. */
xFreeBytesRemaining -= heapSTRUCT_SIZE;
#ifdef MEMLEAK_DEBUG
//add by jjj
yStart.pxNextFreeBlock = NULL;
yStart.xBlockSize = ( size_t ) 0;
yFreeBytesRemaining = 0;
#endif
}
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert )
{
xBlockLink *pxIterator;
unsigned char *puc;
/* Iterate through the list until a block is found that has a higher address than the block being inserted. */
/* Iterate through the list until a block is found that has a higher address
than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
@ -667,17 +728,21 @@ unsigned char *puc;
/* Do the block being inserted, and the block it is being inserted after
make a contiguous block of memory? */
puc = ( unsigned char * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( unsigned char * ) pxBlockToInsert )
puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Do the block being inserted, and the block it is being inserted before
make a contiguous block of memory? */
puc = ( unsigned char * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( unsigned char * ) pxIterator->pxNextFreeBlock )
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
@ -703,5 +768,109 @@ unsigned char *puc;
{
pxIterator->pxNextFreeBlock = pxBlockToInsert;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/*-----------------------------------------------------------*/
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )
{
BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;
uint8_t *pucAlignedHeap;
size_t xTotalRegionSize, xTotalHeapSize = 0;
uint8_t xDefinedRegions = 0;
uint32_t ulAddress;
const HeapRegion_t *pxHeapRegion;
/* Can only call once! */
configASSERT( pxEnd == NULL );
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
while( pxHeapRegion->xSizeInBytes > 0 )
{
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
/* Ensure the heap region starts on a correctly aligned boundary. */
ulAddress = ( uint32_t ) pxHeapRegion->pucStartAddress;
if( ( ulAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
{
ulAddress += ( portBYTE_ALIGNMENT - 1 );
ulAddress &= ~portBYTE_ALIGNMENT_MASK;
/* Adjust the size for the bytes lost to alignment. */
xTotalRegionSize -= ulAddress - ( uint32_t ) pxHeapRegion->pucStartAddress;
}
pucAlignedHeap = ( uint8_t * ) ulAddress;
/* Set xStart if it has not already been set. */
if( xDefinedRegions == 0 )
{
/* 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. */
xStart.pxNextFreeBlock = ( BlockLink_t * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
}
else
{
/* Should only get here if one region has already been added to the
heap. */
configASSERT( pxEnd != NULL );
/* Check blocks are passed in with increasing start addresses. */
configASSERT( ulAddress > ( uint32_t ) pxEnd );
}
/* Remember the location of the end marker in the previous region, if
any. */
pxPreviousFreeBlock = pxEnd;
/* pxEnd is used to mark the end of the list of free blocks and is
inserted at the end of the region space. */
ulAddress = ( ( uint32_t ) pucAlignedHeap ) + xTotalRegionSize;
ulAddress -= uxHeapStructSize;
ulAddress &= ~portBYTE_ALIGNMENT_MASK;
pxEnd = ( BlockLink_t * ) ulAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block in this region that is
sized to take up the entire heap region minus the space taken by the
free block structure. */
pxFirstFreeBlockInRegion = ( BlockLink_t * ) pucAlignedHeap;
pxFirstFreeBlockInRegion->xBlockSize = ulAddress - ( uint32_t ) pxFirstFreeBlockInRegion;
pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
/* If this is not the first region that makes up the entire heap space
then link the previous region to this region. */
if( pxPreviousFreeBlock != NULL )
{
pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
}
xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;
/* Move onto the next HeapRegion_t structure. */
xDefinedRegions++;
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
}
xMinimumEverFreeBytesRemaining = xTotalHeapSize;
xFreeBytesRemaining = xTotalHeapSize;
/* Check something was actually defined before it is accessed. */
configASSERT( xTotalHeapSize );
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
#ifdef MEMLEAK_DEBUG
//add by jjj
yStart.pxNextFreeBlock = NULL;
yStart.xBlockSize = ( size_t ) 0;
yFreeBytesRemaining = 0;
#endif
}

View File

@ -299,14 +299,14 @@ xQueueHandle xReturn = NULL;
/* Allocate the new queue structure. */
if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
{
pxNewQueue = ( xQUEUE * ) os_malloc( sizeof( xQUEUE ) );
pxNewQueue = ( xQUEUE * ) os_malloc_iram( sizeof( xQUEUE ) );
if( pxNewQueue != NULL )
{
/* Create the list of pointers to queue items. The queue is one byte
longer than asked for to make wrap checking easier/faster. */
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
pxNewQueue->pcHead = ( signed char * ) os_malloc( xQueueSizeInBytes );
pxNewQueue->pcHead = ( signed char * ) os_malloc_iram( xQueueSizeInBytes );
if( pxNewQueue->pcHead != NULL )
{
/* Initialise the queue members as described above where the
@ -356,7 +356,7 @@ xQueueHandle xReturn = NULL;
( void ) ucQueueType;
/* Allocate the new queue structure. */
pxNewQueue = ( xQUEUE * ) os_malloc( sizeof( xQUEUE ) );
pxNewQueue = ( xQUEUE * ) os_malloc_iram( sizeof( xQUEUE ) );
if( pxNewQueue != NULL )
{
/* Information required for priority inheritance. */

View File

@ -2486,7 +2486,7 @@ tskTCB *pxNewTCB;
/* Allocate space for the TCB. Where the memory comes from depends on
the implementation of the port malloc function. */
pxNewTCB = ( tskTCB * ) os_malloc( sizeof( tskTCB ) );
pxNewTCB = ( tskTCB * ) os_malloc_iram( sizeof( tskTCB ) );
if( pxNewTCB != NULL )
{

View File

@ -1406,7 +1406,7 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
cleanup:
if( T != NULL && ! p_eq_g )
if( T != NULL && T != grp->T )
{
for( i = 0; i < pre_len; i++ )
mbedtls_ecp_point_free( &T[i] );