├── component.mk ├── Source ├── readme.txt ├── portable │ ├── readme.txt │ ├── MemMang │ │ ├── heap_3.c │ │ ├── heap_1.c │ │ ├── heap_2.c │ │ ├── heap_4.c │ │ └── heap_5.c │ └── esp8266 │ │ ├── portmacro.h │ │ ├── xtensa_timer.h │ │ ├── xtensa_rtos.h │ │ ├── xtruntime.h │ │ ├── port.c │ │ └── xtensa_context.h ├── include │ ├── stdint.readme │ ├── projdefs.h │ ├── stack_macros.h │ ├── FreeRTOSConfig.h │ ├── portable.h │ ├── deprecated_definitions.h │ ├── mpu_wrappers.h │ ├── mpu_prototypes.h │ └── list.h ├── list.c └── croutine.c ├── README.md └── License └── license.txt /component.mk: -------------------------------------------------------------------------------- 1 | 2 | INC_DIRS += $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266 3 | 4 | # args for passing into compile rule generation 5 | freertos_MAIN = $(freertos_ROOT)Source/ 6 | freertos_INC_DIR = $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266 7 | freertos_SRC_DIR = $(freertos_MAIN) $(freertos_MAIN)portable/esp8266 8 | $(eval $(call component_compile_rules,freertos)) 9 | -------------------------------------------------------------------------------- /Source/readme.txt: -------------------------------------------------------------------------------- 1 | Each real time kernel port consists of three files that contain the core kernel 2 | components and are common to every port, and one or more files that are 3 | specific to a particular microcontroller and or compiler. 4 | 5 | + The FreeRTOS/Source directory contains the three files that are common to 6 | every port - list.c, queue.c and tasks.c. The kernel is contained within these 7 | three files. croutine.c implements the optional co-routine functionality - which 8 | is normally only used on very memory limited systems. 9 | 10 | + The FreeRTOS/Source/Portable directory contains the files that are specific to 11 | a particular microcontroller and or compiler. 12 | 13 | + The FreeRTOS/Source/include directory contains the real time kernel header 14 | files. 15 | 16 | See the readme file in the FreeRTOS/Source/Portable directory for more 17 | information. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FreeRTOS - for esp-open-rtos 2 | 3 | This is a fork of https://sourceforge.net/projects/freertos/ with support 4 | added for esp-open-rtos. 5 | 6 | The default branch is esp-open-rtos, which has the current code for 7 | esp-open-rtos. 8 | 9 | The master branch is select and periodic merges of the upstream code 10 | from the FreeRTOS SVN repo and with line endings converted to unix 11 | style. Modifications are to be kept in separate branches to make 12 | rebasing easier and so that the changes can be easily seen. 13 | 14 | The initial commit is version 7.5.2 which appears to be the base 15 | version for the ESP8266 SDK port. Some select SDK versions are 16 | maintained in the esp8266-rtos-sdk branch, and are based on the code 17 | released at https://github.com/espressif/ESP8266_RTOS_SDK and again 18 | with line endings converted to unix style and some re-organisation of 19 | the files. 20 | -------------------------------------------------------------------------------- /Source/portable/readme.txt: -------------------------------------------------------------------------------- 1 | Each real time kernel port consists of three files that contain the core kernel 2 | components and are common to every port, and one or more files that are 3 | specific to a particular microcontroller and/or compiler. 4 | 5 | 6 | + The FreeRTOS/Source/Portable/MemMang directory contains the five sample 7 | memory allocators as described on the http://www.FreeRTOS.org WEB site. 8 | 9 | + The other directories each contain files specific to a particular 10 | microcontroller or compiler, where the directory name denotes the compiler 11 | specific files the directory contains. 12 | 13 | 14 | 15 | For example, if you are interested in the [compiler] port for the [architecture] 16 | microcontroller, then the port specific files are contained in 17 | FreeRTOS/Source/Portable/[compiler]/[architecture] directory. If this is the 18 | only port you are interested in then all the other directories can be 19 | ignored. 20 | 21 | -------------------------------------------------------------------------------- /Source/include/stdint.readme: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FREERTOS_STDINT 3 | #define FREERTOS_STDINT 4 | 5 | /******************************************************************************* 6 | * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions 7 | * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be 8 | * built using compilers that do not provide their own stdint.h definition. 9 | * 10 | * To use this file: 11 | * 12 | * 1) Copy this file into the directory that contains your FreeRTOSConfig.h 13 | * header file, as that directory will already be in the compilers include 14 | * path. 15 | * 16 | * 2) Rename the copied file stdint.h. 17 | * 18 | */ 19 | 20 | typedef signed char int8_t; 21 | typedef unsigned char uint8_t; 22 | typedef short int16_t; 23 | typedef unsigned short uint16_t; 24 | typedef long int32_t; 25 | typedef unsigned long uint32_t; 26 | 27 | #endif /* FREERTOS_STDINT */ 28 | -------------------------------------------------------------------------------- /License/license.txt: -------------------------------------------------------------------------------- 1 | The FreeRTOS kernel is released under the MIT open source license, the text of 2 | which is provided below. 3 | 4 | This license covers the FreeRTOS kernel source files, which are located in the 5 | /FreeRTOS/Source directory of the official FreeRTOS kernel download. It also 6 | covers most of the source files in the demo application projects, which are 7 | located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The 8 | demo projects may also include third party software that is not part of FreeRTOS 9 | and is licensed separately to FreeRTOS. Examples of third party software 10 | includes header files provided by chip or tools vendors, linker scripts, 11 | peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS 12 | directory is either open source or distributed with permission, and is free for 13 | use. For the avoidance of doubt, refer to the comments at the top of each 14 | source file. 15 | 16 | 17 | License text: 18 | ------------- 19 | 20 | Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of 22 | this software and associated documentation files (the "Software"), to deal in 23 | the Software without restriction, including without limitation the rights to 24 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 25 | the Software, and to permit persons to whom the Software is furnished to do so, 26 | subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 33 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 34 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 35 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 36 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 | 38 | -------------------------------------------------------------------------------- /Source/portable/MemMang/heap_3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | /* 30 | * Implementation of pvPortMalloc() and vPortFree() that relies on the 31 | * compilers own malloc() and free() implementations. 32 | * 33 | * This file can only be used if the linker is configured to to generate 34 | * a heap memory area. 35 | * 36 | * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the 37 | * memory management pages of http://www.FreeRTOS.org for more information. 38 | */ 39 | 40 | #include 41 | 42 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 43 | all the API functions to use the MPU wrappers. That should only be done when 44 | task.h is included from an application file. */ 45 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 46 | 47 | #include "FreeRTOS.h" 48 | #include "task.h" 49 | 50 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 51 | 52 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 53 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 54 | #endif 55 | 56 | /*-----------------------------------------------------------*/ 57 | 58 | void *pvPortMalloc( size_t xWantedSize ) 59 | { 60 | void *pvReturn; 61 | 62 | vTaskSuspendAll(); 63 | { 64 | pvReturn = malloc( xWantedSize ); 65 | traceMALLOC( pvReturn, xWantedSize ); 66 | } 67 | ( void ) xTaskResumeAll(); 68 | 69 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 70 | { 71 | if( pvReturn == NULL ) 72 | { 73 | extern void vApplicationMallocFailedHook( void ); 74 | vApplicationMallocFailedHook(); 75 | } 76 | } 77 | #endif 78 | 79 | return pvReturn; 80 | } 81 | /*-----------------------------------------------------------*/ 82 | 83 | void vPortFree( void *pv ) 84 | { 85 | if( pv ) 86 | { 87 | vTaskSuspendAll(); 88 | { 89 | free( pv ); 90 | traceFREE( pv, 0 ); 91 | } 92 | ( void ) xTaskResumeAll(); 93 | } 94 | } 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Source/portable/MemMang/heap_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | /* 30 | * The simplest possible implementation of pvPortMalloc(). Note that this 31 | * implementation does NOT allow allocated memory to be freed again. 32 | * 33 | * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the 34 | * memory management pages of http://www.FreeRTOS.org for more information. 35 | */ 36 | #include 37 | 38 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 39 | all the API functions to use the MPU wrappers. That should only be done when 40 | task.h is included from an application file. */ 41 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 42 | 43 | #include "FreeRTOS.h" 44 | #include "task.h" 45 | 46 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 47 | 48 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 49 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 50 | #endif 51 | 52 | /* A few bytes might be lost to byte aligning the heap start address. */ 53 | #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) 54 | 55 | /* Allocate the memory for the heap. */ 56 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 57 | /* The application writer has already defined the array used for the RTOS 58 | heap - probably so it can be placed in a special segment or address. */ 59 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 60 | #else 61 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 62 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 63 | 64 | /* Index into the ucHeap array. */ 65 | static size_t xNextFreeByte = ( size_t ) 0; 66 | 67 | /*-----------------------------------------------------------*/ 68 | 69 | void *pvPortMalloc( size_t xWantedSize ) 70 | { 71 | void *pvReturn = NULL; 72 | static uint8_t *pucAlignedHeap = NULL; 73 | 74 | /* Ensure that blocks are always aligned to the required number of bytes. */ 75 | #if( portBYTE_ALIGNMENT != 1 ) 76 | { 77 | if( xWantedSize & portBYTE_ALIGNMENT_MASK ) 78 | { 79 | /* Byte alignment required. */ 80 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 81 | } 82 | } 83 | #endif 84 | 85 | vTaskSuspendAll(); 86 | { 87 | if( pucAlignedHeap == NULL ) 88 | { 89 | /* Ensure the heap starts on a correctly aligned boundary. */ 90 | pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); 91 | } 92 | 93 | /* Check there is enough room left for the allocation. */ 94 | if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && 95 | ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ 96 | { 97 | /* Return the next free byte then increment the index past this 98 | block. */ 99 | pvReturn = pucAlignedHeap + xNextFreeByte; 100 | xNextFreeByte += xWantedSize; 101 | } 102 | 103 | traceMALLOC( pvReturn, xWantedSize ); 104 | } 105 | ( void ) xTaskResumeAll(); 106 | 107 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 108 | { 109 | if( pvReturn == NULL ) 110 | { 111 | extern void vApplicationMallocFailedHook( void ); 112 | vApplicationMallocFailedHook(); 113 | } 114 | } 115 | #endif 116 | 117 | return pvReturn; 118 | } 119 | /*-----------------------------------------------------------*/ 120 | 121 | void vPortFree( void *pv ) 122 | { 123 | /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and 124 | heap_4.c for alternative implementations, and the memory management pages of 125 | http://www.FreeRTOS.org for more information. */ 126 | ( void ) pv; 127 | 128 | /* Force an assert as it is invalid to call this function. */ 129 | configASSERT( pv == NULL ); 130 | } 131 | /*-----------------------------------------------------------*/ 132 | 133 | void vPortInitialiseBlocks( void ) 134 | { 135 | /* Only required when static memory is not cleared. */ 136 | xNextFreeByte = ( size_t ) 0; 137 | } 138 | /*-----------------------------------------------------------*/ 139 | 140 | size_t xPortGetFreeHeapSize( void ) 141 | { 142 | return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); 143 | } 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /Source/include/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef PROJDEFS_H 29 | #define PROJDEFS_H 30 | 31 | /* 32 | * Defines the prototype to which task functions must conform. Defined in this 33 | * file to ensure the type is known before portable.h is included. 34 | */ 35 | typedef void (*TaskFunction_t)( void * ); 36 | 37 | /* Converts a time in milliseconds to a time in ticks. This macro can be 38 | overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 39 | definition here is not suitable for your application. */ 40 | #ifndef pdMS_TO_TICKS 41 | #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) 42 | #endif 43 | 44 | #define pdFALSE ( ( BaseType_t ) 0 ) 45 | #define pdTRUE ( ( BaseType_t ) 1 ) 46 | 47 | #define pdPASS ( pdTRUE ) 48 | #define pdFAIL ( pdFALSE ) 49 | #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) 50 | #define errQUEUE_FULL ( ( BaseType_t ) 0 ) 51 | 52 | /* FreeRTOS error definitions. */ 53 | #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) 54 | #define errQUEUE_BLOCKED ( -4 ) 55 | #define errQUEUE_YIELD ( -5 ) 56 | 57 | /* Macros used for basic data corruption checks. */ 58 | #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 59 | #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 60 | #endif 61 | 62 | #if( configUSE_16_BIT_TICKS == 1 ) 63 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a 64 | #else 65 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL 66 | #endif 67 | 68 | /* The following errno values are used by FreeRTOS+ components, not FreeRTOS 69 | itself. */ 70 | #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ 71 | #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ 72 | #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ 73 | #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ 74 | #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ 75 | #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ 76 | #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ 77 | #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ 78 | #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ 79 | #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ 80 | #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ 81 | #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ 82 | #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ 83 | #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ 84 | #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ 85 | #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ 86 | #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ 87 | #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ 88 | #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ 89 | #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ 90 | #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ 91 | #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ 92 | #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ 93 | #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ 94 | #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ 95 | #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ 96 | #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ 97 | #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 98 | #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ 99 | #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ 100 | #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ 101 | #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ 102 | #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ 103 | #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ 104 | #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ 105 | #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ 106 | #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ 107 | #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ 108 | #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ 109 | #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ 110 | 111 | /* The following endian values are used by FreeRTOS+ components, not FreeRTOS 112 | itself. */ 113 | #define pdFREERTOS_LITTLE_ENDIAN 0 114 | #define pdFREERTOS_BIG_ENDIAN 1 115 | 116 | /* Re-defining endian values for generic naming. */ 117 | #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN 118 | #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN 119 | 120 | 121 | #endif /* PROJDEFS_H */ 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /Source/portable/esp8266/portmacro.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #ifndef PORTMACRO_H 30 | #define PORTMACRO_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include "esp8266.h" 37 | #include "espressif/esp8266/ets_sys.h" 38 | #include 39 | #include "xtensa_rtos.h" 40 | #include 41 | 42 | /*----------------------------------------------------------- 43 | * Port specific definitions for ESP8266 44 | * 45 | * The settings in this file configure FreeRTOS correctly for the 46 | * given hardware and compiler. 47 | * 48 | * These settings should not be altered. 49 | *----------------------------------------------------------- 50 | */ 51 | 52 | /* Type definitions. */ 53 | #define portCHAR char 54 | #define portFLOAT float 55 | #define portDOUBLE double 56 | #define portLONG long 57 | #define portSHORT short 58 | #define portSTACK_TYPE uint32_t 59 | #define portBASE_TYPE long 60 | 61 | typedef portSTACK_TYPE StackType_t; 62 | typedef portBASE_TYPE BaseType_t; 63 | typedef unsigned portBASE_TYPE UBaseType_t; 64 | 65 | typedef uint32_t TickType_t; 66 | #define portMAX_DELAY ( TickType_t ) 0xffffffffUL 67 | 68 | /* Architecture specifics. */ 69 | #define portSTACK_GROWTH ( -1 ) 70 | #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) 71 | #define portBYTE_ALIGNMENT 8 72 | /*-----------------------------------------------------------*/ 73 | 74 | enum SVC_ReqType { 75 | SVC_Software = 1, 76 | SVC_MACLayer = 2, 77 | }; 78 | 79 | /* Scheduler utilities. */ 80 | void PendSV(enum SVC_ReqType); 81 | #define portYIELD() PendSV(SVC_Software) 82 | 83 | /* Task utilities. */ 84 | #define portEND_SWITCHING_ISR( xSwitchRequired ) \ 85 | { \ 86 | extern void vTaskSwitchContext( void ); \ 87 | \ 88 | if( xSwitchRequired ) \ 89 | { \ 90 | vTaskSwitchContext(); \ 91 | } \ 92 | } 93 | 94 | /*-----------------------------------------------------------*/ 95 | 96 | /* NMIIrqIsOn flag is defined in libpp.a, and appears to be set when an NMI 97 | (int level 3) is currently runnning (during which time libpp.a might 98 | call back into parts of the OS?) 99 | 100 | The esp_iot_rtos_sdk disables all interrupt manipulations while this 101 | flag is set. 102 | 103 | It's also referenced from some other blob libraries (not known if 104 | read or written there). 105 | 106 | ESPTODO: It may be possible to just read the 'ps' register instead 107 | of accessing thisvariable. 108 | */ 109 | extern uint8_t sdk_NMIIrqIsOn; 110 | extern char level1_int_disabled; 111 | extern unsigned cpu_sr; 112 | 113 | /* Disable interrupts, store old ps level in global variable cpu_sr. 114 | 115 | Note: cpu_sr is also referenced by the binary SDK. 116 | 117 | Where possible (and when writing non-FreeRTOS specific code), 118 | prefer to _xt_disable_interrupts & _xt_enable_interrupts and store 119 | the ps value in a local variable - that approach is recursive-safe 120 | and generally better. 121 | 122 | The NMI must not touch the interrupt mask and it should not in 123 | regular operation, but there is a guard here just in case. 124 | */ 125 | inline static __attribute__((always_inline)) void portDISABLE_INTERRUPTS(void) 126 | { 127 | if(!sdk_NMIIrqIsOn && !level1_int_disabled) { 128 | cpu_sr = _xt_disable_interrupts(); 129 | level1_int_disabled = 1; 130 | } 131 | } 132 | 133 | inline static __attribute__((always_inline)) void portENABLE_INTERRUPTS(void) 134 | { 135 | if(!sdk_NMIIrqIsOn && level1_int_disabled) { 136 | level1_int_disabled = 0; 137 | _xt_restore_interrupts(cpu_sr); 138 | } 139 | } 140 | 141 | /* Critical section management. */ 142 | void vPortEnterCritical( void ); 143 | void vPortExitCritical( void ); 144 | 145 | #define portENTER_CRITICAL() vPortEnterCritical() 146 | #define portEXIT_CRITICAL() vPortExitCritical() 147 | 148 | /* Task function macros as described on the FreeRTOS.org WEB site. These are 149 | not necessary for to use this port. They are defined so the common demo files 150 | (which build with all the ports) will build. */ 151 | #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) 152 | #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) 153 | 154 | /* FreeRTOS API functions should not be called from the NMI handler. */ 155 | #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT(sdk_NMIIrqIsOn == 0) 156 | 157 | /*-----------------------------------------------------------*/ 158 | 159 | #ifdef __cplusplus 160 | } 161 | #endif 162 | 163 | #endif /* PORTMACRO_H */ 164 | 165 | -------------------------------------------------------------------------------- /Source/include/stack_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef STACK_MACROS_H 29 | #define STACK_MACROS_H 30 | 31 | /* 32 | * Call the stack overflow hook function if the stack of the task being swapped 33 | * out is currently overflowed, or looks like it might have overflowed in the 34 | * past. 35 | * 36 | * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 37 | * the current stack state only - comparing the current top of stack value to 38 | * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 39 | * will also cause the last few stack bytes to be checked to ensure the value 40 | * to which the bytes were set when the task was created have not been 41 | * overwritten. Note this second test does not guarantee that an overflowed 42 | * stack will always be recognised. 43 | */ 44 | 45 | /*-----------------------------------------------------------*/ 46 | 47 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) 48 | 49 | /* Only the current stack state is to be checked. */ 50 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 51 | { \ 52 | /* Is the currently saved stack pointer within the stack limit? */ \ 53 | if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ 54 | { \ 55 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 56 | } \ 57 | } 58 | 59 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 60 | /*-----------------------------------------------------------*/ 61 | 62 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) 63 | 64 | /* Only the current stack state is to be checked. */ 65 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 66 | { \ 67 | \ 68 | /* Is the currently saved stack pointer within the stack limit? */ \ 69 | if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ 70 | { \ 71 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 72 | } \ 73 | } 74 | 75 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 76 | /*-----------------------------------------------------------*/ 77 | 78 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 79 | 80 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 81 | { \ 82 | const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ 83 | const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ 84 | \ 85 | if( ( pulStack[ 0 ] != ulCheckValue ) || \ 86 | ( pulStack[ 1 ] != ulCheckValue ) || \ 87 | ( pulStack[ 2 ] != ulCheckValue ) || \ 88 | ( pulStack[ 3 ] != ulCheckValue ) ) \ 89 | { \ 90 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 91 | } \ 92 | } 93 | 94 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 95 | /*-----------------------------------------------------------*/ 96 | 97 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 98 | 99 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 100 | { \ 101 | int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ 102 | static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 103 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 104 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 105 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 106 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 107 | \ 108 | \ 109 | pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 110 | \ 111 | /* Has the extremity of the task stack ever been written over? */ \ 112 | if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 113 | { \ 114 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 115 | } \ 116 | } 117 | 118 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 119 | /*-----------------------------------------------------------*/ 120 | 121 | /* Remove stack overflow macro if not being used. */ 122 | #ifndef taskCHECK_FOR_STACK_OVERFLOW 123 | #define taskCHECK_FOR_STACK_OVERFLOW() 124 | #endif 125 | 126 | 127 | 128 | #endif /* STACK_MACROS_H */ 129 | 130 | -------------------------------------------------------------------------------- /Source/portable/esp8266/xtensa_timer.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED. 3 | These coded instructions, statements, and computer programs are the 4 | copyrighted works and confidential proprietary information of Tensilica Inc. 5 | They may not be modified, copied, reproduced, distributed, or disclosed to 6 | third parties in any manner, medium, or form, in whole or in part, without 7 | the prior written consent of Tensilica Inc. 8 | -------------------------------------------------------------------------------- 9 | 10 | XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY 11 | 12 | This header contains definitions and macros for use primarily by Xtensa 13 | RTOS assembly coded source files. It includes and uses the Xtensa hardware 14 | abstraction layer (HAL) to deal with config specifics. It may also be 15 | included in C source files. 16 | 17 | User may edit to modify timer selection and to specify clock frequency and 18 | tick duration to match timer interrupt to the real-time tick duration. 19 | 20 | If the RTOS has no timer interrupt, then there is no tick timer and the 21 | clock frequency is irrelevant, so all of these macros are left undefined 22 | and the Xtensa core configuration need not have a timer. 23 | 24 | *******************************************************************************/ 25 | 26 | #ifndef XTENSA_TIMER_H 27 | #define XTENSA_TIMER_H 28 | 29 | #ifdef XT_RTOS_TIMER_INT /* skip all this stuff if no timer int */ 30 | 31 | #ifdef __ASSEMBLER__ 32 | #include 33 | #endif 34 | 35 | #include 36 | #include 37 | 38 | #include "xtensa_rtos.h" /* in case this wasn't included directly */ 39 | 40 | 41 | /* 42 | Select timer to use for periodic tick, and determine its interrupt number 43 | and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, 44 | in which case its validity is checked (it must exist in this core and must 45 | not be on a high priority interrupt - an error will be reported in invalid). 46 | Otherwise select the first low or medium priority interrupt timer available. 47 | */ 48 | #ifndef XT_TIMER_INDEX 49 | #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED 50 | #if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL 51 | #undef XT_TIMER_INDEX 52 | #define XT_TIMER_INDEX 3 53 | #endif 54 | #endif 55 | #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED 56 | #if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL 57 | #undef XT_TIMER_INDEX 58 | #define XT_TIMER_INDEX 2 59 | #endif 60 | #endif 61 | #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED 62 | #if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL 63 | #undef XT_TIMER_INDEX 64 | #define XT_TIMER_INDEX 1 65 | #endif 66 | #endif 67 | #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED 68 | #if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL 69 | #undef XT_TIMER_INDEX 70 | #define XT_TIMER_INDEX 0 71 | #endif 72 | #endif 73 | #endif 74 | #ifndef XT_TIMER_INDEX 75 | #error "There is no suitable timer in this Xtensa configuration." 76 | #endif 77 | 78 | #define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX) 79 | #define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX) 80 | #define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM) 81 | #define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM) 82 | 83 | #if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED 84 | #error "The timer selected by XT_TIMER_INDEX does not exist in this core." 85 | #elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL 86 | #error "The timer interrupt cannot be high priority (use medium or low)." 87 | #endif 88 | 89 | /* 90 | Set processor clock frequency, used to determine clock divisor for timer tick. 91 | User should BE SURE TO ADJUST THIS for the Xtensa platform being used. 92 | If using a supported board via the board-independent API defined in xtbsp.h, 93 | this may be left undefined and frequency and tick divisor will be computed 94 | and cached during run-time initialization. 95 | 96 | NOTE ON SIMULATOR: 97 | Under the Xtensa instruction set simulator, the frequency can only be estimated 98 | because it depends on the speed of the host and the version of the simulator. 99 | Also because it runs much slower than hardware, it is not possible to achieve 100 | real-time performance for most applications under the simulator. A frequency 101 | too low does not allow enough time between timer interrupts, starving threads. 102 | To obtain a more convenient but non-real-time tick duration on the simulator, 103 | compile with xt-xcc option "-DXT_SIMULATOR". 104 | Adjust this frequency to taste (it's not real-time anyway!). 105 | */ 106 | #if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ) 107 | #define XT_CLOCK_FREQ 2000000 /* 2 MHz */ 108 | #else 109 | #ifdef XT_XT2000 /* deprecated */ 110 | #define XT_CLOCK_FREQ 16500000 /* 16.5 MHz (XT2000 default) */ 111 | #else 112 | #define XT_CLOCK_FREQ 80000000 113 | #endif 114 | #endif /* XT_SIMULATOR */ 115 | 116 | #if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD) 117 | #error "XT_CLOCK_FREQ must be defined for the target platform." 118 | #endif 119 | 120 | /* 121 | Default number of timer "ticks" per second (default 100 for 10ms tick). 122 | RTOS may define this in its own way (if applicable) in xtensa_rtos.h. 123 | User may redefine this to an optimal value for the application, either by 124 | editing this here or in xtensa_rtos.h, or compiling with xt-xcc option 125 | "-DXT_TICKS_PER_SEC " where is a suitable number. 126 | */ 127 | #ifndef XT_TICK_PER_SEC 128 | #define XT_TICK_PER_SEC 100 /* 10 ms tick = 100 ticks per second */ 129 | #endif 130 | 131 | /* 132 | Derviation of clock divisor for timer tick and interrupt (one per tick). 133 | */ 134 | #ifdef XT_CLOCK_FREQ 135 | #define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC) 136 | #else 137 | #ifndef __ASSEMBLER__ 138 | extern unsigned _xt_tick_divisor; 139 | extern void _xt_tick_divisor_init(void); 140 | #endif 141 | #define XT_TICK_DIVISOR _xt_tick_divisor 142 | #endif 143 | 144 | #endif /* XT_RTOS_TIMER_INT */ 145 | #endif /* XTENSA_TIMER_H */ 146 | 147 | -------------------------------------------------------------------------------- /Source/include/FreeRTOSConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | #ifndef __DEFAULT_FREERTOS_CONFIG_H 30 | #define __DEFAULT_FREERTOS_CONFIG_H 31 | 32 | /*----------------------------------------------------------- 33 | * Application specific definitions. 34 | * 35 | * These definitions should be adjusted for your particular hardware and 36 | * application requirements. 37 | * 38 | * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE 39 | * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 40 | * 41 | * See http://www.freertos.org/a00110.html. 42 | *----------------------------------------------------------*/ 43 | #ifndef configUSE_PREEMPTION 44 | #define configUSE_PREEMPTION 1 45 | #endif 46 | #ifndef configUSE_IDLE_HOOK 47 | #define configUSE_IDLE_HOOK 0 48 | #endif 49 | #ifndef configUSE_TICK_HOOK 50 | #define configUSE_TICK_HOOK 0 51 | #endif 52 | #ifndef configCPU_CLOCK_HZ 53 | /* This is the _default_ clock speed for the CPU. Can be either 80MHz 54 | * or 160MHz, and the system will set the clock speed to match at startup. 55 | * 56 | * Note that it's possible to change the clock speed at runtime, so you 57 | * can/should use sdk_system_get_cpu_frequency() in order to determine the 58 | * current CPU frequency, in preference to this macro. 59 | */ 60 | #define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 ) 61 | #endif 62 | #ifndef configTICK_RATE_HZ 63 | #define configTICK_RATE_HZ ( ( TickType_t ) 100 ) 64 | #endif 65 | #ifndef configMAX_PRIORITIES 66 | #define configMAX_PRIORITIES ( 15 ) 67 | #endif 68 | #ifndef configMINIMAL_STACK_SIZE 69 | #define configMINIMAL_STACK_SIZE ( ( unsigned short )256 ) 70 | #endif 71 | #ifndef configTOTAL_HEAP_SIZE 72 | #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) ) 73 | #endif 74 | #ifndef configMAX_TASK_NAME_LEN 75 | #define configMAX_TASK_NAME_LEN ( 16 ) 76 | #endif 77 | #ifndef configUSE_TRACE_FACILITY 78 | #define configUSE_TRACE_FACILITY 0 79 | #endif 80 | #ifndef configUSE_STATS_FORMATTING_FUNCTIONS 81 | #define configUSE_STATS_FORMATTING_FUNCTIONS 0 82 | #endif 83 | #ifndef configUSE_16_BIT_TICKS 84 | #define configUSE_16_BIT_TICKS 0 85 | #endif 86 | #ifndef configIDLE_SHOULD_YIELD 87 | #define configIDLE_SHOULD_YIELD 1 88 | #endif 89 | 90 | #ifndef INCLUDE_xTaskGetIdleTaskHandle 91 | #define INCLUDE_xTaskGetIdleTaskHandle 1 92 | #endif 93 | #ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle 94 | #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 95 | #endif 96 | 97 | #ifndef configCHECK_FOR_STACK_OVERFLOW 98 | #define configCHECK_FOR_STACK_OVERFLOW 2 99 | #endif 100 | #ifndef configUSE_RECURSIVE_MUTEXES 101 | #define configUSE_RECURSIVE_MUTEXES 1 102 | #endif 103 | #ifndef configUSE_MUTEXES 104 | #define configUSE_MUTEXES 1 105 | #endif 106 | #ifndef configUSE_TIMERS 107 | #define configUSE_TIMERS 1 108 | #endif 109 | 110 | #if configUSE_TIMERS 111 | #ifndef configTIMER_TASK_PRIORITY 112 | #define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) 113 | #endif 114 | #ifndef configTIMER_QUEUE_LENGTH 115 | #define configTIMER_QUEUE_LENGTH (10) 116 | #endif 117 | #ifndef configTIMER_TASK_STACK_DEPTH 118 | #define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 ) 119 | #endif 120 | #endif 121 | 122 | /* Co-routine definitions. */ 123 | #ifndef configUSE_CO_ROUTINES 124 | #define configUSE_CO_ROUTINES 0 125 | #endif 126 | #ifndef configMAX_CO_ROUTINE_PRIORITIES 127 | #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) 128 | #endif 129 | 130 | #ifndef configUSE_NEWLIB_REENTRANT 131 | #define configUSE_NEWLIB_REENTRANT 1 132 | #endif 133 | 134 | /* Set the following definitions to 1 to include the API function, or zero 135 | to exclude the API function. */ 136 | #ifndef INCLUDE_vTaskPrioritySet 137 | #define INCLUDE_vTaskPrioritySet 1 138 | #endif 139 | #ifndef INCLUDE_uxTaskPriorityGet 140 | #define INCLUDE_uxTaskPriorityGet 1 141 | #endif 142 | #ifndef INCLUDE_vTaskDelete 143 | #define INCLUDE_vTaskDelete 1 144 | #endif 145 | #ifndef INCLUDE_vTaskCleanUpResource 146 | #define INCLUDE_vTaskCleanUpResources 0 147 | #endif 148 | #ifndef INCLUDE_vTaskSuspend 149 | #define INCLUDE_vTaskSuspend 1 150 | #endif 151 | #ifndef INCLUDE_vTaskDelayUntil 152 | #define INCLUDE_vTaskDelayUntil 1 153 | #endif 154 | #ifndef INCLUDE_vTaskDelay 155 | #define INCLUDE_vTaskDelay 1 156 | #endif 157 | 158 | /*set the #define for debug info*/ 159 | #ifndef INCLUDE_xTaskGetCurrentTaskHandle 160 | #define INCLUDE_xTaskGetCurrentTaskHandle 1 161 | #endif 162 | #ifndef INCLUDE_uxTaskGetStackHighWaterMark 163 | #define INCLUDE_uxTaskGetStackHighWaterMark 1 164 | #endif 165 | 166 | #ifndef configENABLE_BACKWARD_COMPATIBILITY 167 | #define configENABLE_BACKWARD_COMPATIBILITY 0 168 | #endif 169 | 170 | /* Normal assert() semantics without relying on the provision of an assert.h 171 | header file. */ 172 | void vAssertCalled(const char * pcFile, unsigned long ulLine); 173 | #define configASSERT(x) if((x) == 0) vAssertCalled(__FILE__, __LINE__); 174 | 175 | #endif /* __DEFAULT_FREERTOS_CONFIG_H */ 176 | 177 | -------------------------------------------------------------------------------- /Source/include/portable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /*----------------------------------------------------------- 29 | * Portable layer API. Each function must be defined for each port. 30 | *----------------------------------------------------------*/ 31 | 32 | #ifndef PORTABLE_H 33 | #define PORTABLE_H 34 | 35 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 36 | pre-processor definition was used to ensure the pre-processor found the correct 37 | portmacro.h file for the port being used. That scheme was deprecated in favour 38 | of setting the compiler's include path such that it found the correct 39 | portmacro.h file - removing the need for the constant and allowing the 40 | portmacro.h file to be located anywhere in relation to the port being used. 41 | Purely for reasons of backward compatibility the old method is still valid, but 42 | to make it clear that new projects should not use it, support for the port 43 | specific constants has been moved into the deprecated_definitions.h header 44 | file. */ 45 | #include "deprecated_definitions.h" 46 | 47 | /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h 48 | did not result in a portmacro.h header file being included - and it should be 49 | included here. In this case the path to the correct portmacro.h header file 50 | must be set in the compiler's include path. */ 51 | #ifndef portENTER_CRITICAL 52 | #include "portmacro.h" 53 | #endif 54 | 55 | #if portBYTE_ALIGNMENT == 32 56 | #define portBYTE_ALIGNMENT_MASK ( 0x001f ) 57 | #endif 58 | 59 | #if portBYTE_ALIGNMENT == 16 60 | #define portBYTE_ALIGNMENT_MASK ( 0x000f ) 61 | #endif 62 | 63 | #if portBYTE_ALIGNMENT == 8 64 | #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) 65 | #endif 66 | 67 | #if portBYTE_ALIGNMENT == 4 68 | #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) 69 | #endif 70 | 71 | #if portBYTE_ALIGNMENT == 2 72 | #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) 73 | #endif 74 | 75 | #if portBYTE_ALIGNMENT == 1 76 | #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) 77 | #endif 78 | 79 | #ifndef portBYTE_ALIGNMENT_MASK 80 | #error "Invalid portBYTE_ALIGNMENT definition" 81 | #endif 82 | 83 | #ifndef portNUM_CONFIGURABLE_REGIONS 84 | #define portNUM_CONFIGURABLE_REGIONS 1 85 | #endif 86 | 87 | #ifdef __cplusplus 88 | extern "C" { 89 | #endif 90 | 91 | #include "mpu_wrappers.h" 92 | 93 | /* 94 | * Setup the stack of a new task so it is ready to be placed under the 95 | * scheduler control. The registers have to be placed on the stack in 96 | * the order that the port expects to find them. 97 | * 98 | */ 99 | #if( portUSING_MPU_WRAPPERS == 1 ) 100 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; 101 | #else 102 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; 103 | #endif 104 | 105 | /* Used by heap_5.c. */ 106 | typedef struct HeapRegion 107 | { 108 | uint8_t *pucStartAddress; 109 | size_t xSizeInBytes; 110 | } HeapRegion_t; 111 | 112 | /* 113 | * Used to define multiple heap regions for use by heap_5.c. This function 114 | * must be called before any calls to pvPortMalloc() - not creating a task, 115 | * queue, semaphore, mutex, software timer, event group, etc. will result in 116 | * pvPortMalloc being called. 117 | * 118 | * pxHeapRegions passes in an array of HeapRegion_t structures - each of which 119 | * defines a region of memory that can be used as the heap. The array is 120 | * terminated by a HeapRegions_t structure that has a size of 0. The region 121 | * with the lowest start address must appear first in the array. 122 | */ 123 | void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; 124 | 125 | 126 | /* 127 | * Map to the memory management routines required for the port. 128 | */ 129 | void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; 130 | void vPortFree( void *pv ) PRIVILEGED_FUNCTION; 131 | void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; 132 | size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; 133 | size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; 134 | 135 | /* 136 | * Setup the hardware ready for the scheduler to take control. This generally 137 | * sets up a tick interrupt and sets timers for the correct tick frequency. 138 | */ 139 | BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; 140 | 141 | /* 142 | * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so 143 | * the hardware is left in its original condition after the scheduler stops 144 | * executing. 145 | */ 146 | void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; 147 | 148 | /* 149 | * The structures and methods of manipulating the MPU are contained within the 150 | * port layer. 151 | * 152 | * Fills the xMPUSettings structure with the memory region information 153 | * contained in xRegions. 154 | */ 155 | #if( portUSING_MPU_WRAPPERS == 1 ) 156 | struct xMEMORY_REGION; 157 | void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; 158 | #endif 159 | 160 | #ifdef __cplusplus 161 | } 162 | #endif 163 | 164 | #endif /* PORTABLE_H */ 165 | 166 | -------------------------------------------------------------------------------- /Source/portable/esp8266/xtensa_rtos.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED. 3 | These coded instructions, statements, and computer programs are the 4 | copyrighted works and confidential proprietary information of Tensilica Inc. 5 | They may not be modified, copied, reproduced, distributed, or disclosed to 6 | third parties in any manner, medium, or form, in whole or in part, without 7 | the prior written consent of Tensilica Inc. 8 | -------------------------------------------------------------------------------- 9 | 10 | RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES 11 | 12 | This header is the primary glue between generic Xtensa RTOS support 13 | sources and a specific RTOS port for Xtensa. It contains definitions 14 | and macros for use primarily by Xtensa assembly coded source files. 15 | 16 | Macros in this header map callouts from generic Xtensa files to specific 17 | RTOS functions. It may also be included in C source files. 18 | 19 | Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa 20 | architecture, using the Xtensa hardware abstraction layer (HAL) to deal 21 | with configuration specifics. 22 | 23 | Should be included by all Xtensa generic and RTOS port-specific sources. 24 | 25 | *******************************************************************************/ 26 | 27 | #ifndef XTENSA_RTOS_H 28 | #define XTENSA_RTOS_H 29 | 30 | #ifdef __ASSEMBLER__ 31 | #include 32 | #else 33 | #include 34 | #endif 35 | 36 | #include 37 | #include 38 | 39 | /* 40 | Include any RTOS specific definitions that are needed by this header. 41 | */ 42 | 43 | #ifdef XCHAL_EXCM_LEVEL 44 | #undef XCHAL_EXCM_LEVEL 45 | #define XCHAL_EXCM_LEVEL 3 46 | #endif 47 | 48 | /* 49 | Name of RTOS (for messages). 50 | */ 51 | #define XT_RTOS_NAME FreeRTOS 52 | 53 | /* 54 | Check some Xtensa configuration requirements and report error if not met. 55 | Error messages can be customize to the RTOS port. 56 | */ 57 | 58 | #if !XCHAL_HAVE_XEA2 59 | #error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)." 60 | #endif 61 | 62 | 63 | /******************************************************************************* 64 | 65 | RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS. 66 | 67 | Define callout macros used in generic Xtensa code to interact with the RTOS. 68 | The macros are simply the function names for use in calls from assembler code. 69 | Some of these functions may call back to generic functions in xtensa_context.h . 70 | 71 | *******************************************************************************/ 72 | 73 | /* 74 | Inform RTOS of entry into an interrupt handler that will affect it. 75 | Allows RTOS to manage switch to any system stack and count nesting level. 76 | Called after minimal context has been saved, with interrupts disabled. 77 | RTOS port can call0 _xt_context_save to save the rest of the context. 78 | May only be called from assembly code by the 'call0' instruction. 79 | */ 80 | // void XT_RTOS_INT_ENTER(void) 81 | #define XT_RTOS_INT_ENTER _xt_int_enter 82 | 83 | /* 84 | Inform RTOS of completion of an interrupt handler, and give control to 85 | RTOS to perform thread/task scheduling, switch back from any system stack 86 | and restore the context, and return to the exit dispatcher saved in the 87 | stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore 88 | to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save, 89 | leaving only a minimal part of the context to be restored by the exit 90 | dispatcher. This function does not return to the place it was called from. 91 | May only be called from assembly code by the 'call0' instruction. 92 | */ 93 | // void XT_RTOS_INT_EXIT(void) 94 | #define XT_RTOS_INT_EXIT _xt_int_exit 95 | 96 | /* 97 | Inform RTOS of the occurrence of a tick timer interrupt. 98 | If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined. 99 | May be coded in or called from C or assembly, per ABI conventions. 100 | RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro). 101 | */ 102 | // void XT_RTOS_TIMER_INT(void) 103 | #define XT_RTOS_TIMER_INT _xt_timer_int 104 | 105 | /* 106 | Return in a15 the base address of the co-processor state save area for the 107 | thread that triggered a co-processor exception, or 0 if no thread was running. 108 | The state save area is structured as defined in xtensa_context.h and has size 109 | XT_CP_SIZE. Co-processor instructions should only be used in thread code, never 110 | in interrupt handlers or the RTOS kernel. May only be called from assembly code 111 | and by the 'call0' instruction. A result of 0 indicates an unrecoverable error. 112 | The implementation may use only a2-4, a15 (all other regs must be preserved). 113 | */ 114 | // void* XT_RTOS_CP_STATE(void) 115 | 116 | /******************************************************************************* 117 | 118 | HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL. 119 | 120 | This Xtensa RTOS port provides hooks for dynamically installing exception 121 | and interrupt handlers to facilitate automated testing where each test 122 | case can install its own handler for user exceptions and each interrupt 123 | priority (level). This consists of an array of function pointers indexed 124 | by interrupt priority, with index 0 being the user exception handler hook. 125 | Each entry in the array is initially 0, and may be replaced by a function 126 | pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0. 127 | 128 | The handler for low and medium priority obeys ABI conventions so may be coded 129 | in C. For the exception handler, the cause is the contents of the EXCCAUSE 130 | reg, and the result is -1 if handled, else the cause (still needs handling). 131 | For interrupt handlers, the cause is a mask of pending enabled interrupts at 132 | that level, and the result is the same mask with the bits for the handled 133 | interrupts cleared (those not cleared still need handling). This allows a test 134 | case to either pre-handle or override the default handling for the exception 135 | or interrupt level (see xtensa_vectors.S). 136 | 137 | High priority handlers (including NMI) must be coded in assembly, are always 138 | called by 'call0' regardless of ABI, must preserve all registers except a0, 139 | and must not use or modify the interrupted stack. The hook argument 'cause' 140 | is not passed and the result is ignored, so as not to burden the caller with 141 | saving and restoring a2 (it assumes only one interrupt per level - see the 142 | discussion in high priority interrupts in xtensa_vectors.S). The handler 143 | therefore should be coded to prototype 'void h(void)' even though it plugs 144 | into an array of handlers of prototype 'unsigned h(unsigned)'. 145 | 146 | To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'. 147 | 148 | *******************************************************************************/ 149 | 150 | #define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI) 151 | 152 | #ifndef __ASSEMBLER__ 153 | typedef unsigned (*XT_INTEXC_HOOK)(unsigned cause); 154 | extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM]; 155 | #endif 156 | 157 | 158 | /******************************************************************************* 159 | 160 | CONVENIENCE INCLUSIONS. 161 | 162 | Ensures RTOS specific files need only include this one Xtensa-generic header. 163 | These headers are included last so they can use the RTOS definitions above. 164 | 165 | *******************************************************************************/ 166 | 167 | #include "xtensa_context.h" 168 | 169 | #ifdef XT_RTOS_TIMER_INT 170 | #include "xtensa_timer.h" 171 | #endif 172 | 173 | 174 | #endif /* XTENSA_RTOS_H */ 175 | -------------------------------------------------------------------------------- /Source/include/deprecated_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef DEPRECATED_DEFINITIONS_H 29 | #define DEPRECATED_DEFINITIONS_H 30 | 31 | 32 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 33 | pre-processor definition was used to ensure the pre-processor found the correct 34 | portmacro.h file for the port being used. That scheme was deprecated in favour 35 | of setting the compiler's include path such that it found the correct 36 | portmacro.h file - removing the need for the constant and allowing the 37 | portmacro.h file to be located anywhere in relation to the port being used. The 38 | definitions below remain in the code for backward compatibility only. New 39 | projects should not use them. */ 40 | 41 | #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT 42 | #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" 43 | typedef void ( __interrupt __far *pxISR )(); 44 | #endif 45 | 46 | #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT 47 | #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" 48 | typedef void ( __interrupt __far *pxISR )(); 49 | #endif 50 | 51 | #ifdef GCC_MEGA_AVR 52 | #include "../portable/GCC/ATMega323/portmacro.h" 53 | #endif 54 | 55 | #ifdef IAR_MEGA_AVR 56 | #include "../portable/IAR/ATMega323/portmacro.h" 57 | #endif 58 | 59 | #ifdef MPLAB_PIC24_PORT 60 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 61 | #endif 62 | 63 | #ifdef MPLAB_DSPIC_PORT 64 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 65 | #endif 66 | 67 | #ifdef MPLAB_PIC18F_PORT 68 | #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" 69 | #endif 70 | 71 | #ifdef MPLAB_PIC32MX_PORT 72 | #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" 73 | #endif 74 | 75 | #ifdef _FEDPICC 76 | #include "libFreeRTOS/Include/portmacro.h" 77 | #endif 78 | 79 | #ifdef SDCC_CYGNAL 80 | #include "../../Source/portable/SDCC/Cygnal/portmacro.h" 81 | #endif 82 | 83 | #ifdef GCC_ARM7 84 | #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" 85 | #endif 86 | 87 | #ifdef GCC_ARM7_ECLIPSE 88 | #include "portmacro.h" 89 | #endif 90 | 91 | #ifdef ROWLEY_LPC23xx 92 | #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" 93 | #endif 94 | 95 | #ifdef IAR_MSP430 96 | #include "..\..\Source\portable\IAR\MSP430\portmacro.h" 97 | #endif 98 | 99 | #ifdef GCC_MSP430 100 | #include "../../Source/portable/GCC/MSP430F449/portmacro.h" 101 | #endif 102 | 103 | #ifdef ROWLEY_MSP430 104 | #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" 105 | #endif 106 | 107 | #ifdef ARM7_LPC21xx_KEIL_RVDS 108 | #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" 109 | #endif 110 | 111 | #ifdef SAM7_GCC 112 | #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" 113 | #endif 114 | 115 | #ifdef SAM7_IAR 116 | #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" 117 | #endif 118 | 119 | #ifdef SAM9XE_IAR 120 | #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" 121 | #endif 122 | 123 | #ifdef LPC2000_IAR 124 | #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" 125 | #endif 126 | 127 | #ifdef STR71X_IAR 128 | #include "..\..\Source\portable\IAR\STR71x\portmacro.h" 129 | #endif 130 | 131 | #ifdef STR75X_IAR 132 | #include "..\..\Source\portable\IAR\STR75x\portmacro.h" 133 | #endif 134 | 135 | #ifdef STR75X_GCC 136 | #include "..\..\Source\portable\GCC\STR75x\portmacro.h" 137 | #endif 138 | 139 | #ifdef STR91X_IAR 140 | #include "..\..\Source\portable\IAR\STR91x\portmacro.h" 141 | #endif 142 | 143 | #ifdef GCC_H8S 144 | #include "../../Source/portable/GCC/H8S2329/portmacro.h" 145 | #endif 146 | 147 | #ifdef GCC_AT91FR40008 148 | #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" 149 | #endif 150 | 151 | #ifdef RVDS_ARMCM3_LM3S102 152 | #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" 153 | #endif 154 | 155 | #ifdef GCC_ARMCM3_LM3S102 156 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 157 | #endif 158 | 159 | #ifdef GCC_ARMCM3 160 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 161 | #endif 162 | 163 | #ifdef IAR_ARM_CM3 164 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 165 | #endif 166 | 167 | #ifdef IAR_ARMCM3_LM 168 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 169 | #endif 170 | 171 | #ifdef HCS12_CODE_WARRIOR 172 | #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" 173 | #endif 174 | 175 | #ifdef MICROBLAZE_GCC 176 | #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" 177 | #endif 178 | 179 | #ifdef TERN_EE 180 | #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" 181 | #endif 182 | 183 | #ifdef GCC_HCS12 184 | #include "../../Source/portable/GCC/HCS12/portmacro.h" 185 | #endif 186 | 187 | #ifdef GCC_MCF5235 188 | #include "../../Source/portable/GCC/MCF5235/portmacro.h" 189 | #endif 190 | 191 | #ifdef COLDFIRE_V2_GCC 192 | #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" 193 | #endif 194 | 195 | #ifdef COLDFIRE_V2_CODEWARRIOR 196 | #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" 197 | #endif 198 | 199 | #ifdef GCC_PPC405 200 | #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" 201 | #endif 202 | 203 | #ifdef GCC_PPC440 204 | #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" 205 | #endif 206 | 207 | #ifdef _16FX_SOFTUNE 208 | #include "..\..\Source\portable\Softune\MB96340\portmacro.h" 209 | #endif 210 | 211 | #ifdef BCC_INDUSTRIAL_PC_PORT 212 | /* A short file name has to be used in place of the normal 213 | FreeRTOSConfig.h when using the Borland compiler. */ 214 | #include "frconfig.h" 215 | #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" 216 | typedef void ( __interrupt __far *pxISR )(); 217 | #endif 218 | 219 | #ifdef BCC_FLASH_LITE_186_PORT 220 | /* A short file name has to be used in place of the normal 221 | FreeRTOSConfig.h when using the Borland compiler. */ 222 | #include "frconfig.h" 223 | #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" 224 | typedef void ( __interrupt __far *pxISR )(); 225 | #endif 226 | 227 | #ifdef __GNUC__ 228 | #ifdef __AVR32_AVR32A__ 229 | #include "portmacro.h" 230 | #endif 231 | #endif 232 | 233 | #ifdef __ICCAVR32__ 234 | #ifdef __CORE__ 235 | #if __CORE__ == __AVR32A__ 236 | #include "portmacro.h" 237 | #endif 238 | #endif 239 | #endif 240 | 241 | #ifdef __91467D 242 | #include "portmacro.h" 243 | #endif 244 | 245 | #ifdef __96340 246 | #include "portmacro.h" 247 | #endif 248 | 249 | 250 | #ifdef __IAR_V850ES_Fx3__ 251 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 252 | #endif 253 | 254 | #ifdef __IAR_V850ES_Jx3__ 255 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 256 | #endif 257 | 258 | #ifdef __IAR_V850ES_Jx3_L__ 259 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 260 | #endif 261 | 262 | #ifdef __IAR_V850ES_Jx2__ 263 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 264 | #endif 265 | 266 | #ifdef __IAR_V850ES_Hx2__ 267 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 268 | #endif 269 | 270 | #ifdef __IAR_78K0R_Kx3__ 271 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 272 | #endif 273 | 274 | #ifdef __IAR_78K0R_Kx3L__ 275 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 276 | #endif 277 | 278 | #endif /* DEPRECATED_DEFINITIONS_H */ 279 | 280 | -------------------------------------------------------------------------------- /Source/portable/esp8266/xtruntime.h: -------------------------------------------------------------------------------- 1 | /* 2 | * xtruntime.h -- general C definitions for single-threaded run-time 3 | * 4 | * Copyright (c) 2002-2008 Tensilica Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files (the 8 | * "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef XTRUNTIME_H 27 | #define XTRUNTIME_H 28 | 29 | #include 30 | #include 31 | 32 | #ifndef XTSTR 33 | #define _XTSTR(x) # x 34 | #define XTSTR(x) _XTSTR(x) 35 | #endif 36 | 37 | #define _xtos_set_execption_handler _xtos_set_exception_handler /* backward compatibility */ 38 | #define _xtos_set_saved_intenable _xtos_ints_on /* backward compatibility */ 39 | #define _xtos_clear_saved_intenable _xtos_ints_off /* backward compatibility */ 40 | 41 | #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__) 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | /*typedef void (_xtos_timerdelta_func)(int);*/ 48 | #ifdef __cplusplus 49 | typedef void (_xtos_handler_func)(...); 50 | #else 51 | typedef void (_xtos_handler_func)(); 52 | #endif 53 | typedef _xtos_handler_func *_xtos_handler; 54 | 55 | /* 56 | * unsigned XTOS_SET_INTLEVEL(int intlevel); 57 | * This macro sets the current interrupt level. 58 | * The 'intlevel' parameter must be a constant. 59 | * This macro returns a 32-bit value that must be passed to 60 | * XTOS_RESTORE_INTLEVEL() to restore the previous interrupt level. 61 | * XTOS_RESTORE_JUST_INTLEVEL() also does this, but in XEA2 configs 62 | * it restores only PS.INTLEVEL rather than the entire PS register 63 | * and thus is slower. 64 | */ 65 | #if !XCHAL_HAVE_INTERRUPTS 66 | # define XTOS_SET_INTLEVEL(intlevel) 0 67 | # define XTOS_SET_MIN_INTLEVEL(intlevel) 0 68 | # define XTOS_RESTORE_INTLEVEL(restoreval) 69 | # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) 70 | #elif XCHAL_HAVE_XEA2 71 | /* In XEA2, we can simply safely set PS.INTLEVEL directly: */ 72 | /* NOTE: these asm macros don't modify memory, but they are marked 73 | * as such to act as memory access barriers to the compiler because 74 | * these macros are sometimes used to delineate critical sections; 75 | * function calls are natural barriers (the compiler does not know 76 | * whether a function modifies memory) unless declared to be inlined. */ 77 | # define XTOS_SET_INTLEVEL(intlevel) ({ unsigned __tmp; \ 78 | __asm__ __volatile__( "rsil %0, " XTSTR(intlevel) "\n" \ 79 | : "=a" (__tmp) : : "memory" ); \ 80 | __tmp;}) 81 | # define XTOS_SET_MIN_INTLEVEL(intlevel) ({ unsigned __tmp, __tmp2, __tmp3; \ 82 | __asm__ __volatile__( "rsr %0, " XTSTR(PS) "\n" /* get old (current) PS.INTLEVEL */ \ 83 | "movi %2, " XTSTR(intlevel) "\n" \ 84 | "extui %1, %0, 0, 4\n" /* keep only INTLEVEL bits of parameter */ \ 85 | "blt %2, %1, 1f\n" \ 86 | "rsil %0, " XTSTR(intlevel) "\n" \ 87 | "1:\n" \ 88 | : "=a" (__tmp), "=&a" (__tmp2), "=&a" (__tmp3) : : "memory" ); \ 89 | __tmp;}) 90 | # define XTOS_RESTORE_INTLEVEL(restoreval) do{ unsigned __tmp = (restoreval); \ 91 | __asm__ __volatile__( "wsr %0, " XTSTR(PS) " ; rsync\n" \ 92 | : : "a" (__tmp) : "memory" ); \ 93 | }while(0) 94 | # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_intlevel(restoreval) 95 | #else 96 | /* In XEA1, we have to rely on INTENABLE register virtualization: */ 97 | extern unsigned _xtos_set_vpri( unsigned vpri ); 98 | extern unsigned _xtos_vpri_enabled; /* current virtual priority */ 99 | # define XTOS_SET_INTLEVEL(intlevel) _xtos_set_vpri(~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel)) 100 | # define XTOS_SET_MIN_INTLEVEL(intlevel) _xtos_set_vpri(_xtos_vpri_enabled & ~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel)) 101 | # define XTOS_RESTORE_INTLEVEL(restoreval) _xtos_set_vpri(restoreval) 102 | # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_vpri(restoreval) 103 | #endif 104 | 105 | /* 106 | * The following macros build upon the above. They are generally used 107 | * instead of invoking the SET_INTLEVEL and SET_MIN_INTLEVEL macros directly. 108 | * They all return a value that can be used with XTOS_RESTORE_INTLEVEL() 109 | * or _xtos_restore_intlevel() or _xtos_restore_just_intlevel() to restore 110 | * the effective interrupt level to what it was before the macro was invoked. 111 | * In XEA2, the DISABLE macros are much faster than the MASK macros 112 | * (in all configs, DISABLE sets the effective interrupt level, whereas MASK 113 | * makes ensures the effective interrupt level is at least the level given 114 | * without lowering it; in XEA2 with INTENABLE virtualization, these macros 115 | * affect PS.INTLEVEL only, not the virtual priority, so DISABLE has partial 116 | * MASK semantics). 117 | * 118 | * A typical critical section sequence might be: 119 | * unsigned rval = XTOS_DISABLE_EXCM_INTERRUPTS; 120 | * ... critical section ... 121 | * XTOS_RESTORE_INTLEVEL(rval); 122 | */ 123 | /* Enable all interrupts (those activated with _xtos_ints_on()): */ 124 | #define XTOS_ENABLE_INTERRUPTS XTOS_SET_INTLEVEL(0) 125 | /* Disable low priority level interrupts (they can interact with the OS): */ 126 | #define XTOS_DISABLE_LOWPRI_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS) 127 | #define XTOS_MASK_LOWPRI_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS) 128 | /* Disable interrupts that can interact with the OS: */ 129 | #define XTOS_DISABLE_EXCM_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL) 130 | #define XTOS_MASK_EXCM_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_EXCM_LEVEL) 131 | #if 0 /* XTOS_LOCK_LEVEL is not exported to applications */ 132 | /* Disable interrupts that can interact with the OS, or manipulate virtual INTENABLE: */ 133 | #define XTOS_DISABLE_LOCK_INTERRUPTS XTOS_SET_INTLEVEL(XTOS_LOCK_LEVEL) 134 | #define XTOS_MASK_LOCK_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XTOS_LOCK_LEVEL) 135 | #endif 136 | /* Disable ALL interrupts (not for common use, particularly if one's processor 137 | * configuration has high-level interrupts and one cares about their latency): */ 138 | #define XTOS_DISABLE_ALL_INTERRUPTS XTOS_SET_INTLEVEL(15) 139 | 140 | 141 | extern unsigned int _xtos_ints_off( unsigned int mask ); 142 | extern unsigned int _xtos_ints_on( unsigned int mask ); 143 | extern unsigned _xtos_set_intlevel( int intlevel ); 144 | extern unsigned _xtos_set_min_intlevel( int intlevel ); 145 | extern unsigned _xtos_restore_intlevel( unsigned restoreval ); 146 | extern unsigned _xtos_restore_just_intlevel( unsigned restoreval ); 147 | extern _xtos_handler _xtos_set_interrupt_handler( int n, _xtos_handler f ); 148 | extern _xtos_handler _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg ); 149 | extern _xtos_handler _xtos_set_exception_handler( int n, _xtos_handler f ); 150 | 151 | extern void _xtos_memep_initrams( void ); 152 | extern void _xtos_memep_enable( int flags ); 153 | 154 | /* Deprecated (but kept because they were documented): */ 155 | extern unsigned int _xtos_read_ints( void ); /* use xthal_get_interrupt() instead */ 156 | extern void _xtos_clear_ints( unsigned int mask ); /* use xthal_set_intclear() instead */ 157 | 158 | #if XCHAL_NUM_CONTEXTS > 1 159 | extern unsigned _xtos_init_context(int context_num, int stack_size, 160 | _xtos_handler_func *start_func, int arg1); 161 | #endif 162 | 163 | /* Deprecated: */ 164 | #if XCHAL_NUM_TIMERS > 0 165 | extern void _xtos_timer_0_delta( int cycles ); 166 | #endif 167 | #if XCHAL_NUM_TIMERS > 1 168 | extern void _xtos_timer_1_delta( int cycles ); 169 | #endif 170 | #if XCHAL_NUM_TIMERS > 2 171 | extern void _xtos_timer_2_delta( int cycles ); 172 | #endif 173 | #if XCHAL_NUM_TIMERS > 3 174 | extern void _xtos_timer_3_delta( int cycles ); 175 | #endif 176 | 177 | #ifdef __cplusplus 178 | } 179 | #endif 180 | 181 | #endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */ 182 | 183 | #endif /* XTRUNTIME_H */ 184 | 185 | -------------------------------------------------------------------------------- /Source/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | #include 30 | #include "FreeRTOS.h" 31 | #include "list.h" 32 | 33 | /*----------------------------------------------------------- 34 | * PUBLIC LIST API documented in list.h 35 | *----------------------------------------------------------*/ 36 | 37 | void vListInitialise( List_t * const pxList ) 38 | { 39 | /* The list structure contains a list item which is used to mark the 40 | end of the list. To initialise the list the list end is inserted 41 | as the only list entry. */ 42 | pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 43 | 44 | /* The list end value is the highest possible value in the list to 45 | ensure it remains at the end of the list. */ 46 | pxList->xListEnd.xItemValue = portMAX_DELAY; 47 | 48 | /* The list end next and previous pointers point to itself so we know 49 | when the list is empty. */ 50 | pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 51 | pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 52 | 53 | pxList->uxNumberOfItems = ( UBaseType_t ) 0U; 54 | 55 | /* Write known values into the list if 56 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 57 | listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); 58 | listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); 59 | } 60 | /*-----------------------------------------------------------*/ 61 | 62 | void vListInitialiseItem( ListItem_t * const pxItem ) 63 | { 64 | /* Make sure the list item is not recorded as being on a list. */ 65 | pxItem->pxContainer = NULL; 66 | 67 | /* Write known values into the list item if 68 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 69 | listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 70 | listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 71 | } 72 | /*-----------------------------------------------------------*/ 73 | 74 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) 75 | { 76 | ListItem_t * const pxIndex = pxList->pxIndex; 77 | 78 | /* Only effective when configASSERT() is also defined, these tests may catch 79 | the list data structures being overwritten in memory. They will not catch 80 | data errors caused by incorrect configuration or use of FreeRTOS. */ 81 | listTEST_LIST_INTEGRITY( pxList ); 82 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 83 | 84 | /* Insert a new list item into pxList, but rather than sort the list, 85 | makes the new list item the last item to be removed by a call to 86 | listGET_OWNER_OF_NEXT_ENTRY(). */ 87 | pxNewListItem->pxNext = pxIndex; 88 | pxNewListItem->pxPrevious = pxIndex->pxPrevious; 89 | 90 | /* Only used during decision coverage testing. */ 91 | mtCOVERAGE_TEST_DELAY(); 92 | 93 | pxIndex->pxPrevious->pxNext = pxNewListItem; 94 | pxIndex->pxPrevious = pxNewListItem; 95 | 96 | /* Remember which list the item is in. */ 97 | pxNewListItem->pxContainer = pxList; 98 | 99 | ( pxList->uxNumberOfItems )++; 100 | } 101 | /*-----------------------------------------------------------*/ 102 | 103 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) 104 | { 105 | ListItem_t *pxIterator; 106 | const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; 107 | 108 | /* Only effective when configASSERT() is also defined, these tests may catch 109 | the list data structures being overwritten in memory. They will not catch 110 | data errors caused by incorrect configuration or use of FreeRTOS. */ 111 | listTEST_LIST_INTEGRITY( pxList ); 112 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 113 | 114 | /* Insert the new list item into the list, sorted in xItemValue order. 115 | 116 | If the list already contains a list item with the same item value then the 117 | new list item should be placed after it. This ensures that TCBs which are 118 | stored in ready lists (all of which have the same xItemValue value) get a 119 | share of the CPU. However, if the xItemValue is the same as the back marker 120 | the iteration loop below will not end. Therefore the value is checked 121 | first, and the algorithm slightly modified if necessary. */ 122 | if( xValueOfInsertion == portMAX_DELAY ) 123 | { 124 | pxIterator = pxList->xListEnd.pxPrevious; 125 | } 126 | else 127 | { 128 | /* *** NOTE *********************************************************** 129 | If you find your application is crashing here then likely causes are 130 | listed below. In addition see https://www.freertos.org/FAQHelp.html for 131 | more tips, and ensure configASSERT() is defined! 132 | https://www.freertos.org/a00110.html#configASSERT 133 | 134 | 1) Stack overflow - 135 | see https://www.freertos.org/Stacks-and-stack-overflow-checking.html 136 | 2) Incorrect interrupt priority assignment, especially on Cortex-M 137 | parts where numerically high priority values denote low actual 138 | interrupt priorities, which can seem counter intuitive. See 139 | https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition 140 | of configMAX_SYSCALL_INTERRUPT_PRIORITY on 141 | https://www.freertos.org/a00110.html 142 | 3) Calling an API function from within a critical section or when 143 | the scheduler is suspended, or calling an API function that does 144 | not end in "FromISR" from an interrupt. 145 | 4) Using a queue or semaphore before it has been initialised or 146 | before the scheduler has been started (are interrupts firing 147 | before vTaskStartScheduler() has been called?). 148 | **********************************************************************/ 149 | 150 | for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ 151 | { 152 | /* There is nothing to do here, just iterating to the wanted 153 | insertion position. */ 154 | } 155 | } 156 | 157 | pxNewListItem->pxNext = pxIterator->pxNext; 158 | pxNewListItem->pxNext->pxPrevious = pxNewListItem; 159 | pxNewListItem->pxPrevious = pxIterator; 160 | pxIterator->pxNext = pxNewListItem; 161 | 162 | /* Remember which list the item is in. This allows fast removal of the 163 | item later. */ 164 | pxNewListItem->pxContainer = pxList; 165 | 166 | ( pxList->uxNumberOfItems )++; 167 | } 168 | /*-----------------------------------------------------------*/ 169 | 170 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) 171 | { 172 | /* The list item knows which list it is in. Obtain the list from the list 173 | item. */ 174 | List_t * const pxList = pxItemToRemove->pxContainer; 175 | 176 | pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; 177 | pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; 178 | 179 | /* Only used during decision coverage testing. */ 180 | mtCOVERAGE_TEST_DELAY(); 181 | 182 | /* Make sure the index is left pointing to a valid item. */ 183 | if( pxList->pxIndex == pxItemToRemove ) 184 | { 185 | pxList->pxIndex = pxItemToRemove->pxPrevious; 186 | } 187 | else 188 | { 189 | mtCOVERAGE_TEST_MARKER(); 190 | } 191 | 192 | pxItemToRemove->pxContainer = NULL; 193 | ( pxList->uxNumberOfItems )--; 194 | 195 | return pxList->uxNumberOfItems; 196 | } 197 | /*-----------------------------------------------------------*/ 198 | 199 | -------------------------------------------------------------------------------- /Source/include/mpu_wrappers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef MPU_WRAPPERS_H 29 | #define MPU_WRAPPERS_H 30 | 31 | /* This file redefines API functions to be called through a wrapper macro, but 32 | only for ports that are using the MPU. */ 33 | #ifdef portUSING_MPU_WRAPPERS 34 | 35 | /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is 36 | included from queue.c or task.c to prevent it from having an effect within 37 | those files. */ 38 | #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 39 | 40 | /* 41 | * Map standard (non MPU) API functions to equivalents that start 42 | * "MPU_". This will cause the application code to call the MPU_ 43 | * version, which wraps the non-MPU version with privilege promoting 44 | * then demoting code, so the kernel code always runs will full 45 | * privileges. 46 | */ 47 | 48 | /* Map standard tasks.h API functions to the MPU equivalents. */ 49 | #define xTaskCreate MPU_xTaskCreate 50 | #define xTaskCreateStatic MPU_xTaskCreateStatic 51 | #define xTaskCreateRestricted MPU_xTaskCreateRestricted 52 | #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions 53 | #define vTaskDelete MPU_vTaskDelete 54 | #define vTaskDelay MPU_vTaskDelay 55 | #define vTaskDelayUntil MPU_vTaskDelayUntil 56 | #define xTaskAbortDelay MPU_xTaskAbortDelay 57 | #define uxTaskPriorityGet MPU_uxTaskPriorityGet 58 | #define eTaskGetState MPU_eTaskGetState 59 | #define vTaskGetInfo MPU_vTaskGetInfo 60 | #define vTaskPrioritySet MPU_vTaskPrioritySet 61 | #define vTaskSuspend MPU_vTaskSuspend 62 | #define vTaskResume MPU_vTaskResume 63 | #define vTaskSuspendAll MPU_vTaskSuspendAll 64 | #define xTaskResumeAll MPU_xTaskResumeAll 65 | #define xTaskGetTickCount MPU_xTaskGetTickCount 66 | #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks 67 | #define pcTaskGetName MPU_pcTaskGetName 68 | #define xTaskGetHandle MPU_xTaskGetHandle 69 | #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark 70 | #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 71 | #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag 72 | #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag 73 | #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer 74 | #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer 75 | #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook 76 | #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle 77 | #define uxTaskGetSystemState MPU_uxTaskGetSystemState 78 | #define vTaskList MPU_vTaskList 79 | #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats 80 | #define xTaskGenericNotify MPU_xTaskGenericNotify 81 | #define xTaskNotifyWait MPU_xTaskNotifyWait 82 | #define ulTaskNotifyTake MPU_ulTaskNotifyTake 83 | #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear 84 | 85 | #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle 86 | #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState 87 | #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut 88 | #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState 89 | 90 | /* Map standard queue.h API functions to the MPU equivalents. */ 91 | #define xQueueGenericSend MPU_xQueueGenericSend 92 | #define xQueueReceive MPU_xQueueReceive 93 | #define xQueuePeek MPU_xQueuePeek 94 | #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake 95 | #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting 96 | #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable 97 | #define vQueueDelete MPU_vQueueDelete 98 | #define xQueueCreateMutex MPU_xQueueCreateMutex 99 | #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic 100 | #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore 101 | #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic 102 | #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder 103 | #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive 104 | #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive 105 | #define xQueueGenericCreate MPU_xQueueGenericCreate 106 | #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic 107 | #define xQueueCreateSet MPU_xQueueCreateSet 108 | #define xQueueAddToSet MPU_xQueueAddToSet 109 | #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet 110 | #define xQueueSelectFromSet MPU_xQueueSelectFromSet 111 | #define xQueueGenericReset MPU_xQueueGenericReset 112 | 113 | #if( configQUEUE_REGISTRY_SIZE > 0 ) 114 | #define vQueueAddToRegistry MPU_vQueueAddToRegistry 115 | #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue 116 | #define pcQueueGetName MPU_pcQueueGetName 117 | #endif 118 | 119 | /* Map standard timer.h API functions to the MPU equivalents. */ 120 | #define xTimerCreate MPU_xTimerCreate 121 | #define xTimerCreateStatic MPU_xTimerCreateStatic 122 | #define pvTimerGetTimerID MPU_pvTimerGetTimerID 123 | #define vTimerSetTimerID MPU_vTimerSetTimerID 124 | #define xTimerIsTimerActive MPU_xTimerIsTimerActive 125 | #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle 126 | #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall 127 | #define pcTimerGetName MPU_pcTimerGetName 128 | #define vTimerSetReloadMode MPU_vTimerSetReloadMode 129 | #define xTimerGetPeriod MPU_xTimerGetPeriod 130 | #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime 131 | #define xTimerGenericCommand MPU_xTimerGenericCommand 132 | 133 | /* Map standard event_group.h API functions to the MPU equivalents. */ 134 | #define xEventGroupCreate MPU_xEventGroupCreate 135 | #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic 136 | #define xEventGroupWaitBits MPU_xEventGroupWaitBits 137 | #define xEventGroupClearBits MPU_xEventGroupClearBits 138 | #define xEventGroupSetBits MPU_xEventGroupSetBits 139 | #define xEventGroupSync MPU_xEventGroupSync 140 | #define vEventGroupDelete MPU_vEventGroupDelete 141 | 142 | /* Map standard message/stream_buffer.h API functions to the MPU 143 | equivalents. */ 144 | #define xStreamBufferSend MPU_xStreamBufferSend 145 | #define xStreamBufferReceive MPU_xStreamBufferReceive 146 | #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes 147 | #define vStreamBufferDelete MPU_vStreamBufferDelete 148 | #define xStreamBufferIsFull MPU_xStreamBufferIsFull 149 | #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty 150 | #define xStreamBufferReset MPU_xStreamBufferReset 151 | #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable 152 | #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable 153 | #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel 154 | #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate 155 | #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic 156 | 157 | 158 | /* Remove the privileged function macro, but keep the PRIVILEGED_DATA 159 | macro so applications can place data in privileged access sections 160 | (useful when using statically allocated objects). */ 161 | #define PRIVILEGED_FUNCTION 162 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 163 | 164 | #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 165 | 166 | /* Ensure API functions go in the privileged execution section. */ 167 | #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) 168 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 169 | 170 | #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 171 | 172 | #else /* portUSING_MPU_WRAPPERS */ 173 | 174 | #define PRIVILEGED_FUNCTION 175 | #define PRIVILEGED_DATA 176 | #define portUSING_MPU_WRAPPERS 0 177 | 178 | #endif /* portUSING_MPU_WRAPPERS */ 179 | 180 | 181 | #endif /* MPU_WRAPPERS_H */ 182 | 183 | -------------------------------------------------------------------------------- /Source/portable/esp8266/port.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.0 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. If you wish to use our Amazon 14 | * FreeRTOS name, please do so in a fair use way that does not cause confusion. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | * http://www.FreeRTOS.org 24 | * http://aws.amazon.com/freertos 25 | * 26 | * 1 tab == 4 spaces! 27 | */ 28 | 29 | /*----------------------------------------------------------- 30 | * Implementation of functions defined in portable.h for ESP8266 31 | * 32 | * This is based on the version supplied in esp_iot_rtos_sdk, 33 | * which is in turn based on the ARM CM3 port. 34 | *----------------------------------------------------------*/ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "FreeRTOS.h" 44 | #include "task.h" 45 | #include "queue.h" 46 | #include "xtensa_rtos.h" 47 | 48 | unsigned cpu_sr; 49 | char level1_int_disabled; 50 | 51 | /* Supervisor stack pointer entry. This is the "high water mark" of 52 | how far the supervisor stack grew down before task started. Is zero 53 | before the scheduler starts. 54 | 55 | After the scheduler starts, task stacks are all allocated from the 56 | heap and FreeRTOS checks for stack overflow. 57 | */ 58 | void *xPortSupervisorStackPointer; 59 | 60 | void vAssertCalled(const char * pcFile, unsigned long ulLine) 61 | { 62 | printf("rtos assert %s %lu\n", pcFile, ulLine); 63 | abort(); 64 | //for (;;); 65 | } 66 | 67 | /* 68 | * Stack initialization 69 | */ 70 | portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) 71 | { 72 | #define SET_STKREG(r,v) sp[(r) >> 2] = (portSTACK_TYPE)(v) 73 | portSTACK_TYPE *sp, *tp; 74 | 75 | /* Create interrupt stack frame aligned to 16 byte boundary */ 76 | sp = (portSTACK_TYPE*) (((uint32_t)(pxTopOfStack + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf); 77 | 78 | /* Clear the entire frame (do not use memset() because we don't depend on C library) */ 79 | for (tp = sp; tp <= pxTopOfStack; ++tp) 80 | *tp = 0; 81 | 82 | /* Explicitly initialize certain saved registers */ 83 | SET_STKREG( XT_STK_PC, pxCode ); /* task entrypoint */ 84 | SET_STKREG( XT_STK_A0, 0 ); /* to terminate GDB backtrace */ 85 | SET_STKREG( XT_STK_A1, (uint32_t)sp + XT_STK_FRMSZ ); /* physical top of stack frame */ 86 | SET_STKREG( XT_STK_A2, pvParameters ); /* parameters */ 87 | SET_STKREG( XT_STK_EXIT, _xt_user_exit ); /* user exception exit dispatcher */ 88 | 89 | /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */ 90 | SET_STKREG( XT_STK_PS, PS_UM | PS_EXCM ); 91 | return sp; 92 | } 93 | 94 | static int pending_soft_sv; 95 | static int pending_maclayer_sv; 96 | 97 | /* 98 | * The portYIELD macro calls PendSV with SVC_Software to set a pending interrupt 99 | * service callback that allows a task switch, and this occur when interrupts 100 | * are enabled which might be after exiting the critical region below. 101 | * 102 | * The wdev NMI calls this function from pp_post() with SVC_MACLayer to set a 103 | * pending interrupt service callback which flushs the queue of messages that 104 | * the NMI stashes away. This interrupt will be triggered after the return from 105 | * the NMI and when interrupts are enabled. The NMI can not touch the FreeRTOS 106 | * queues itself. The NMI must not touch the interrupt masks so that path must 107 | * not call vPortEnterCritical and vPortExitCritical. 108 | */ 109 | void IRAM PendSV(enum SVC_ReqType req) 110 | { 111 | if (req == SVC_Software) { 112 | vPortEnterCritical(); 113 | pending_soft_sv = 1; 114 | WSR(BIT(INUM_SOFT), interrupt); 115 | vPortExitCritical(); 116 | } else if (req == SVC_MACLayer) { 117 | pending_maclayer_sv= 1; 118 | WSR(BIT(INUM_SOFT), interrupt); 119 | } 120 | } 121 | 122 | /* This MAC layer ISR handler is defined in libpp.a, and is called 123 | * after a Blob SV requests a soft interrupt by calling 124 | * PendSV(SVC_MACLayer). 125 | */ 126 | extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void); 127 | 128 | void IRAM SV_ISR(void *arg) 129 | { 130 | portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE ; 131 | if (pending_maclayer_sv) { 132 | xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl(); 133 | pending_maclayer_sv = 0; 134 | } 135 | if (xHigherPriorityTaskWoken || pending_soft_sv) { 136 | sdk__xt_timer_int1(); 137 | pending_soft_sv = 0; 138 | } 139 | } 140 | 141 | void xPortSysTickHandle (void) 142 | { 143 | if (xTaskIncrementTick() != pdFALSE) { 144 | vTaskSwitchContext(); 145 | } 146 | } 147 | 148 | /* 149 | * See header file for description. 150 | */ 151 | portBASE_TYPE xPortStartScheduler( void ) 152 | { 153 | _xt_isr_attach(INUM_SOFT, SV_ISR, NULL); 154 | _xt_isr_unmask(BIT(INUM_SOFT)); 155 | 156 | /* Initialize system tick timer interrupt and schedule the first tick. */ 157 | _xt_isr_attach(INUM_TICK, sdk__xt_timer_int, NULL); 158 | _xt_isr_unmask(BIT(INUM_TICK)); 159 | sdk__xt_tick_timer_init(); 160 | 161 | vTaskSwitchContext(); 162 | 163 | /* mark the supervisor stack pointer high water mark. xt_int_exit 164 | actually frees ~0x50 bytes off the stack, so this value is 165 | conservative. 166 | */ 167 | __asm__ __volatile__ ("mov %0, a1\n" : "=a"(xPortSupervisorStackPointer)); 168 | 169 | sdk__xt_int_exit(); 170 | 171 | /* Should not get here as the tasks are now running! */ 172 | return pdTRUE; 173 | } 174 | 175 | /* Determine free heap size via libc sbrk function & mallinfo 176 | 177 | sbrk gives total size in totally unallocated memory, 178 | mallinfo.fordblks gives free space inside area dedicated to heap. 179 | 180 | mallinfo is possibly non-portable, although glibc & newlib both support 181 | the fordblks member. 182 | */ 183 | size_t xPortGetFreeHeapSize( void ) 184 | { 185 | struct mallinfo mi = mallinfo(); 186 | uint32_t brk_val = (uint32_t) sbrk(0); 187 | 188 | intptr_t sp = (intptr_t)xPortSupervisorStackPointer; 189 | if (sp == 0) { 190 | /* scheduler not started */ 191 | SP(sp); 192 | } 193 | return sp - brk_val + mi.fordblks; 194 | } 195 | 196 | void vPortEndScheduler( void ) 197 | { 198 | /* No-op, nothing to return to */ 199 | } 200 | 201 | /*-----------------------------------------------------------*/ 202 | 203 | static unsigned portBASE_TYPE uxCriticalNesting = 0; 204 | 205 | /* These nested vPortEnter/ExitCritical macros are called by SDK 206 | * libraries in libmain, libnet80211, libpp 207 | * 208 | * It may be possible to replace the global nesting count variable 209 | * with a save/restore of interrupt level, although it's difficult as 210 | * the functions have no return value. 211 | * 212 | * These should not be called from the NMI in regular operation and 213 | * the NMI must not touch the interrupt mask, but that might occur in 214 | * exceptional paths such as aborts and debug code. 215 | */ 216 | void IRAM vPortEnterCritical(void) { 217 | portDISABLE_INTERRUPTS(); 218 | uxCriticalNesting++; 219 | } 220 | 221 | /*-----------------------------------------------------------*/ 222 | 223 | void IRAM vPortExitCritical(void) { 224 | uxCriticalNesting--; 225 | if (uxCriticalNesting == 0) 226 | portENABLE_INTERRUPTS(); 227 | } 228 | 229 | /* Backward compatibility, for the sdk library. */ 230 | 231 | signed portBASE_TYPE xTaskGenericCreate(TaskFunction_t pxTaskCode, 232 | const signed char * const pcName, 233 | unsigned short usStackDepth, 234 | void *pvParameters, 235 | unsigned portBASE_TYPE uxPriority, 236 | TaskHandle_t *pxCreatedTask, 237 | portSTACK_TYPE *puxStackBuffer, 238 | const MemoryRegion_t * const xRegions) { 239 | (void)puxStackBuffer; 240 | (void)xRegions; 241 | return xTaskCreate(pxTaskCode, (const char * const)pcName, usStackDepth, 242 | pvParameters, uxPriority, pxCreatedTask); 243 | } 244 | 245 | BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer, 246 | TickType_t xTicksToWait, const BaseType_t xJustPeeking) { 247 | configASSERT(xJustPeeking == 0); 248 | return xQueueReceive(xQueue, pvBuffer, xTicksToWait); 249 | } 250 | -------------------------------------------------------------------------------- /Source/portable/MemMang/heap_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * A sample implementation of pvPortMalloc() and vPortFree() that permits 30 | * allocated blocks to be freed, but does not combine adjacent free blocks 31 | * into a single larger block (and so will fragment memory). See heap_4.c for 32 | * an equivalent that does combine adjacent blocks into single larger blocks. 33 | * 34 | * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the 35 | * memory management pages of http://www.FreeRTOS.org for more information. 36 | */ 37 | #include 38 | 39 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 40 | all the API functions to use the MPU wrappers. That should only be done when 41 | task.h is included from an application file. */ 42 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 43 | 44 | #include "FreeRTOS.h" 45 | #include "task.h" 46 | 47 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 48 | 49 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 50 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 51 | #endif 52 | 53 | /* A few bytes might be lost to byte aligning the heap start address. */ 54 | #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) 55 | 56 | /* 57 | * Initialises the heap structures before their first use. 58 | */ 59 | static void prvHeapInit( void ); 60 | 61 | /* Allocate the memory for the heap. */ 62 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 63 | /* The application writer has already defined the array used for the RTOS 64 | heap - probably so it can be placed in a special segment or address. */ 65 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 66 | #else 67 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 68 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 69 | 70 | 71 | /* Define the linked list structure. This is used to link free blocks in order 72 | of their size. */ 73 | typedef struct A_BLOCK_LINK 74 | { 75 | struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ 76 | size_t xBlockSize; /*<< The size of the free block. */ 77 | } BlockLink_t; 78 | 79 | 80 | static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); 81 | #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) 82 | 83 | /* Create a couple of list links to mark the start and end of the list. */ 84 | static BlockLink_t xStart, xEnd; 85 | 86 | /* Keeps track of the number of free bytes remaining, but says nothing about 87 | fragmentation. */ 88 | static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; 89 | 90 | /* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ 91 | 92 | /* 93 | * Insert a block into the list of free blocks - which is ordered by size of 94 | * the block. Small blocks at the start of the list and large blocks at the end 95 | * of the list. 96 | */ 97 | #define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ 98 | { \ 99 | BlockLink_t *pxIterator; \ 100 | size_t xBlockSize; \ 101 | \ 102 | xBlockSize = pxBlockToInsert->xBlockSize; \ 103 | \ 104 | /* Iterate through the list until a block is found that has a larger size */ \ 105 | /* than the block we are inserting. */ \ 106 | for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ 107 | { \ 108 | /* There is nothing to do here - just iterate to the correct position. */ \ 109 | } \ 110 | \ 111 | /* Update the list to include the block being inserted in the correct */ \ 112 | /* position. */ \ 113 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ 114 | pxIterator->pxNextFreeBlock = pxBlockToInsert; \ 115 | } 116 | /*-----------------------------------------------------------*/ 117 | 118 | void *pvPortMalloc( size_t xWantedSize ) 119 | { 120 | BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; 121 | static BaseType_t xHeapHasBeenInitialised = pdFALSE; 122 | void *pvReturn = NULL; 123 | 124 | vTaskSuspendAll(); 125 | { 126 | /* If this is the first call to malloc then the heap will require 127 | initialisation to setup the list of free blocks. */ 128 | if( xHeapHasBeenInitialised == pdFALSE ) 129 | { 130 | prvHeapInit(); 131 | xHeapHasBeenInitialised = pdTRUE; 132 | } 133 | 134 | /* The wanted size is increased so it can contain a BlockLink_t 135 | structure in addition to the requested amount of bytes. */ 136 | if( xWantedSize > 0 ) 137 | { 138 | xWantedSize += heapSTRUCT_SIZE; 139 | 140 | /* Ensure that blocks are always aligned to the required number of bytes. */ 141 | if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) 142 | { 143 | /* Byte alignment required. */ 144 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 145 | } 146 | } 147 | 148 | if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) ) 149 | { 150 | /* Blocks are stored in byte order - traverse the list from the start 151 | (smallest) block until one of adequate size is found. */ 152 | pxPreviousBlock = &xStart; 153 | pxBlock = xStart.pxNextFreeBlock; 154 | while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) 155 | { 156 | pxPreviousBlock = pxBlock; 157 | pxBlock = pxBlock->pxNextFreeBlock; 158 | } 159 | 160 | /* If we found the end marker then a block of adequate size was not found. */ 161 | if( pxBlock != &xEnd ) 162 | { 163 | /* Return the memory space - jumping over the BlockLink_t structure 164 | at its start. */ 165 | pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); 166 | 167 | /* This block is being returned for use so must be taken out of the 168 | list of free blocks. */ 169 | pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; 170 | 171 | /* If the block is larger than required it can be split into two. */ 172 | if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) 173 | { 174 | /* This block is to be split into two. Create a new block 175 | following the number of bytes requested. The void cast is 176 | used to prevent byte alignment warnings from the compiler. */ 177 | pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); 178 | 179 | /* Calculate the sizes of two blocks split from the single 180 | block. */ 181 | pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; 182 | pxBlock->xBlockSize = xWantedSize; 183 | 184 | /* Insert the new block into the list of free blocks. */ 185 | prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); 186 | } 187 | 188 | xFreeBytesRemaining -= pxBlock->xBlockSize; 189 | } 190 | } 191 | 192 | traceMALLOC( pvReturn, xWantedSize ); 193 | } 194 | ( void ) xTaskResumeAll(); 195 | 196 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 197 | { 198 | if( pvReturn == NULL ) 199 | { 200 | extern void vApplicationMallocFailedHook( void ); 201 | vApplicationMallocFailedHook(); 202 | } 203 | } 204 | #endif 205 | 206 | return pvReturn; 207 | } 208 | /*-----------------------------------------------------------*/ 209 | 210 | void vPortFree( void *pv ) 211 | { 212 | uint8_t *puc = ( uint8_t * ) pv; 213 | BlockLink_t *pxLink; 214 | 215 | if( pv != NULL ) 216 | { 217 | /* The memory being freed will have an BlockLink_t structure immediately 218 | before it. */ 219 | puc -= heapSTRUCT_SIZE; 220 | 221 | /* This unexpected casting is to keep some compilers from issuing 222 | byte alignment warnings. */ 223 | pxLink = ( void * ) puc; 224 | 225 | vTaskSuspendAll(); 226 | { 227 | /* Add this block to the list of free blocks. */ 228 | prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); 229 | xFreeBytesRemaining += pxLink->xBlockSize; 230 | traceFREE( pv, pxLink->xBlockSize ); 231 | } 232 | ( void ) xTaskResumeAll(); 233 | } 234 | } 235 | /*-----------------------------------------------------------*/ 236 | 237 | size_t xPortGetFreeHeapSize( void ) 238 | { 239 | return xFreeBytesRemaining; 240 | } 241 | /*-----------------------------------------------------------*/ 242 | 243 | void vPortInitialiseBlocks( void ) 244 | { 245 | /* This just exists to keep the linker quiet. */ 246 | } 247 | /*-----------------------------------------------------------*/ 248 | 249 | static void prvHeapInit( void ) 250 | { 251 | BlockLink_t *pxFirstFreeBlock; 252 | uint8_t *pucAlignedHeap; 253 | 254 | /* Ensure the heap starts on a correctly aligned boundary. */ 255 | pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); 256 | 257 | /* xStart is used to hold a pointer to the first item in the list of free 258 | blocks. The void cast is used to prevent compiler warnings. */ 259 | xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; 260 | xStart.xBlockSize = ( size_t ) 0; 261 | 262 | /* xEnd is used to mark the end of the list of free blocks. */ 263 | xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; 264 | xEnd.pxNextFreeBlock = NULL; 265 | 266 | /* To start with there is a single free block that is sized to take up the 267 | entire heap space. */ 268 | pxFirstFreeBlock = ( void * ) pucAlignedHeap; 269 | pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; 270 | pxFirstFreeBlock->pxNextFreeBlock = &xEnd; 271 | } 272 | /*-----------------------------------------------------------*/ 273 | -------------------------------------------------------------------------------- /Source/include/mpu_prototypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * When the MPU is used the standard (non MPU) API functions are mapped to 30 | * equivalents that start "MPU_", the prototypes for which are defined in this 31 | * header files. This will cause the application code to call the MPU_ version 32 | * which wraps the non-MPU version with privilege promoting then demoting code, 33 | * so the kernel code always runs will full privileges. 34 | */ 35 | 36 | 37 | #ifndef MPU_PROTOTYPES_H 38 | #define MPU_PROTOTYPES_H 39 | 40 | /* MPU versions of tasks.h API functions. */ 41 | BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ); 42 | TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ); 43 | BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ); 44 | BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ); 45 | void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); 46 | void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ); 47 | void MPU_vTaskDelay( const TickType_t xTicksToDelay ); 48 | void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ); 49 | BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ); 50 | UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ); 51 | eTaskState MPU_eTaskGetState( TaskHandle_t xTask ); 52 | void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); 53 | void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); 54 | void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ); 55 | void MPU_vTaskResume( TaskHandle_t xTaskToResume ); 56 | void MPU_vTaskStartScheduler( void ); 57 | void MPU_vTaskSuspendAll( void ); 58 | BaseType_t MPU_xTaskResumeAll( void ); 59 | TickType_t MPU_xTaskGetTickCount( void ); 60 | UBaseType_t MPU_uxTaskGetNumberOfTasks( void ); 61 | char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ); 62 | TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ); 63 | UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); 64 | configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ); 65 | void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); 66 | TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); 67 | void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ); 68 | void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ); 69 | BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); 70 | TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ); 71 | UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ); 72 | void MPU_vTaskList( char * pcWriteBuffer ); 73 | void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ); 74 | BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ); 75 | BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); 76 | uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); 77 | BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ); 78 | BaseType_t MPU_xTaskIncrementTick( void ); 79 | TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ); 80 | void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); 81 | BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); 82 | void MPU_vTaskMissedYield( void ); 83 | BaseType_t MPU_xTaskGetSchedulerState( void ); 84 | 85 | /* MPU versions of queue.h API functions. */ 86 | BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ); 87 | BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ); 88 | BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ); 89 | BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ); 90 | UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ); 91 | UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ); 92 | void MPU_vQueueDelete( QueueHandle_t xQueue ); 93 | QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ); 94 | QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ); 95 | QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ); 96 | QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ); 97 | TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ); 98 | BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ); 99 | BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ); 100 | void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ); 101 | void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ); 102 | const char * MPU_pcQueueGetName( QueueHandle_t xQueue ); 103 | QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ); 104 | QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ); 105 | QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ); 106 | BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); 107 | BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); 108 | QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ); 109 | BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ); 110 | void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ); 111 | UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ); 112 | uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ); 113 | 114 | /* MPU versions of timers.h API functions. */ 115 | TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ); 116 | TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ); 117 | void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ); 118 | void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); 119 | BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ); 120 | TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ); 121 | BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ); 122 | const char * MPU_pcTimerGetName( TimerHandle_t xTimer ); 123 | void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ); 124 | TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ); 125 | TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ); 126 | BaseType_t MPU_xTimerCreateTimerTask( void ); 127 | BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ); 128 | 129 | /* MPU versions of event_group.h API functions. */ 130 | EventGroupHandle_t MPU_xEventGroupCreate( void ); 131 | EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ); 132 | EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ); 133 | EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); 134 | EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); 135 | EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ); 136 | void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ); 137 | UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ); 138 | 139 | /* MPU versions of message/stream_buffer.h API functions. */ 140 | size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ); 141 | size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ); 142 | size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ); 143 | void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); 144 | BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); 145 | BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); 146 | BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); 147 | size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); 148 | size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); 149 | BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); 150 | StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ); 151 | StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ); 152 | 153 | 154 | 155 | #endif /* MPU_PROTOTYPES_H */ 156 | 157 | -------------------------------------------------------------------------------- /Source/portable/esp8266/xtensa_context.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Copyright (c) 2006-2008 by Tensilica Inc. ALL RIGHTS RESERVED. 3 | These coded instructions, statements, and computer programs are the 4 | copyrighted works and confidential proprietary information of Tensilica Inc. 5 | They may not be modified, copied, reproduced, distributed, or disclosed to 6 | third parties in any manner, medium, or form, in whole or in part, without 7 | the prior written consent of Tensilica Inc. 8 | -------------------------------------------------------------------------------- 9 | 10 | XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES 11 | 12 | This header contains definitions and macros for use primarily by Xtensa 13 | RTOS assembly coded source files. It includes and uses the Xtensa hardware 14 | abstraction layer (HAL) to deal with config specifics. It may also be 15 | included in C source files. 16 | 17 | !! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !! 18 | 19 | NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes. 20 | 21 | *******************************************************************************/ 22 | 23 | #ifndef XTENSA_CONTEXT_H 24 | #define XTENSA_CONTEXT_H 25 | 26 | #ifdef __ASSEMBLER__ 27 | #include 28 | #endif 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | 35 | /* 36 | Align a value up to nearest n-byte boundary, where n is a power of 2. 37 | */ 38 | #define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) 39 | 40 | 41 | /******************************************************************************* 42 | 43 | INTERRUPT STACK FRAME FOR A THREAD OR NESTED INTERRUPT 44 | 45 | A stack frame of this structure is allocated for any interrupt or exception. 46 | It goes on the current stack. If the RTOS has a system stack for handling 47 | interrupts, every thread stack must allow space for just one interrupt stack 48 | frame, then nested interrupt stack frames go on the system stack. 49 | 50 | The frame includes basic registers (explicit) and "extra" registers introduced 51 | by user TIE or the use of the MAC16 option in the user's Xtensa config. 52 | The frame size is minimized by omitting regs not applicable to user's config. 53 | 54 | For Windowed ABI, this stack frame includes the interruptee's base save area, 55 | another base save area to manage gcc nested functions, and a little temporary 56 | space to help manage the spilling of the register windows. 57 | 58 | *******************************************************************************/ 59 | 60 | #define XT_STK_EXIT 0x00 /* (offset 0) exit point for dispatch */ 61 | #define XT_STK_PC 0x04 /* return address */ 62 | #define XT_STK_PS 0x08 /* at level 1 PS.EXCM is set here */ 63 | #define XT_STK_A0 0x0C 64 | #define XT_STK_A1 0x10 /* stack ptr before interrupt */ 65 | #define XT_STK_A2 0x14 66 | #define XT_STK_A3 0x18 67 | #define XT_STK_A4 0x1C 68 | #define XT_STK_A5 0x20 69 | #define XT_STK_A6 0x24 70 | #define XT_STK_A7 0x28 71 | #define XT_STK_A8 0x2C 72 | #define XT_STK_A9 0x30 73 | #define XT_STK_A10 0x34 74 | #define XT_STK_A11 0x38 75 | #define XT_STK_A12 0x3C /* Call0 callee-save */ 76 | #define XT_STK_A13 0x40 /* Call0 callee-save */ 77 | #define XT_STK_A14 0x44 /* Call0 callee-save */ 78 | #define XT_STK_A15 0x48 /* Call0 callee-save */ 79 | #define XT_STK_SAR 0x4C 80 | 81 | #if XCHAL_HAVE_LOOPS 82 | #define XT_STK_LBEG 0x50 83 | #define XT_STK_LEND 0x54 84 | #define XT_STK_LCOUNT 0x58 85 | #define XT_STK_NEXT1 0x5C /* next unused offset */ 86 | #else 87 | #define XT_STK_NEXT1 0x50 /* next unused offset */ 88 | #endif 89 | /* there may be some unused space here */ 90 | #if XCHAL_EXTRA_SA_SIZE != 0 91 | #define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) 92 | 93 | #define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE) 94 | #else 95 | #define XT_STK_NEXT2 XT_STK_NEXT1 96 | #endif 97 | /* next unused offset */ 98 | /* there may be some unused space here */ 99 | #ifdef __XTENSA_CALL0_ABI__ 100 | /* Call0 - no more stack frame needed */ 101 | #define XT_STK_FRMSZ ALIGNUP(0x10, XT_STK_NEXT2) 102 | #else 103 | /* 104 | Windowed - 105 | Need some temp space for saving stuff during window spill. 106 | Also add 16 bytes to skip over interruptee's base save area 107 | and another 16 bytes in case of gcc nested functions: these 108 | must be at physical top (logical base) of frame. 109 | */ 110 | #define XT_STK_N_TMP 3 /* # of 4-byte temp. slots */ 111 | #define XT_STK_TMP XT_STK_NEXT2 112 | #define XT_STK_NEXT3 XT_STK_TMP + (4 * XT_STK_N_TMP) 113 | #define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT3) + 0x20) 114 | #endif 115 | 116 | 117 | /******************************************************************************* 118 | 119 | SOLICTED STACK FRAME FOR A THREAD 120 | 121 | A stack frame of this structure is allocated whenever a thread enters the 122 | RTOS kernel intentionally (and synchronously) to submit to thread scheduling. 123 | It goes on the current thread's stack. 124 | 125 | The solicted frame only includes registers that are required to be preserved 126 | by the callee according to the compiler's ABI conventions, some space to save 127 | the return address for returning to the caller, and the caller's PS register. 128 | 129 | For Windowed ABI, this stack frame includes the caller's base save area. 130 | 131 | Note on XT_SOL_EXIT field: 132 | It is necessary to distinguish a solicited from an interrupt stack frame. 133 | This field corresponds to XT_STK_EXIT in the interrupt stack frame and is 134 | always at the same offset (0). It can be written with a code (usually 0) 135 | to distinguish a solicted frame from an interrupt frame. An RTOS port may 136 | opt to ignore this field if it has another way of distinguishing frames. 137 | 138 | *******************************************************************************/ 139 | 140 | #ifdef __XTENSA_CALL0_ABI__ 141 | 142 | /* Call0 ABI: room to save callee-save regs and return address. */ 143 | #define XT_SOL_EXIT XT_STK_EXIT /* code indicates solicited frame */ 144 | #define XT_SOL_PC 0x04 /* return address */ 145 | #define XT_SOL_PS 0x08 146 | #define XT_SOL_NEXT 0x0c /* next unused offset */ 147 | /* there may be some unused space here */ 148 | #define XT_SOL_A12 ALIGNUP(0x10, XT_SOL_NEXT) 149 | #define XT_SOL_A13 XT_SOL_A12 + 4 150 | #define XT_SOL_A14 XT_SOL_A13 + 4 151 | #define XT_SOL_A15 XT_SOL_A14 + 4 152 | #define XT_SOL_FRMSZ ALIGNUP(0x10, XT_SOL_A15) 153 | 154 | #else 155 | 156 | /* Windowed ABI: room to spill base-save area and save return address. */ 157 | #define XT_SOL_EXIT XT_STK_EXIT /* code indicates solicited frame */ 158 | #define XT_SOL_PC 0x04 /* return address (b30-31=callinc) */ 159 | #define XT_SOL_PS 0x08 160 | #define XT_SOL_NEXT 0x0c /* next unused offset */ 161 | /* there may be some unused space here */ 162 | #define XT_SOL_A0 ALIGNUP(0x10, XT_SOL_NEXT) 163 | #define XT_SOL_A1 XT_SOL_A0 + 4 164 | #define XT_SOL_A2 XT_SOL_A1 + 4 165 | #define XT_SOL_A3 XT_SOL_A2 + 4 166 | #define XT_SOL_FRMSZ ALIGNUP(0x10, XT_SOL_A3) 167 | 168 | #endif 169 | 170 | 171 | /******************************************************************************* 172 | 173 | CO-PROCESSOR STATE SAVE AREA FOR A THREAD 174 | 175 | The RTOS must provide an area per thread to save the state of co-processors 176 | when that thread does not have control. Co-processors are context-switched 177 | lazily (on demand) only when a new thread uses a co-processor instruction, 178 | otherwise a thread retains ownership of the co-processor even when it loses 179 | control of the processor. An Xtensa co-processor exception is triggered when 180 | any co-processor instruction is executed by a thread that is not the owner, 181 | and the context switch of that co-processor is then peformed by the handler. 182 | Ownership represents which thread's state is currently in the co-processor. 183 | 184 | Co-processors may not be used by interrupt or exception handlers. If an 185 | co-processor instruction is executed by an interrupt or exception handler, 186 | the co-processor exception handler will trigger a kernel panic and freeze. 187 | This restriction is introduced to reduce the overhead of saving and restoring 188 | co-processor state (which can be quite large) and in particular remove that 189 | overhead from interrupt handlers. 190 | 191 | The co-processor state save area may be in any convenient per-thread location 192 | such as in the thread control block or above the thread stack area. It need 193 | not be in the interrupt stack frame since interrupts don't use co-processors. 194 | 195 | Along with the save area for each co-processor, two bitmasks with flags per 196 | co-processor (laid out as in the CPENABLE reg) help manage context-switching 197 | co-processors as efficiently as possible: 198 | 199 | XT_CPENABLE 200 | The contents of a non-running thread's CPENABLE register. 201 | It represents the co-processors owned (and whose state is still needed) 202 | by the thread. When a thread is preempted, its CPENABLE is saved here. 203 | When a thread solicits a context-swtich, its CPENABLE is cleared - the 204 | compiler has saved the (caller-saved) co-proc state if it needs to. 205 | When a non-running thread loses ownership of a CP, its bit is cleared. 206 | When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg. 207 | Avoids co-processor exceptions when no change of ownership is needed. 208 | 209 | XT_CPSTORED 210 | A bitmask with the same layout as CPENABLE, a bit per co-processor. 211 | Indicates whether the state of each co-processor is saved in the state 212 | save area. When a thread enters the kernel, only the state of co-procs 213 | still enabled in CPENABLE is saved. When the co-processor exception 214 | handler assigns ownership of a co-processor to a thread, it restores 215 | the saved state only if this bit is set, and clears this bit. 216 | 217 | *******************************************************************************/ 218 | 219 | #if XCHAL_CP_NUM > 0 220 | #define XT_CPENABLE 0 221 | #define XT_CPSTORED (XT_CPENABLE + 1) 222 | #define XT_CP0_SA ALIGNUP(XCHAL_CP0_SA_ALIGN, XT_CPSTORED + 1) 223 | #define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE) 224 | #define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE) 225 | #define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE) 226 | #define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE) 227 | #define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE) 228 | #define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE) 229 | #define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE) 230 | #define XT_CP_SIZE ALIGNUP(4 , XT_CP7_SA + XCHAL_CP7_SA_SIZE) 231 | #else 232 | #define XT_CP_SIZE 0 233 | #endif 234 | 235 | 236 | /******************************************************************************* 237 | 238 | MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN 239 | 240 | Convenient where the frame size requirements are the same for both ABIs. 241 | ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). 242 | ENTRY0, RET0 are for frameless functions (no locals, no calls). 243 | where size = size of stack frame in bytes (must be >0 and aligned to 16). 244 | For framed functions the frame is created and the return address saved at 245 | base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). 246 | For frameless functions, there is no frame and return address remains in a0. 247 | Note: Because CPP macros expand to a single line, macros requiring multi-line 248 | expansions are implemented as assembler macros. 249 | 250 | *******************************************************************************/ 251 | 252 | #ifdef __ASSEMBLER__ 253 | #ifdef __XTENSA_CALL0_ABI__ 254 | /* Call0 */ 255 | #define ENTRY(sz) entry1 sz 256 | .macro entry1 size=0x10 257 | addi sp, sp, -\size 258 | s32i a0, sp, 0 259 | .endm 260 | #define ENTRY0 261 | #define RET(sz) ret1 sz 262 | .macro ret1 size=0x10 263 | l32i a0, sp, 0 264 | addi sp, sp, \size 265 | ret 266 | .endm 267 | #define RET0 ret 268 | #else 269 | /* Windowed */ 270 | #define ENTRY(sz) entry sp, sz 271 | #define ENTRY0 entry sp, 0x10 272 | #define RET(sz) retw 273 | #define RET0 retw 274 | #endif 275 | #endif 276 | 277 | 278 | #endif /* XTENSA_CONTEXT_H */ 279 | -------------------------------------------------------------------------------- /Source/croutine.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #include "FreeRTOS.h" 29 | #include "task.h" 30 | #include "croutine.h" 31 | 32 | /* Remove the whole file is co-routines are not being used. */ 33 | #if( configUSE_CO_ROUTINES != 0 ) 34 | 35 | /* 36 | * Some kernel aware debuggers require data to be viewed to be global, rather 37 | * than file scope. 38 | */ 39 | #ifdef portREMOVE_STATIC_QUALIFIER 40 | #define static 41 | #endif 42 | 43 | 44 | /* Lists for ready and blocked co-routines. --------------------*/ 45 | static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ 46 | static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ 47 | static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ 48 | static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ 49 | static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ 50 | static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ 51 | 52 | /* Other file private variables. --------------------------------*/ 53 | CRCB_t * pxCurrentCoRoutine = NULL; 54 | static UBaseType_t uxTopCoRoutineReadyPriority = 0; 55 | static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; 56 | 57 | /* The initial state of the co-routine when it is created. */ 58 | #define corINITIAL_STATE ( 0 ) 59 | 60 | /* 61 | * Place the co-routine represented by pxCRCB into the appropriate ready queue 62 | * for the priority. It is inserted at the end of the list. 63 | * 64 | * This macro accesses the co-routine ready lists and therefore must not be 65 | * used from within an ISR. 66 | */ 67 | #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ 68 | { \ 69 | if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ 70 | { \ 71 | uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ 72 | } \ 73 | vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ 74 | } 75 | 76 | /* 77 | * Utility to ready all the lists used by the scheduler. This is called 78 | * automatically upon the creation of the first co-routine. 79 | */ 80 | static void prvInitialiseCoRoutineLists( void ); 81 | 82 | /* 83 | * Co-routines that are readied by an interrupt cannot be placed directly into 84 | * the ready lists (there is no mutual exclusion). Instead they are placed in 85 | * in the pending ready list in order that they can later be moved to the ready 86 | * list by the co-routine scheduler. 87 | */ 88 | static void prvCheckPendingReadyList( void ); 89 | 90 | /* 91 | * Macro that looks at the list of co-routines that are currently delayed to 92 | * see if any require waking. 93 | * 94 | * Co-routines are stored in the queue in the order of their wake time - 95 | * meaning once one co-routine has been found whose timer has not expired 96 | * we need not look any further down the list. 97 | */ 98 | static void prvCheckDelayedList( void ); 99 | 100 | /*-----------------------------------------------------------*/ 101 | 102 | BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) 103 | { 104 | BaseType_t xReturn; 105 | CRCB_t *pxCoRoutine; 106 | 107 | /* Allocate the memory that will store the co-routine control block. */ 108 | pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); 109 | if( pxCoRoutine ) 110 | { 111 | /* If pxCurrentCoRoutine is NULL then this is the first co-routine to 112 | be created and the co-routine data structures need initialising. */ 113 | if( pxCurrentCoRoutine == NULL ) 114 | { 115 | pxCurrentCoRoutine = pxCoRoutine; 116 | prvInitialiseCoRoutineLists(); 117 | } 118 | 119 | /* Check the priority is within limits. */ 120 | if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) 121 | { 122 | uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; 123 | } 124 | 125 | /* Fill out the co-routine control block from the function parameters. */ 126 | pxCoRoutine->uxState = corINITIAL_STATE; 127 | pxCoRoutine->uxPriority = uxPriority; 128 | pxCoRoutine->uxIndex = uxIndex; 129 | pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; 130 | 131 | /* Initialise all the other co-routine control block parameters. */ 132 | vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); 133 | vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); 134 | 135 | /* Set the co-routine control block as a link back from the ListItem_t. 136 | This is so we can get back to the containing CRCB from a generic item 137 | in a list. */ 138 | listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); 139 | listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); 140 | 141 | /* Event lists are always in priority order. */ 142 | listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); 143 | 144 | /* Now the co-routine has been initialised it can be added to the ready 145 | list at the correct priority. */ 146 | prvAddCoRoutineToReadyQueue( pxCoRoutine ); 147 | 148 | xReturn = pdPASS; 149 | } 150 | else 151 | { 152 | xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; 153 | } 154 | 155 | return xReturn; 156 | } 157 | /*-----------------------------------------------------------*/ 158 | 159 | void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) 160 | { 161 | TickType_t xTimeToWake; 162 | 163 | /* Calculate the time to wake - this may overflow but this is 164 | not a problem. */ 165 | xTimeToWake = xCoRoutineTickCount + xTicksToDelay; 166 | 167 | /* We must remove ourselves from the ready list before adding 168 | ourselves to the blocked list as the same list item is used for 169 | both lists. */ 170 | ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 171 | 172 | /* The list item will be inserted in wake time order. */ 173 | listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); 174 | 175 | if( xTimeToWake < xCoRoutineTickCount ) 176 | { 177 | /* Wake time has overflowed. Place this item in the 178 | overflow list. */ 179 | vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 180 | } 181 | else 182 | { 183 | /* The wake time has not overflowed, so we can use the 184 | current block list. */ 185 | vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 186 | } 187 | 188 | if( pxEventList ) 189 | { 190 | /* Also add the co-routine to an event list. If this is done then the 191 | function must be called with interrupts disabled. */ 192 | vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); 193 | } 194 | } 195 | /*-----------------------------------------------------------*/ 196 | 197 | static void prvCheckPendingReadyList( void ) 198 | { 199 | /* Are there any co-routines waiting to get moved to the ready list? These 200 | are co-routines that have been readied by an ISR. The ISR cannot access 201 | the ready lists itself. */ 202 | while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) 203 | { 204 | CRCB_t *pxUnblockedCRCB; 205 | 206 | /* The pending ready list can be accessed by an ISR. */ 207 | portDISABLE_INTERRUPTS(); 208 | { 209 | pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); 210 | ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 211 | } 212 | portENABLE_INTERRUPTS(); 213 | 214 | ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); 215 | prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); 216 | } 217 | } 218 | /*-----------------------------------------------------------*/ 219 | 220 | static void prvCheckDelayedList( void ) 221 | { 222 | CRCB_t *pxCRCB; 223 | 224 | xPassedTicks = xTaskGetTickCount() - xLastTickCount; 225 | while( xPassedTicks ) 226 | { 227 | xCoRoutineTickCount++; 228 | xPassedTicks--; 229 | 230 | /* If the tick count has overflowed we need to swap the ready lists. */ 231 | if( xCoRoutineTickCount == 0 ) 232 | { 233 | List_t * pxTemp; 234 | 235 | /* Tick count has overflowed so we need to swap the delay lists. If there are 236 | any items in pxDelayedCoRoutineList here then there is an error! */ 237 | pxTemp = pxDelayedCoRoutineList; 238 | pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; 239 | pxOverflowDelayedCoRoutineList = pxTemp; 240 | } 241 | 242 | /* See if this tick has made a timeout expire. */ 243 | while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) 244 | { 245 | pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); 246 | 247 | if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) 248 | { 249 | /* Timeout not yet expired. */ 250 | break; 251 | } 252 | 253 | portDISABLE_INTERRUPTS(); 254 | { 255 | /* The event could have occurred just before this critical 256 | section. If this is the case then the generic list item will 257 | have been moved to the pending ready list and the following 258 | line is still valid. Also the pvContainer parameter will have 259 | been set to NULL so the following lines are also valid. */ 260 | ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); 261 | 262 | /* Is the co-routine waiting on an event also? */ 263 | if( pxCRCB->xEventListItem.pxContainer ) 264 | { 265 | ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); 266 | } 267 | } 268 | portENABLE_INTERRUPTS(); 269 | 270 | prvAddCoRoutineToReadyQueue( pxCRCB ); 271 | } 272 | } 273 | 274 | xLastTickCount = xCoRoutineTickCount; 275 | } 276 | /*-----------------------------------------------------------*/ 277 | 278 | void vCoRoutineSchedule( void ) 279 | { 280 | /* See if any co-routines readied by events need moving to the ready lists. */ 281 | prvCheckPendingReadyList(); 282 | 283 | /* See if any delayed co-routines have timed out. */ 284 | prvCheckDelayedList(); 285 | 286 | /* Find the highest priority queue that contains ready co-routines. */ 287 | while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) 288 | { 289 | if( uxTopCoRoutineReadyPriority == 0 ) 290 | { 291 | /* No more co-routines to check. */ 292 | return; 293 | } 294 | --uxTopCoRoutineReadyPriority; 295 | } 296 | 297 | /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines 298 | of the same priority get an equal share of the processor time. */ 299 | listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); 300 | 301 | /* Call the co-routine. */ 302 | ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); 303 | 304 | return; 305 | } 306 | /*-----------------------------------------------------------*/ 307 | 308 | static void prvInitialiseCoRoutineLists( void ) 309 | { 310 | UBaseType_t uxPriority; 311 | 312 | for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) 313 | { 314 | vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); 315 | } 316 | 317 | vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); 318 | vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); 319 | vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); 320 | 321 | /* Start with pxDelayedCoRoutineList using list1 and the 322 | pxOverflowDelayedCoRoutineList using list2. */ 323 | pxDelayedCoRoutineList = &xDelayedCoRoutineList1; 324 | pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; 325 | } 326 | /*-----------------------------------------------------------*/ 327 | 328 | BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) 329 | { 330 | CRCB_t *pxUnblockedCRCB; 331 | BaseType_t xReturn; 332 | 333 | /* This function is called from within an interrupt. It can only access 334 | event lists and the pending ready list. This function assumes that a 335 | check has already been made to ensure pxEventList is not empty. */ 336 | pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); 337 | ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 338 | vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); 339 | 340 | if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) 341 | { 342 | xReturn = pdTRUE; 343 | } 344 | else 345 | { 346 | xReturn = pdFALSE; 347 | } 348 | 349 | return xReturn; 350 | } 351 | 352 | #endif /* configUSE_CO_ROUTINES == 0 */ 353 | 354 | -------------------------------------------------------------------------------- /Source/portable/MemMang/heap_4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * A sample implementation of pvPortMalloc() and vPortFree() that combines 30 | * (coalescences) adjacent memory blocks as they are freed, and in so doing 31 | * limits memory fragmentation. 32 | * 33 | * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the 34 | * memory management pages of http://www.FreeRTOS.org for more information. 35 | */ 36 | #include 37 | 38 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 39 | all the API functions to use the MPU wrappers. That should only be done when 40 | task.h is included from an application file. */ 41 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 42 | 43 | #include "FreeRTOS.h" 44 | #include "task.h" 45 | 46 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 47 | 48 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 49 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 50 | #endif 51 | 52 | /* Block sizes must not get too small. */ 53 | #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) 54 | 55 | /* Assumes 8bit bytes! */ 56 | #define heapBITS_PER_BYTE ( ( size_t ) 8 ) 57 | 58 | /* Allocate the memory for the heap. */ 59 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 60 | /* The application writer has already defined the array used for the RTOS 61 | heap - probably so it can be placed in a special segment or address. */ 62 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 63 | #else 64 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 65 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 66 | 67 | /* Define the linked list structure. This is used to link free blocks in order 68 | of their memory address. */ 69 | typedef struct A_BLOCK_LINK 70 | { 71 | struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ 72 | size_t xBlockSize; /*<< The size of the free block. */ 73 | } BlockLink_t; 74 | 75 | /*-----------------------------------------------------------*/ 76 | 77 | /* 78 | * Inserts a block of memory that is being freed into the correct position in 79 | * the list of free memory blocks. The block being freed will be merged with 80 | * the block in front it and/or the block behind it if the memory blocks are 81 | * adjacent to each other. 82 | */ 83 | static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); 84 | 85 | /* 86 | * Called automatically to setup the required heap structures the first time 87 | * pvPortMalloc() is called. 88 | */ 89 | static void prvHeapInit( void ); 90 | 91 | /*-----------------------------------------------------------*/ 92 | 93 | /* The size of the structure placed at the beginning of each allocated memory 94 | block must by correctly byte aligned. */ 95 | static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 96 | 97 | /* Create a couple of list links to mark the start and end of the list. */ 98 | static BlockLink_t xStart, *pxEnd = NULL; 99 | 100 | /* Keeps track of the number of free bytes remaining, but says nothing about 101 | fragmentation. */ 102 | static size_t xFreeBytesRemaining = 0U; 103 | static size_t xMinimumEverFreeBytesRemaining = 0U; 104 | 105 | /* Gets set to the top bit of an size_t type. When this bit in the xBlockSize 106 | member of an BlockLink_t structure is set then the block belongs to the 107 | application. When the bit is free the block is still part of the free heap 108 | space. */ 109 | static size_t xBlockAllocatedBit = 0; 110 | 111 | /*-----------------------------------------------------------*/ 112 | 113 | void *pvPortMalloc( size_t xWantedSize ) 114 | { 115 | BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; 116 | void *pvReturn = NULL; 117 | 118 | vTaskSuspendAll(); 119 | { 120 | /* If this is the first call to malloc then the heap will require 121 | initialisation to setup the list of free blocks. */ 122 | if( pxEnd == NULL ) 123 | { 124 | prvHeapInit(); 125 | } 126 | else 127 | { 128 | mtCOVERAGE_TEST_MARKER(); 129 | } 130 | 131 | /* Check the requested block size is not so large that the top bit is 132 | set. The top bit of the block size member of the BlockLink_t structure 133 | is used to determine who owns the block - the application or the 134 | kernel, so it must be free. */ 135 | if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) 136 | { 137 | /* The wanted size is increased so it can contain a BlockLink_t 138 | structure in addition to the requested amount of bytes. */ 139 | if( xWantedSize > 0 ) 140 | { 141 | xWantedSize += xHeapStructSize; 142 | 143 | /* Ensure that blocks are always aligned to the required number 144 | of bytes. */ 145 | if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) 146 | { 147 | /* Byte alignment required. */ 148 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 149 | configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); 150 | } 151 | else 152 | { 153 | mtCOVERAGE_TEST_MARKER(); 154 | } 155 | } 156 | else 157 | { 158 | mtCOVERAGE_TEST_MARKER(); 159 | } 160 | 161 | if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) 162 | { 163 | /* Traverse the list from the start (lowest address) block until 164 | one of adequate size is found. */ 165 | pxPreviousBlock = &xStart; 166 | pxBlock = xStart.pxNextFreeBlock; 167 | while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) 168 | { 169 | pxPreviousBlock = pxBlock; 170 | pxBlock = pxBlock->pxNextFreeBlock; 171 | } 172 | 173 | /* If the end marker was reached then a block of adequate size 174 | was not found. */ 175 | if( pxBlock != pxEnd ) 176 | { 177 | /* Return the memory space pointed to - jumping over the 178 | BlockLink_t structure at its start. */ 179 | pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); 180 | 181 | /* This block is being returned for use so must be taken out 182 | of the list of free blocks. */ 183 | pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; 184 | 185 | /* If the block is larger than required it can be split into 186 | two. */ 187 | if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) 188 | { 189 | /* This block is to be split into two. Create a new 190 | block following the number of bytes requested. The void 191 | cast is used to prevent byte alignment warnings from the 192 | compiler. */ 193 | pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); 194 | configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); 195 | 196 | /* Calculate the sizes of two blocks split from the 197 | single block. */ 198 | pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; 199 | pxBlock->xBlockSize = xWantedSize; 200 | 201 | /* Insert the new block into the list of free blocks. */ 202 | prvInsertBlockIntoFreeList( pxNewBlockLink ); 203 | } 204 | else 205 | { 206 | mtCOVERAGE_TEST_MARKER(); 207 | } 208 | 209 | xFreeBytesRemaining -= pxBlock->xBlockSize; 210 | 211 | if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) 212 | { 213 | xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; 214 | } 215 | else 216 | { 217 | mtCOVERAGE_TEST_MARKER(); 218 | } 219 | 220 | /* The block is being returned - it is allocated and owned 221 | by the application and has no "next" block. */ 222 | pxBlock->xBlockSize |= xBlockAllocatedBit; 223 | pxBlock->pxNextFreeBlock = NULL; 224 | } 225 | else 226 | { 227 | mtCOVERAGE_TEST_MARKER(); 228 | } 229 | } 230 | else 231 | { 232 | mtCOVERAGE_TEST_MARKER(); 233 | } 234 | } 235 | else 236 | { 237 | mtCOVERAGE_TEST_MARKER(); 238 | } 239 | 240 | traceMALLOC( pvReturn, xWantedSize ); 241 | } 242 | ( void ) xTaskResumeAll(); 243 | 244 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 245 | { 246 | if( pvReturn == NULL ) 247 | { 248 | extern void vApplicationMallocFailedHook( void ); 249 | vApplicationMallocFailedHook(); 250 | } 251 | else 252 | { 253 | mtCOVERAGE_TEST_MARKER(); 254 | } 255 | } 256 | #endif 257 | 258 | configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); 259 | return pvReturn; 260 | } 261 | /*-----------------------------------------------------------*/ 262 | 263 | void vPortFree( void *pv ) 264 | { 265 | uint8_t *puc = ( uint8_t * ) pv; 266 | BlockLink_t *pxLink; 267 | 268 | if( pv != NULL ) 269 | { 270 | /* The memory being freed will have an BlockLink_t structure immediately 271 | before it. */ 272 | puc -= xHeapStructSize; 273 | 274 | /* This casting is to keep the compiler from issuing warnings. */ 275 | pxLink = ( void * ) puc; 276 | 277 | /* Check the block is actually allocated. */ 278 | configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); 279 | configASSERT( pxLink->pxNextFreeBlock == NULL ); 280 | 281 | if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) 282 | { 283 | if( pxLink->pxNextFreeBlock == NULL ) 284 | { 285 | /* The block is being returned to the heap - it is no longer 286 | allocated. */ 287 | pxLink->xBlockSize &= ~xBlockAllocatedBit; 288 | 289 | vTaskSuspendAll(); 290 | { 291 | /* Add this block to the list of free blocks. */ 292 | xFreeBytesRemaining += pxLink->xBlockSize; 293 | traceFREE( pv, pxLink->xBlockSize ); 294 | prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); 295 | } 296 | ( void ) xTaskResumeAll(); 297 | } 298 | else 299 | { 300 | mtCOVERAGE_TEST_MARKER(); 301 | } 302 | } 303 | else 304 | { 305 | mtCOVERAGE_TEST_MARKER(); 306 | } 307 | } 308 | } 309 | /*-----------------------------------------------------------*/ 310 | 311 | size_t xPortGetFreeHeapSize( void ) 312 | { 313 | return xFreeBytesRemaining; 314 | } 315 | /*-----------------------------------------------------------*/ 316 | 317 | size_t xPortGetMinimumEverFreeHeapSize( void ) 318 | { 319 | return xMinimumEverFreeBytesRemaining; 320 | } 321 | /*-----------------------------------------------------------*/ 322 | 323 | void vPortInitialiseBlocks( void ) 324 | { 325 | /* This just exists to keep the linker quiet. */ 326 | } 327 | /*-----------------------------------------------------------*/ 328 | 329 | static void prvHeapInit( void ) 330 | { 331 | BlockLink_t *pxFirstFreeBlock; 332 | uint8_t *pucAlignedHeap; 333 | size_t uxAddress; 334 | size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; 335 | 336 | /* Ensure the heap starts on a correctly aligned boundary. */ 337 | uxAddress = ( size_t ) ucHeap; 338 | 339 | if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) 340 | { 341 | uxAddress += ( portBYTE_ALIGNMENT - 1 ); 342 | uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 343 | xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; 344 | } 345 | 346 | pucAlignedHeap = ( uint8_t * ) uxAddress; 347 | 348 | /* xStart is used to hold a pointer to the first item in the list of free 349 | blocks. The void cast is used to prevent compiler warnings. */ 350 | xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; 351 | xStart.xBlockSize = ( size_t ) 0; 352 | 353 | /* pxEnd is used to mark the end of the list of free blocks and is inserted 354 | at the end of the heap space. */ 355 | uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; 356 | uxAddress -= xHeapStructSize; 357 | uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 358 | pxEnd = ( void * ) uxAddress; 359 | pxEnd->xBlockSize = 0; 360 | pxEnd->pxNextFreeBlock = NULL; 361 | 362 | /* To start with there is a single free block that is sized to take up the 363 | entire heap space, minus the space taken by pxEnd. */ 364 | pxFirstFreeBlock = ( void * ) pucAlignedHeap; 365 | pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; 366 | pxFirstFreeBlock->pxNextFreeBlock = pxEnd; 367 | 368 | /* Only one block exists - and it covers the entire usable heap space. */ 369 | xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; 370 | xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; 371 | 372 | /* Work out the position of the top bit in a size_t variable. */ 373 | xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); 374 | } 375 | /*-----------------------------------------------------------*/ 376 | 377 | static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) 378 | { 379 | BlockLink_t *pxIterator; 380 | uint8_t *puc; 381 | 382 | /* Iterate through the list until a block is found that has a higher address 383 | than the block being inserted. */ 384 | for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) 385 | { 386 | /* Nothing to do here, just iterate to the right position. */ 387 | } 388 | 389 | /* Do the block being inserted, and the block it is being inserted after 390 | make a contiguous block of memory? */ 391 | puc = ( uint8_t * ) pxIterator; 392 | if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) 393 | { 394 | pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; 395 | pxBlockToInsert = pxIterator; 396 | } 397 | else 398 | { 399 | mtCOVERAGE_TEST_MARKER(); 400 | } 401 | 402 | /* Do the block being inserted, and the block it is being inserted before 403 | make a contiguous block of memory? */ 404 | puc = ( uint8_t * ) pxBlockToInsert; 405 | if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) 406 | { 407 | if( pxIterator->pxNextFreeBlock != pxEnd ) 408 | { 409 | /* Form one big block from the two blocks. */ 410 | pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; 411 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; 412 | } 413 | else 414 | { 415 | pxBlockToInsert->pxNextFreeBlock = pxEnd; 416 | } 417 | } 418 | else 419 | { 420 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; 421 | } 422 | 423 | /* If the block being inserted plugged a gab, so was merged with the block 424 | before and the block after, then it's pxNextFreeBlock pointer will have 425 | already been set, and should not be set here as that would make it point 426 | to itself. */ 427 | if( pxIterator != pxBlockToInsert ) 428 | { 429 | pxIterator->pxNextFreeBlock = pxBlockToInsert; 430 | } 431 | else 432 | { 433 | mtCOVERAGE_TEST_MARKER(); 434 | } 435 | } 436 | 437 | -------------------------------------------------------------------------------- /Source/portable/MemMang/heap_5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * A sample implementation of pvPortMalloc() that allows the heap to be defined 30 | * across multiple non-contigous blocks and combines (coalescences) adjacent 31 | * memory blocks as they are freed. 32 | * 33 | * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative 34 | * implementations, and the memory management pages of http://www.FreeRTOS.org 35 | * for more information. 36 | * 37 | * Usage notes: 38 | * 39 | * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). 40 | * pvPortMalloc() will be called if any task objects (tasks, queues, event 41 | * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be 42 | * called before any other objects are defined. 43 | * 44 | * vPortDefineHeapRegions() takes a single parameter. The parameter is an array 45 | * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as 46 | * 47 | * typedef struct HeapRegion 48 | * { 49 | * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. 50 | * size_t xSizeInBytes; << Size of the block of memory. 51 | * } HeapRegion_t; 52 | * 53 | * The array is terminated using a NULL zero sized region definition, and the 54 | * memory regions defined in the array ***must*** appear in address order from 55 | * low address to high address. So the following is a valid example of how 56 | * to use the function. 57 | * 58 | * HeapRegion_t xHeapRegions[] = 59 | * { 60 | * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 61 | * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 62 | * { NULL, 0 } << Terminates the array. 63 | * }; 64 | * 65 | * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). 66 | * 67 | * Note 0x80000000 is the lower address so appears in the array first. 68 | * 69 | */ 70 | #include 71 | 72 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 73 | all the API functions to use the MPU wrappers. That should only be done when 74 | task.h is included from an application file. */ 75 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 76 | 77 | #include "FreeRTOS.h" 78 | #include "task.h" 79 | 80 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 81 | 82 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 83 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 84 | #endif 85 | 86 | /* Block sizes must not get too small. */ 87 | #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) 88 | 89 | /* Assumes 8bit bytes! */ 90 | #define heapBITS_PER_BYTE ( ( size_t ) 8 ) 91 | 92 | /* Define the linked list structure. This is used to link free blocks in order 93 | of their memory address. */ 94 | typedef struct A_BLOCK_LINK 95 | { 96 | struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ 97 | size_t xBlockSize; /*<< The size of the free block. */ 98 | } BlockLink_t; 99 | 100 | /*-----------------------------------------------------------*/ 101 | 102 | /* 103 | * Inserts a block of memory that is being freed into the correct position in 104 | * the list of free memory blocks. The block being freed will be merged with 105 | * the block in front it and/or the block behind it if the memory blocks are 106 | * adjacent to each other. 107 | */ 108 | static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); 109 | 110 | /*-----------------------------------------------------------*/ 111 | 112 | /* The size of the structure placed at the beginning of each allocated memory 113 | block must by correctly byte aligned. */ 114 | static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 115 | 116 | /* Create a couple of list links to mark the start and end of the list. */ 117 | static BlockLink_t xStart, *pxEnd = NULL; 118 | 119 | /* Keeps track of the number of free bytes remaining, but says nothing about 120 | fragmentation. */ 121 | static size_t xFreeBytesRemaining = 0U; 122 | static size_t xMinimumEverFreeBytesRemaining = 0U; 123 | 124 | /* Gets set to the top bit of an size_t type. When this bit in the xBlockSize 125 | member of an BlockLink_t structure is set then the block belongs to the 126 | application. When the bit is free the block is still part of the free heap 127 | space. */ 128 | static size_t xBlockAllocatedBit = 0; 129 | 130 | /*-----------------------------------------------------------*/ 131 | 132 | void *pvPortMalloc( size_t xWantedSize ) 133 | { 134 | BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; 135 | void *pvReturn = NULL; 136 | 137 | /* The heap must be initialised before the first call to 138 | prvPortMalloc(). */ 139 | configASSERT( pxEnd ); 140 | 141 | vTaskSuspendAll(); 142 | { 143 | /* Check the requested block size is not so large that the top bit is 144 | set. The top bit of the block size member of the BlockLink_t structure 145 | is used to determine who owns the block - the application or the 146 | kernel, so it must be free. */ 147 | if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) 148 | { 149 | /* The wanted size is increased so it can contain a BlockLink_t 150 | structure in addition to the requested amount of bytes. */ 151 | if( xWantedSize > 0 ) 152 | { 153 | xWantedSize += xHeapStructSize; 154 | 155 | /* Ensure that blocks are always aligned to the required number 156 | of bytes. */ 157 | if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) 158 | { 159 | /* Byte alignment required. */ 160 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 161 | } 162 | else 163 | { 164 | mtCOVERAGE_TEST_MARKER(); 165 | } 166 | } 167 | else 168 | { 169 | mtCOVERAGE_TEST_MARKER(); 170 | } 171 | 172 | if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) 173 | { 174 | /* Traverse the list from the start (lowest address) block until 175 | one of adequate size is found. */ 176 | pxPreviousBlock = &xStart; 177 | pxBlock = xStart.pxNextFreeBlock; 178 | while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) 179 | { 180 | pxPreviousBlock = pxBlock; 181 | pxBlock = pxBlock->pxNextFreeBlock; 182 | } 183 | 184 | /* If the end marker was reached then a block of adequate size 185 | was not found. */ 186 | if( pxBlock != pxEnd ) 187 | { 188 | /* Return the memory space pointed to - jumping over the 189 | BlockLink_t structure at its start. */ 190 | pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); 191 | 192 | /* This block is being returned for use so must be taken out 193 | of the list of free blocks. */ 194 | pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; 195 | 196 | /* If the block is larger than required it can be split into 197 | two. */ 198 | if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) 199 | { 200 | /* This block is to be split into two. Create a new 201 | block following the number of bytes requested. The void 202 | cast is used to prevent byte alignment warnings from the 203 | compiler. */ 204 | pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); 205 | 206 | /* Calculate the sizes of two blocks split from the 207 | single block. */ 208 | pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; 209 | pxBlock->xBlockSize = xWantedSize; 210 | 211 | /* Insert the new block into the list of free blocks. */ 212 | prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); 213 | } 214 | else 215 | { 216 | mtCOVERAGE_TEST_MARKER(); 217 | } 218 | 219 | xFreeBytesRemaining -= pxBlock->xBlockSize; 220 | 221 | if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) 222 | { 223 | xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; 224 | } 225 | else 226 | { 227 | mtCOVERAGE_TEST_MARKER(); 228 | } 229 | 230 | /* The block is being returned - it is allocated and owned 231 | by the application and has no "next" block. */ 232 | pxBlock->xBlockSize |= xBlockAllocatedBit; 233 | pxBlock->pxNextFreeBlock = NULL; 234 | } 235 | else 236 | { 237 | mtCOVERAGE_TEST_MARKER(); 238 | } 239 | } 240 | else 241 | { 242 | mtCOVERAGE_TEST_MARKER(); 243 | } 244 | } 245 | else 246 | { 247 | mtCOVERAGE_TEST_MARKER(); 248 | } 249 | 250 | traceMALLOC( pvReturn, xWantedSize ); 251 | } 252 | ( void ) xTaskResumeAll(); 253 | 254 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 255 | { 256 | if( pvReturn == NULL ) 257 | { 258 | extern void vApplicationMallocFailedHook( void ); 259 | vApplicationMallocFailedHook(); 260 | } 261 | else 262 | { 263 | mtCOVERAGE_TEST_MARKER(); 264 | } 265 | } 266 | #endif 267 | 268 | return pvReturn; 269 | } 270 | /*-----------------------------------------------------------*/ 271 | 272 | void vPortFree( void *pv ) 273 | { 274 | uint8_t *puc = ( uint8_t * ) pv; 275 | BlockLink_t *pxLink; 276 | 277 | if( pv != NULL ) 278 | { 279 | /* The memory being freed will have an BlockLink_t structure immediately 280 | before it. */ 281 | puc -= xHeapStructSize; 282 | 283 | /* This casting is to keep the compiler from issuing warnings. */ 284 | pxLink = ( void * ) puc; 285 | 286 | /* Check the block is actually allocated. */ 287 | configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); 288 | configASSERT( pxLink->pxNextFreeBlock == NULL ); 289 | 290 | if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) 291 | { 292 | if( pxLink->pxNextFreeBlock == NULL ) 293 | { 294 | /* The block is being returned to the heap - it is no longer 295 | allocated. */ 296 | pxLink->xBlockSize &= ~xBlockAllocatedBit; 297 | 298 | vTaskSuspendAll(); 299 | { 300 | /* Add this block to the list of free blocks. */ 301 | xFreeBytesRemaining += pxLink->xBlockSize; 302 | traceFREE( pv, pxLink->xBlockSize ); 303 | prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); 304 | } 305 | ( void ) xTaskResumeAll(); 306 | } 307 | else 308 | { 309 | mtCOVERAGE_TEST_MARKER(); 310 | } 311 | } 312 | else 313 | { 314 | mtCOVERAGE_TEST_MARKER(); 315 | } 316 | } 317 | } 318 | /*-----------------------------------------------------------*/ 319 | 320 | size_t xPortGetFreeHeapSize( void ) 321 | { 322 | return xFreeBytesRemaining; 323 | } 324 | /*-----------------------------------------------------------*/ 325 | 326 | size_t xPortGetMinimumEverFreeHeapSize( void ) 327 | { 328 | return xMinimumEverFreeBytesRemaining; 329 | } 330 | /*-----------------------------------------------------------*/ 331 | 332 | static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) 333 | { 334 | BlockLink_t *pxIterator; 335 | uint8_t *puc; 336 | 337 | /* Iterate through the list until a block is found that has a higher address 338 | than the block being inserted. */ 339 | for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) 340 | { 341 | /* Nothing to do here, just iterate to the right position. */ 342 | } 343 | 344 | /* Do the block being inserted, and the block it is being inserted after 345 | make a contiguous block of memory? */ 346 | puc = ( uint8_t * ) pxIterator; 347 | if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) 348 | { 349 | pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; 350 | pxBlockToInsert = pxIterator; 351 | } 352 | else 353 | { 354 | mtCOVERAGE_TEST_MARKER(); 355 | } 356 | 357 | /* Do the block being inserted, and the block it is being inserted before 358 | make a contiguous block of memory? */ 359 | puc = ( uint8_t * ) pxBlockToInsert; 360 | if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) 361 | { 362 | if( pxIterator->pxNextFreeBlock != pxEnd ) 363 | { 364 | /* Form one big block from the two blocks. */ 365 | pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; 366 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; 367 | } 368 | else 369 | { 370 | pxBlockToInsert->pxNextFreeBlock = pxEnd; 371 | } 372 | } 373 | else 374 | { 375 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; 376 | } 377 | 378 | /* If the block being inserted plugged a gab, so was merged with the block 379 | before and the block after, then it's pxNextFreeBlock pointer will have 380 | already been set, and should not be set here as that would make it point 381 | to itself. */ 382 | if( pxIterator != pxBlockToInsert ) 383 | { 384 | pxIterator->pxNextFreeBlock = pxBlockToInsert; 385 | } 386 | else 387 | { 388 | mtCOVERAGE_TEST_MARKER(); 389 | } 390 | } 391 | /*-----------------------------------------------------------*/ 392 | 393 | void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) 394 | { 395 | BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; 396 | size_t xAlignedHeap; 397 | size_t xTotalRegionSize, xTotalHeapSize = 0; 398 | BaseType_t xDefinedRegions = 0; 399 | size_t xAddress; 400 | const HeapRegion_t *pxHeapRegion; 401 | 402 | /* Can only call once! */ 403 | configASSERT( pxEnd == NULL ); 404 | 405 | pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); 406 | 407 | while( pxHeapRegion->xSizeInBytes > 0 ) 408 | { 409 | xTotalRegionSize = pxHeapRegion->xSizeInBytes; 410 | 411 | /* Ensure the heap region starts on a correctly aligned boundary. */ 412 | xAddress = ( size_t ) pxHeapRegion->pucStartAddress; 413 | if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) 414 | { 415 | xAddress += ( portBYTE_ALIGNMENT - 1 ); 416 | xAddress &= ~portBYTE_ALIGNMENT_MASK; 417 | 418 | /* Adjust the size for the bytes lost to alignment. */ 419 | xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress; 420 | } 421 | 422 | xAlignedHeap = xAddress; 423 | 424 | /* Set xStart if it has not already been set. */ 425 | if( xDefinedRegions == 0 ) 426 | { 427 | /* xStart is used to hold a pointer to the first item in the list of 428 | free blocks. The void cast is used to prevent compiler warnings. */ 429 | xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap; 430 | xStart.xBlockSize = ( size_t ) 0; 431 | } 432 | else 433 | { 434 | /* Should only get here if one region has already been added to the 435 | heap. */ 436 | configASSERT( pxEnd != NULL ); 437 | 438 | /* Check blocks are passed in with increasing start addresses. */ 439 | configASSERT( xAddress > ( size_t ) pxEnd ); 440 | } 441 | 442 | /* Remember the location of the end marker in the previous region, if 443 | any. */ 444 | pxPreviousFreeBlock = pxEnd; 445 | 446 | /* pxEnd is used to mark the end of the list of free blocks and is 447 | inserted at the end of the region space. */ 448 | xAddress = xAlignedHeap + xTotalRegionSize; 449 | xAddress -= xHeapStructSize; 450 | xAddress &= ~portBYTE_ALIGNMENT_MASK; 451 | pxEnd = ( BlockLink_t * ) xAddress; 452 | pxEnd->xBlockSize = 0; 453 | pxEnd->pxNextFreeBlock = NULL; 454 | 455 | /* To start with there is a single free block in this region that is 456 | sized to take up the entire heap region minus the space taken by the 457 | free block structure. */ 458 | pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; 459 | pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion; 460 | pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; 461 | 462 | /* If this is not the first region that makes up the entire heap space 463 | then link the previous region to this region. */ 464 | if( pxPreviousFreeBlock != NULL ) 465 | { 466 | pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; 467 | } 468 | 469 | xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; 470 | 471 | /* Move onto the next HeapRegion_t structure. */ 472 | xDefinedRegions++; 473 | pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); 474 | } 475 | 476 | xMinimumEverFreeBytesRemaining = xTotalHeapSize; 477 | xFreeBytesRemaining = xTotalHeapSize; 478 | 479 | /* Check something was actually defined before it is accessed. */ 480 | configASSERT( xTotalHeapSize ); 481 | 482 | /* Work out the position of the top bit in a size_t variable. */ 483 | xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); 484 | } 485 | 486 | -------------------------------------------------------------------------------- /Source/include/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.1.1 3 | * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * This is the list implementation used by the scheduler. While it is tailored 30 | * heavily for the schedulers needs, it is also available for use by 31 | * application code. 32 | * 33 | * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a 34 | * numeric value (xItemValue). Most of the time the lists are sorted in 35 | * descending item value order. 36 | * 37 | * Lists are created already containing one list item. The value of this 38 | * item is the maximum possible that can be stored, it is therefore always at 39 | * the end of the list and acts as a marker. The list member pxHead always 40 | * points to this marker - even though it is at the tail of the list. This 41 | * is because the tail contains a wrap back pointer to the true head of 42 | * the list. 43 | * 44 | * In addition to it's value, each list item contains a pointer to the next 45 | * item in the list (pxNext), a pointer to the list it is in (pxContainer) 46 | * and a pointer to back to the object that contains it. These later two 47 | * pointers are included for efficiency of list manipulation. There is 48 | * effectively a two way link between the object containing the list item and 49 | * the list item itself. 50 | * 51 | * 52 | * \page ListIntroduction List Implementation 53 | * \ingroup FreeRTOSIntro 54 | */ 55 | 56 | #ifndef INC_FREERTOS_H 57 | #error FreeRTOS.h must be included before list.h 58 | #endif 59 | 60 | #ifndef LIST_H 61 | #define LIST_H 62 | 63 | /* 64 | * The list structure members are modified from within interrupts, and therefore 65 | * by rights should be declared volatile. However, they are only modified in a 66 | * functionally atomic way (within critical sections of with the scheduler 67 | * suspended) and are either passed by reference into a function or indexed via 68 | * a volatile variable. Therefore, in all use cases tested so far, the volatile 69 | * qualifier can be omitted in order to provide a moderate performance 70 | * improvement without adversely affecting functional behaviour. The assembly 71 | * instructions generated by the IAR, ARM and GCC compilers when the respective 72 | * compiler's options were set for maximum optimisation has been inspected and 73 | * deemed to be as intended. That said, as compiler technology advances, and 74 | * especially if aggressive cross module optimisation is used (a use case that 75 | * has not been exercised to any great extend) then it is feasible that the 76 | * volatile qualifier will be needed for correct optimisation. It is expected 77 | * that a compiler removing essential code because, without the volatile 78 | * qualifier on the list structure members and with aggressive cross module 79 | * optimisation, the compiler deemed the code unnecessary will result in 80 | * complete and obvious failure of the scheduler. If this is ever experienced 81 | * then the volatile qualifier can be inserted in the relevant places within the 82 | * list structures by simply defining configLIST_VOLATILE to volatile in 83 | * FreeRTOSConfig.h (as per the example at the bottom of this comment block). 84 | * If configLIST_VOLATILE is not defined then the preprocessor directives below 85 | * will simply #define configLIST_VOLATILE away completely. 86 | * 87 | * To use volatile list structure members then add the following line to 88 | * FreeRTOSConfig.h (without the quotes): 89 | * "#define configLIST_VOLATILE volatile" 90 | */ 91 | #ifndef configLIST_VOLATILE 92 | #define configLIST_VOLATILE 93 | #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ 94 | 95 | #ifdef __cplusplus 96 | extern "C" { 97 | #endif 98 | 99 | /* Macros that can be used to place known values within the list structures, 100 | then check that the known values do not get corrupted during the execution of 101 | the application. These may catch the list data structures being overwritten in 102 | memory. They will not catch data errors caused by incorrect configuration or 103 | use of FreeRTOS.*/ 104 | #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) 105 | /* Define the macros to do nothing. */ 106 | #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE 107 | #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE 108 | #define listFIRST_LIST_INTEGRITY_CHECK_VALUE 109 | #define listSECOND_LIST_INTEGRITY_CHECK_VALUE 110 | #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) 111 | #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) 112 | #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) 113 | #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) 114 | #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) 115 | #define listTEST_LIST_INTEGRITY( pxList ) 116 | #else 117 | /* Define macros that add new members into the list structures. */ 118 | #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; 119 | #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; 120 | #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; 121 | #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; 122 | 123 | /* Define macros that set the new structure members to known values. */ 124 | #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE 125 | #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE 126 | #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE 127 | #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE 128 | 129 | /* Define macros that will assert if one of the structure members does not 130 | contain its expected value. */ 131 | #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) 132 | #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) 133 | #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ 134 | 135 | 136 | /* 137 | * Definition of the only type of object that a list can contain. 138 | */ 139 | struct xLIST; 140 | struct xLIST_ITEM 141 | { 142 | listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 143 | configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ 144 | struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ 145 | struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ 146 | void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ 147 | struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ 148 | listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 149 | }; 150 | typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ 151 | 152 | struct xMINI_LIST_ITEM 153 | { 154 | listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 155 | configLIST_VOLATILE TickType_t xItemValue; 156 | struct xLIST_ITEM * configLIST_VOLATILE pxNext; 157 | struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; 158 | }; 159 | typedef struct xMINI_LIST_ITEM MiniListItem_t; 160 | 161 | /* 162 | * Definition of the type of queue used by the scheduler. 163 | */ 164 | typedef struct xLIST 165 | { 166 | listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 167 | volatile UBaseType_t uxNumberOfItems; 168 | ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ 169 | MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ 170 | listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 171 | } List_t; 172 | 173 | /* 174 | * Access macro to set the owner of a list item. The owner of a list item 175 | * is the object (usually a TCB) that contains the list item. 176 | * 177 | * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER 178 | * \ingroup LinkedList 179 | */ 180 | #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) 181 | 182 | /* 183 | * Access macro to get the owner of a list item. The owner of a list item 184 | * is the object (usually a TCB) that contains the list item. 185 | * 186 | * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER 187 | * \ingroup LinkedList 188 | */ 189 | #define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) 190 | 191 | /* 192 | * Access macro to set the value of the list item. In most cases the value is 193 | * used to sort the list in descending order. 194 | * 195 | * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE 196 | * \ingroup LinkedList 197 | */ 198 | #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) 199 | 200 | /* 201 | * Access macro to retrieve the value of the list item. The value can 202 | * represent anything - for example the priority of a task, or the time at 203 | * which a task should be unblocked. 204 | * 205 | * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE 206 | * \ingroup LinkedList 207 | */ 208 | #define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) 209 | 210 | /* 211 | * Access macro to retrieve the value of the list item at the head of a given 212 | * list. 213 | * 214 | * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE 215 | * \ingroup LinkedList 216 | */ 217 | #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) 218 | 219 | /* 220 | * Return the list item at the head of the list. 221 | * 222 | * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY 223 | * \ingroup LinkedList 224 | */ 225 | #define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) 226 | 227 | /* 228 | * Return the list item at the head of the list. 229 | * 230 | * \page listGET_NEXT listGET_NEXT 231 | * \ingroup LinkedList 232 | */ 233 | #define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) 234 | 235 | /* 236 | * Return the list item that marks the end of the list 237 | * 238 | * \page listGET_END_MARKER listGET_END_MARKER 239 | * \ingroup LinkedList 240 | */ 241 | #define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) 242 | 243 | /* 244 | * Access macro to determine if a list contains any items. The macro will 245 | * only have the value true if the list is empty. 246 | * 247 | * \page listLIST_IS_EMPTY listLIST_IS_EMPTY 248 | * \ingroup LinkedList 249 | */ 250 | #define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) 251 | 252 | /* 253 | * Access macro to return the number of items in the list. 254 | */ 255 | #define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) 256 | 257 | /* 258 | * Access function to obtain the owner of the next entry in a list. 259 | * 260 | * The list member pxIndex is used to walk through a list. Calling 261 | * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list 262 | * and returns that entry's pxOwner parameter. Using multiple calls to this 263 | * function it is therefore possible to move through every item contained in 264 | * a list. 265 | * 266 | * The pxOwner parameter of a list item is a pointer to the object that owns 267 | * the list item. In the scheduler this is normally a task control block. 268 | * The pxOwner parameter effectively creates a two way link between the list 269 | * item and its owner. 270 | * 271 | * @param pxTCB pxTCB is set to the address of the owner of the next list item. 272 | * @param pxList The list from which the next item owner is to be returned. 273 | * 274 | * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY 275 | * \ingroup LinkedList 276 | */ 277 | #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ 278 | { \ 279 | List_t * const pxConstList = ( pxList ); \ 280 | /* Increment the index to the next item and return the item, ensuring */ \ 281 | /* we don't return the marker used at the end of the list. */ \ 282 | ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ 283 | if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ 284 | { \ 285 | ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ 286 | } \ 287 | ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ 288 | } 289 | 290 | 291 | /* 292 | * Access function to obtain the owner of the first entry in a list. Lists 293 | * are normally sorted in ascending item value order. 294 | * 295 | * This function returns the pxOwner member of the first item in the list. 296 | * The pxOwner parameter of a list item is a pointer to the object that owns 297 | * the list item. In the scheduler this is normally a task control block. 298 | * The pxOwner parameter effectively creates a two way link between the list 299 | * item and its owner. 300 | * 301 | * @param pxList The list from which the owner of the head item is to be 302 | * returned. 303 | * 304 | * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY 305 | * \ingroup LinkedList 306 | */ 307 | #define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) 308 | 309 | /* 310 | * Check to see if a list item is within a list. The list item maintains a 311 | * "container" pointer that points to the list it is in. All this macro does 312 | * is check to see if the container and the list match. 313 | * 314 | * @param pxList The list we want to know if the list item is within. 315 | * @param pxListItem The list item we want to know if is in the list. 316 | * @return pdTRUE if the list item is in the list, otherwise pdFALSE. 317 | */ 318 | #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) 319 | 320 | /* 321 | * Return the list a list item is contained within (referenced from). 322 | * 323 | * @param pxListItem The list item being queried. 324 | * @return A pointer to the List_t object that references the pxListItem 325 | */ 326 | #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) 327 | 328 | /* 329 | * This provides a crude means of knowing if a list has been initialised, as 330 | * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() 331 | * function. 332 | */ 333 | #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) 334 | 335 | /* 336 | * Must be called before a list is used! This initialises all the members 337 | * of the list structure and inserts the xListEnd item into the list as a 338 | * marker to the back of the list. 339 | * 340 | * @param pxList Pointer to the list being initialised. 341 | * 342 | * \page vListInitialise vListInitialise 343 | * \ingroup LinkedList 344 | */ 345 | void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; 346 | 347 | /* 348 | * Must be called before a list item is used. This sets the list container to 349 | * null so the item does not think that it is already contained in a list. 350 | * 351 | * @param pxItem Pointer to the list item being initialised. 352 | * 353 | * \page vListInitialiseItem vListInitialiseItem 354 | * \ingroup LinkedList 355 | */ 356 | void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; 357 | 358 | /* 359 | * Insert a list item into a list. The item will be inserted into the list in 360 | * a position determined by its item value (descending item value order). 361 | * 362 | * @param pxList The list into which the item is to be inserted. 363 | * 364 | * @param pxNewListItem The item that is to be placed in the list. 365 | * 366 | * \page vListInsert vListInsert 367 | * \ingroup LinkedList 368 | */ 369 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 370 | 371 | /* 372 | * Insert a list item into a list. The item will be inserted in a position 373 | * such that it will be the last item within the list returned by multiple 374 | * calls to listGET_OWNER_OF_NEXT_ENTRY. 375 | * 376 | * The list member pxIndex is used to walk through a list. Calling 377 | * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. 378 | * Placing an item in a list using vListInsertEnd effectively places the item 379 | * in the list position pointed to by pxIndex. This means that every other 380 | * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before 381 | * the pxIndex parameter again points to the item being inserted. 382 | * 383 | * @param pxList The list into which the item is to be inserted. 384 | * 385 | * @param pxNewListItem The list item to be inserted into the list. 386 | * 387 | * \page vListInsertEnd vListInsertEnd 388 | * \ingroup LinkedList 389 | */ 390 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 391 | 392 | /* 393 | * Remove an item from a list. The list item has a pointer to the list that 394 | * it is in, so only the list item need be passed into the function. 395 | * 396 | * @param uxListRemove The item to be removed. The item will remove itself from 397 | * the list pointed to by it's pxContainer parameter. 398 | * 399 | * @return The number of items that remain in the list after the list item has 400 | * been removed. 401 | * 402 | * \page uxListRemove uxListRemove 403 | * \ingroup LinkedList 404 | */ 405 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; 406 | 407 | #ifdef __cplusplus 408 | } 409 | #endif 410 | 411 | #endif 412 | 413 | --------------------------------------------------------------------------------