int ICACHE_FLASH_ATTR dhsender_queue_add(REQUEST_TYPE type, REQUEST_NOTIFICATION_TYPE notification_type, REQUEST_DATA_TYPE data_type, unsigned int id, va_list ap) {
	ETS_INTR_LOCK();
	if(mQueueAddPos == mQueueTakePos) {
		ETS_INTR_UNLOCK();
		dhdebug("ERROR: no space for request");
		return 0;
	}
	mQueue[mQueueAddPos].id = id;
	mQueue[mQueueAddPos].type = type;
	mQueue[mQueueAddPos].data_type = data_type;
	mQueue[mQueueAddPos].notification_type = notification_type;
	dhsender_data_parse_va(ap, &data_type, &mQueue[mQueueAddPos].data,
			&mQueue[mQueueAddPos].data_len, &mQueue[mQueueAddPos].pin);
	if(mQueueTakePos < 0)
		mQueueTakePos = mQueueAddPos;
	if(mQueueAddPos >= mQueueMaxSize - 1)
		mQueueAddPos = 0;
	else
		mQueueAddPos++;
	mQueueSize++;
	if(mQueueSize > RESERVE_FOR_RESPONCE)
		dhmem_block();
	ETS_INTR_UNLOCK();
	return 1;
}
UP_STATUS ICACHE_FLASH_ATTR uploadable_page_put(const char *data, unsigned int data_len) {
    if(mBuffer == NULL)
        return UP_STATUS_WRONG_CALL;
    if(mFlashingSector > UPLOADABLE_PAGE_END_SECTOR)
        return UP_STATUS_OVERFLOW;
    reset_timer();

    ETS_INTR_LOCK();
    while(data_len) {
        uint32_t tocopy = (data_len > (SPI_FLASH_SEC_SIZE - mBufferPos)) ?
                          (SPI_FLASH_SEC_SIZE - mBufferPos): data_len;
        os_memcpy(&mBuffer[mBufferPos], data, tocopy);
        mBufferPos += tocopy;
        data_len -= tocopy;
        data += tocopy;
        if(mBufferPos == SPI_FLASH_SEC_SIZE) {
            SpiFlashOpResult res = flash_data();
            mBufferPos = 0;
            if(res != SPI_FLASH_RESULT_OK) {
                ETS_INTR_UNLOCK();
                dhdebug("Error while writing page at 0x%X",
                        mFlashingSector * SPI_FLASH_SEC_SIZE);
                return UP_STATUS_INTERNAL_ERROR;
            }
        }
    }
    ETS_INTR_UNLOCK();
    return UP_STATUS_OK;
}
UP_STATUS ICACHE_FLASH_ATTR uploadable_page_finish() {
    if(mBuffer == NULL)
        return UP_STATUS_WRONG_CALL;
    os_timer_disarm(&mFlashingTimer);
    ETS_INTR_LOCK();
    // Mark data with null terminated char. If data takes whole available space,
    // there is no need in null terminated char.
    // At this point buffer should have at lest 1 free byte, since buffer
    // reaches maximum size before, it had to be written to flash.
    // If nothing was written, just report ok.
    SpiFlashOpResult res = SPI_FLASH_RESULT_OK;
    if(mBufferPos) {
        mBuffer[mBufferPos] = 0;
        mBufferPos++;
        res = flash_data();
    } else if(mFlashingSector > UPLOADABLE_PAGE_START_SECTOR &&
              mFlashingSector <= UPLOADABLE_PAGE_END_SECTOR) {
        res = write_zero_byte(mFlashingSector);
    }
    mBufferPos = 0;
    os_free(mBuffer);
    mBuffer = NULL;
    // force to recalc page size
    mPageLength = 0;
    ETS_INTR_UNLOCK();
    if(res != SPI_FLASH_RESULT_OK) {
        dhdebug("Error while finishing flash page");
        return UP_STATUS_INTERNAL_ERROR;
    }
    dhdebug("Flashing page has finished successfully");
    return UP_STATUS_OK;
}
Example #4
0
void vPortFree(void *pv, const char * file, unsigned line)
#endif
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;

	if( pv != NULL )
	{
		/* The memory being freed will have an BlockLink_t structure immediately
		before it. */
		puc -= uxHeapStructSize;

		/* This casting is to keep the compiler from issuing warnings. */
		pxLink = ( void * ) puc;

		/* 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
			{
				/* 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);
				}
				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();
		}
	}
}
int ICACHE_FLASH_ATTR dhsender_queue_take(HTTP_REQUEST *out, unsigned int *is_notification) {
	if(mQueueTakePos < 0)
		return 0;
	ETS_INTR_LOCK();
	DHSENDER_QUEUE item;
	os_memcpy(&item, &mQueue[mQueueTakePos], sizeof(DHSENDER_QUEUE));
	if(mQueueTakePos >= mQueueMaxSize - 1)
		mQueueTakePos = 0;
	else
		mQueueTakePos++;
	if(mQueueAddPos == mQueueTakePos)
		mQueueTakePos = -1;
	mQueueSize--;
	ETS_INTR_UNLOCK();

	if(mQueueSize < MEM_RECOVER_THRESHOLD && dhmem_isblock())
		dhmem_unblock();

	char buf[HTTP_REQUEST_MIN_ALLOWED_PAYLOAD];
	if(dhsender_data_to_json(buf, sizeof(buf),
			item.notification_type == RNT_NOTIFICATION_GPIO, item.data_type,
			&item.data, item.data_len, item.pin) < 0) {
		snprintf(buf, sizeof(buf), "Failed to convert data to json");
		item.type = RT_RESPONCE_ERROR;
	}

	*is_notification = 0;
	switch(item.type) {
		case RT_RESPONCE_OK:
		case RT_RESPONCE_ERROR:
			dhrequest_create_update(out, item.id, (item.type == RT_RESPONCE_OK) ? STATUS_OK : STATUS_ERROR, buf);
			break;
		case RT_NOTIFICATION:
			*is_notification = 1;
			switch(item.notification_type) {
			case RNT_NOTIFICATION_GPIO:
				dhrequest_create_notification(out, "gpio/int", buf);
				break;
			case RNT_NOTIFICATION_ADC:
				dhrequest_create_notification(out, "adc/int", buf);
				break;
			case RNT_NOTIFICATION_UART:
				dhrequest_create_notification(out, "uart/int", buf);
				break;
			case RNT_NOTIFICATION_ONEWIRE:
				dhrequest_create_notification(out, "onewire/master/int", buf);
				break;
			default:
				dhdebug("ERROR: Unknown notification type of request %d", item.notification_type);
				return 0;
			}
			break;
		default:
			dhdebug("ERROR: Unknown type of request %d", item.type);
			return 0;
	}
	return 1;
}
Example #6
0
void Hardware_Timer::setCallback(InterruptCallback interrupt)
{
	ETS_INTR_LOCK();
	callback = interrupt;
	ETS_INTR_UNLOCK();

	if (!interrupt)
		stop();
}
Example #7
0
void Timer::setCallback(InterruptCallback interrupt/* = NULL*/)
{
	ETS_INTR_LOCK();
	callback = interrupt;
	delegate_func = nullptr;
	ETS_INTR_UNLOCK();

	if (!interrupt)
		stop();
}
Example #8
0
void Timer::setCallback(Delegate<void()> delegateFunction)
{
	ETS_INTR_LOCK();
	callback = nullptr;
	delegate_func = delegateFunction;
	ETS_INTR_UNLOCK();

	if (!delegateFunction)
		stop();
}
Example #9
0
void pvShowMalloc()
{
	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);
	Cache_Read_Enable_New();
