diff --git a/FreeRTOS/Source/portable/MemMang/heap_4.c b/FreeRTOS/Source/portable/MemMang/heap_4.c deleted file mode 100644 index a69a407..0000000 --- a/FreeRTOS/Source/portable/MemMang/heap_4.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - 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. - - >>! 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 - 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?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - 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.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -/* - * A sample implementation of pvPortMalloc() and vPortFree() that combines - * (coalescences) adjacent memory blocks as they are freed, and in so doing - * limits memory fragmentation. - * - * 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 - -/* 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 -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#include "FreeRTOS.h" -#include "task.h" - -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -/* Block sizes must not get too small. */ -#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) - -/* 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 unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; - -/* Define the linked list structure. This is used to link free blocks in order -of their memory address. */ -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. */ -} xBlockLink; - -/*-----------------------------------------------------------*/ - -/* - * Inserts a block of memory that is being freed into the correct position in - * the list of free memory blocks. The block being freed will be merged with - * 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 ); - -/* - * Called automatically to setup the required heap structures the first time - * pvPortMalloc() is called. - */ -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 unsigned short heapSTRUCT_SIZE = ( ( sizeof ( xBlockLink ) + ( 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 ); - -/* Create a couple of list links to mark the start and end of the list. */ -static xBlockLink 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 ); - -/* 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 -application. When the bit is free the block is still part of the free heap -space. */ -static size_t xBlockAllocatedBit = 0; - -/*-----------------------------------------------------------*/ - -void *pvPortMalloc( size_t xWantedSize ) -{ -xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; -void *pvReturn = NULL; - - vTaskSuspendAll(); - { - /* 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(); - - #if( configUSE_MALLOC_FAILED_HOOK == 1 ) - { - if( pvReturn == NULL ) - { - extern void vApplicationMallocFailedHook( void ); - vApplicationMallocFailedHook(); - } - } - #endif - - return pvReturn; -} -/*-----------------------------------------------------------*/ - -void vPortFree( void *pv ) -{ -unsigned char *puc = ( unsigned char * ) pv; -xBlockLink *pxLink; - - 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(); - { - /* Add this block to the list of free blocks. */ - xFreeBytesRemaining += pxLink->xBlockSize; - prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); - } - xTaskResumeAll(); - } - } - } -} -/*-----------------------------------------------------------*/ - -size_t xPortGetFreeHeapSize( void ) -{ - return xFreeBytesRemaining; -} -/*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ - -static void prvHeapInit( void ) -{ -xBlockLink *pxFirstFreeBlock; -unsigned char *pucHeapEnd, *pucAlignedHeap; - - /* Ensure the heap starts on a correctly aligned boundary. */ - pucAlignedHeap = ( unsigned char * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); - - /* 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; - - /* Work out the position of the top bit in a size_t variable. */ - xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); -} -/*-----------------------------------------------------------*/ - -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. */ - for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) - { - /* Nothing to do here, just iterate to the right position. */ - } - - /* 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 ) - { - pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; - pxBlockToInsert = pxIterator; - } - - /* 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 ) - { - if( pxIterator->pxNextFreeBlock != pxEnd ) - { - /* Form one big block from the two blocks. */ - pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxEnd; - } - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; - } - - /* If the block being inserted plugged a gab, so was merged with the block - before and the block after, then it's pxNextFreeBlock pointer will have - already been set, and should not be set here as that would make it point - to itself. */ - if( pxIterator != pxBlockToInsert ) - { - pxIterator->pxNextFreeBlock = pxBlockToInsert; - } -} - diff --git a/FreeRTOS/Source/portable/esp8266/sdk_compat.c b/FreeRTOS/Source/portable/esp8266/sdk_compat.c index 3b94345..f377287 100644 --- a/FreeRTOS/Source/portable/esp8266/sdk_compat.c +++ b/FreeRTOS/Source/portable/esp8266/sdk_compat.c @@ -1,5 +1,5 @@ /* - * Stub functions called by binary espressif libraries + * Wrappers for functions called by binary espressif libraries * * Part of esp-open-rtos * Copyright (C) 2015 Superhouse Automation Pty Ltd @@ -9,69 +9,6 @@ #include #include "FreeRTOS.h" -/* SDK uses errno. errno was defined in libudhcp.a - but that library has been removed. */ -int errno; - -/* newlib uses __errno in some contexts */ -int *__errno(void) { - return &errno; -} - -/* libc memory management functions. - - Many of these are linked from the RTOS SDK blob libraries. - - In esp_iot_rtos_sdk these are aliased to exception-safe versions of - the FreeRTOS functions. I think the rationale is that they're - sometimes called in exception contexts (ESPTODO: Verify this). - - For now these are exception-safe wrappers to the FreeRTOS versions. - */ - -void *malloc(size_t nbytes) { - void *res; - portENTER_CRITICAL(); - res = pvPortMalloc(nbytes); - portEXIT_CRITICAL(); - return res; -} - -void *calloc(size_t count, size_t size) { - void *res; - size_t nbytes = count * size; - portENTER_CRITICAL(); - res = pvPortMalloc(nbytes); - portEXIT_CRITICAL(); - if(res) { - memset(res, 0, nbytes); - } - return res; -} - void *zalloc(size_t nbytes) { return calloc(1, nbytes); } - -void *realloc(void *old, size_t newsize) { - void *new; - portENTER_CRITICAL(); - if(newsize == 0) { - vPortFree(old); - return 0; - } - /* realloc implementation borrowed from esp_iot_rtos_sdk, could be better I think */ - new = pvPortMalloc(newsize); - if (new) { - memcpy(new, old, newsize); - vPortFree(old); - } - portEXIT_CRITICAL(); - return new; -} - -void free(void *ptr) { - portENTER_CRITICAL(); - vPortFree(ptr); - portEXIT_CRITICAL(); -} diff --git a/FreeRTOS/component.mk b/FreeRTOS/component.mk index 2f06647..437fccb 100644 --- a/FreeRTOS/component.mk +++ b/FreeRTOS/component.mk @@ -5,5 +5,5 @@ INC_DIRS += $(freertos_MAIN)/include $(freertos_MAIN)/portable/esp8266 freertos_ROOT = $(ROOT)FreeRTOS/ freertos_MAIN = $(freertos_ROOT)Source/ freertos_INC_DIR = $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266 -freertos_SRC_DIR = $(freertos_MAIN) $(freertos_MAIN)portable/MemMang $(freertos_MAIN)portable/esp8266 +freertos_SRC_DIR = $(freertos_MAIN) $(freertos_MAIN)portable/esp8266 $(eval $(call component_compile_rules,freertos)) diff --git a/core/newlib_syscalls.c b/core/newlib_syscalls.c new file mode 100644 index 0000000..f28eff0 --- /dev/null +++ b/core/newlib_syscalls.c @@ -0,0 +1,71 @@ +/* newlib_syscalls.c - newlib syscalls for ESP8266 + * + * Part of esp-open-rtos + * Copyright (C) 2105 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include +#include + +caddr_t _sbrk_r (struct _reent *r, int incr) +{ + extern char _heap_start; /* linker script defined */ + static char * heap_end; + char * prev_heap_end; + + if (heap_end == NULL) + heap_end = &_heap_start; + prev_heap_end = heap_end; + /* TODO: Check stack collision + if (heap_end + incr > stack_ptr) + { + _write (1, "_sbrk: Heap collided with stack\n", 32); + while(1) {} + } + */ + heap_end += incr; + + return (caddr_t) prev_heap_end; +} + +/* syscall implementation for stdio write to UART + + at the moment UART functionality is all still in the binary SDK + */ +long _write_r(struct _reent *r, int fd, const char *ptr, int len ) +{ + for(int i = 0; i < len; i++) + sdk_os_putc(ptr[i]); + return len; +} + +/* syscall implementation for stdio read from UART + + at the moment UART functionality is all still in the binary SDK + */ +long _read_r( struct _reent *r, int fd, char *ptr, int len ) +{ + for(int i = 0; i < len; i++) + ptr[i] = sdk_uart_rx_one_char(); + return len; +} + +/* These are stub implementations for the reentrant syscalls that + * newlib is configured to expect */ +int _fstat_r(struct _reent *r, int fd, void *buf) +{ + return -1; +} + +int _close_r(struct _reent *r, int fd) +{ + return -1; +} + +off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence) +{ + return (off_t)-1; +} + diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index e3c9232..1be1ca6 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -3,6 +3,21 @@ Modified for esp open RTOS, this linker script is no longer the same as the esp_iot_rtos_sdk one. */ +/* FreeRTOS memory management functions + + We link these directly to newlib functions (have to do it at link + time as binary libraries use these symbols too.) +*/ +pvPortMalloc = malloc; +vPortFree = free; + +_lock_acquire = vPortEnterCritical; +_lock_acquire_recursive = vPortEnterCritical; +_lock_try_acquire = vPortEnterCritical; +_lock_try_acquire_recursive = vPortEnterCritical; +_lock_release = vPortExitCritical; +_lock_release_recursive = vPortExitCritical; + /* Linker Script for ld -N */ MEMORY { @@ -156,7 +171,7 @@ SECTIONS *(COMMON) . = ALIGN (8); _bss_end = ABSOLUTE(.); - _heap_start = ABSOLUTE(.); /* ESPTODO: Remove this symbol */ + _heap_start = ABSOLUTE(.); /* _stack_sentry = ALIGN(0x8); */ } >dram0_0_seg :dram0_0_bss_phdr /* __stack = 0x3ffc8000; */