//ets_printf("sh1,");
	os_printf("--------Show Malloc--------\n");
	for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) {
		char file_name[33];
		const char *file_name_printf;
//ets_printf("sh2,");
		file_name_printf = vGetFileName(file_name, pxIterator->pxNextFreeBlock->file);
		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();
	}
	os_printf("--------Free %d--------\n\n", xFreeBytesRemaining);

#if 0
	uint32 last_link = (uint32)yStart.pxNextFreeBlock;
	uint32 index = 0;
	os_printf("'*':used, '-'free, each %d bytes\n", portBYTE_ALIGNMENT_v);
	os_printf("%x:", last_link);
	for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) {
	    uint16 i;
	    for (i = 0; i < ((uint32)pxIterator->pxNextFreeBlock - last_link) / portBYTE_ALIGNMENT_v; i++) {
	        index++;
	        os_printf("-");
	        if (index % 64 == 0) {
	            os_printf("\n%x:", (uint32)yStart.pxNextFreeBlock + index * portBYTE_ALIGNMENT_v);
	        }
	    }
	    for (i = 0; i < pxIterator->pxNextFreeBlock->xBlockSize / portBYTE_ALIGNMENT_v; i++) {
	        index++;
	        os_printf("*");
	        if (index % 64 == 0) {
	            os_printf("\n%x:", (uint32)yStart.pxNextFreeBlock + index * portBYTE_ALIGNMENT_v);
            }
	    }
	    last_link = ((uint32)pxIterator->pxNextFreeBlock + pxIterator->pxNextFreeBlock->xBlockSize);
        system_soft_wdt_feed();
    }
	os_printf("\n\n");
#endif

//ets_printf("sh4\n");
	ETS_INTR_UNLOCK();
}
Example #10
0
bool spiffs_format_internal(spiffs_config *cfg)
{
  if (cfg->phys_addr == 0)
  {
	SYSTEM_ERROR("Can't format file system, wrong address");
	return false;
  }

  u32_t sect_first, sect_last;
  sect_first = cfg->phys_addr;
  sect_first = flashmem_get_sector_of_address(sect_first);
  sect_last = cfg->phys_addr + cfg->phys_size;
  sect_last = flashmem_get_sector_of_address(sect_last);
  debugf("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
  ETS_INTR_LOCK();
  int total = sect_last - sect_first;
  int cur = 0;
  int last = -1;
  while( sect_first <= sect_last )
  {
	if(flashmem_erase_sector( sect_first++ ))
	{
		int percent = cur++ * 100 / total;
		if (percent > last)
			debugf("%d%%", percent);
		last = percent;
	}
	else
	{
		ETS_INTR_UNLOCK();
		return false;
	}
  }
  debugf("formated");
  ETS_INTR_UNLOCK();
}
Example #11
0
bool Servo::removeChannel(ServoChannel* channel)
{
	if (channels.removeElement(channel)) {
		ETS_INTR_LOCK();
		getPins();
		calcTiming();
		ETS_INTR_UNLOCK();
		if (channels.size() == 0) {
			started = false;
			hardwareTimer.stop();
		}
		return true;
	}
	return false;
}
UP_STATUS ICACHE_FLASH_ATTR uploadable_page_begin() {
    ETS_INTR_LOCK();
    if(mBuffer == NULL) {
        mBuffer = (char *)os_malloc(SPI_FLASH_SEC_SIZE);
    }
    mBufferPos = 0;
    mFlashingSector = UPLOADABLE_PAGE_START_SECTOR;
    ETS_INTR_UNLOCK();
    if(mBuffer == NULL) {
        dhdebug("No memory to initialize page flashing");
        return UP_STATUS_INTERNAL_ERROR;
    }
    reset_timer();
    dhdebug("Page flashing is initialized");
    return UP_STATUS_OK;
}
Example #13
0
bool uart_getc(char *c){
    RcvMsgBuff *pRxBuff = &(UartDev.rcv_buff);
    if(pRxBuff->pWritePos == pRxBuff->pReadPos){   // empty
        return false;
    }
    // ETS_UART_INTR_DISABLE();
    ETS_INTR_LOCK();
    *c = (char)*(pRxBuff->pReadPos);
    if (pRxBuff->pReadPos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE)) {
        pRxBuff->pReadPos = pRxBuff->pRcvMsgBuff ; 
    } else {
        pRxBuff->pReadPos++;
    }
    // ETS_UART_INTR_ENABLE();
    ETS_INTR_UNLOCK();
    return true;
}
Example #14
0
bool Servo::addChannel(ServoChannel* channel)
{
	uint8 channel_count = channels.size();
	if (channel_count > SERVO_CHANNEL_NUM_MAX) return false;
	channels.add(channel);

	ETS_INTR_LOCK();
	getPins();
	calcTiming();
	ETS_INTR_UNLOCK();

	if (!started) {
		started = true;
		hardwareTimer.initializeUs(100000,ServoTimerInt);
		hardwareTimer.startOnce();
	}
	return true;
}
Example #15
0
void vPortFree( void *pv )
{
unsigned char *puc = ( unsigned char * ) pv;
xBlockLink *pxLink;

//    printf("%s\n", __func__);
    
	if( pv != NULL )
	{
		/* The memory being freed will have an xBlockLink structure immediately
		before it. */
		puc -= heapSTRUCT_SIZE;

		/* This casting is to keep the compiler from issuing warnings. */
		pxLink = ( void * ) puc;

		/* Check the block is actually allocated. */
		configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
		configASSERT( pxLink->pxNextFreeBlock == NULL );
		
		if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
		{
			if( pxLink->pxNextFreeBlock == NULL )
			{
				/* The block is being returned to the heap - it is no longer
				allocated. */
				pxLink->xBlockSize &= ~xBlockAllocatedBit;

//				vTaskSuspendAll();
				ETS_INTR_LOCK();
				{
					/* Add this block to the list of free blocks. */
					xFreeBytesRemaining += pxLink->xBlockSize;
					prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) );
				}
//				xTaskResumeAll();
				ETS_INTR_UNLOCK();
			}
		}
	}

//	printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining);
}
LOCAL void ICACHE_FLASH_ATTR recover_led(void *arg) {
	ETS_INTR_LOCK();
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1);
	gpio_output_set(0, 0x2, 0x2, 0);
	ETS_INTR_UNLOCK();
}
Example #17
0
void *pvPortMalloc( size_t xWantedSize )
{
xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;

//    printf("%s %d %d\n", __func__, xWantedSize, xFreeBytesRemaining);

//	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 )
		{
			prvHeapInit();
		}

		/* 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 xBlockLink structure 
		is used to determine who owns the block - the application or the
		kernel, so it must be free. */
		if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
		{
			/* The wanted size is increased so it can contain a xBlockLink
			structure in addition to the requested amount of bytes. */
			if( xWantedSize > 0 )
			{
				xWantedSize += heapSTRUCT_SIZE;

				/* 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 ) );
				}
			}

			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;
				while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
				{
					pxPreviousBlock = pxBlock;
					pxBlock = pxBlock->pxNextFreeBlock;
				}

				/* If the end marker was reached then a block of adequate size 
				was	not found. */
				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 );

					/* This block is being returned for use so must be taken out 
					of the list of free blocks. */
					pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;

					/* If the block is larger than required it can be split into 
					two. */
					if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
					{
						/* This block is to be split into two.  Create a new 
						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 );

						/* 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. */
						prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
					}

					xFreeBytesRemaining -= pxBlock->xBlockSize;

					/* The block is being returned - it is allocated and owned
					by the application and has no "next" block. */
					pxBlock->xBlockSize |= xBlockAllocatedBit;
					pxBlock->pxNextFreeBlock = NULL;
				}
			}
		}
	}
//	xTaskResumeAll();
	ETS_INTR_UNLOCK();

	#if( configUSE_MALLOC_FAILED_HOOK == 1 )
	{
		if( pvReturn == NULL )
		{
			extern void vApplicationMallocFailedHook( void );
			vApplicationMallocFailedHook();
		}
	}
	#endif

//    printf("%s %x %x\n", __func__, pvReturn, pxBlock);
	return pvReturn;
}
Example #18
0
void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line, bool use_iram)
#endif
{
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;
static bool is_inited = false;

    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();
	{
		/* 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 )
		{
			/* 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 += 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 ) )
			{
				/* 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;
					pxBlock = pxBlock->pxNextFreeBlock;
				}

				/* If the end marker was reached then a block of adequate size
				was	not found. */
				if( pxBlock != pxEnd )
				{
					/* Return the memory space pointed to - jumping over the
					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. */
					pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;

					/* If the block is larger than required it can be split into
					two. */
					if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
					{
						/* This block is to be split into two.  Create a new
						block following the number of bytes requested. The void
						cast is used to prevent byte alignment warnings from the
						compiler. */
						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. */
						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
					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 );
	}
	// ( void ) xTaskResumeAll();
    ETS_INTR_UNLOCK();

	#if( configUSE_MALLOC_FAILED_HOOK == 1 )
	{
		if( pvReturn == NULL )
		{
			extern void vApplicationMallocFailedHook( void );
			vApplicationMallocFailedHook();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}
	#endif

	return pvReturn;
}