diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index 9c7fabc89b..46686a18e8 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -21,6 +21,7 @@ set(arch "linux") endif() set(srcs + "heap_idf.c" "${kernel_dir}/list.c" "${kernel_dir}/queue.c" "${kernel_dir}/tasks.c" diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h index c5d0f40b92..a9567deb4c 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -286,15 +286,32 @@ static inline bool IRAM_ATTR xPortCanYield(void) void vPortSetStackWatchpoint(void *pxStackStart); -#define portVALID_TCB_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY -#define portVALID_STACK_MEM(ptr) (esp_ptr_byte_accessible(ptr)) -#else -#define portVALID_STACK_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#endif +// -------------------- Heap Related ----------------------- -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +bool xPortCheckValidTCBMem(const void *ptr); + +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +bool xPortcheckValidStackMem(const void *ptr); + +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) /* ------------------------------------------------------ Misc --------------------------------------------------------- * - Miscellaneous porting macros diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 7533422c76..686fd0dc59 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -349,42 +349,6 @@ void vPortEndScheduler(void) abort(); } -// ----------------------- Memory -------------------------- - -#define FREERTOS_SMP_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) - -void *pvPortMalloc( size_t xSize ) -{ - return heap_caps_malloc(xSize, FREERTOS_SMP_MALLOC_CAPS); -} - -void vPortFree( void *pv ) -{ - heap_caps_free(pv); -} - -void vPortInitialiseBlocks( void ) -{ - ; //Does nothing, heap is initialized separately in ESP-IDF -} - -size_t xPortGetFreeHeapSize( void ) -{ - return esp_get_free_heap_size(); -} - -#if( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) -void *pvPortMallocStack( size_t xSize ) -{ - return NULL; -} - -void vPortFreeStack( void *pv ) -{ - -} -#endif - // ------------------------ Stack -------------------------- /** diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h index ae8b5875b6..d0104b7b36 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -352,15 +352,32 @@ static inline bool IRAM_ATTR xPortCanYield(void) void vPortSetStackWatchpoint(void *pxStackStart); -#define portVALID_TCB_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY -#define portVALID_STACK_MEM(ptr) (esp_ptr_byte_accessible(ptr)) -#else -#define portVALID_STACK_MEM(ptr) (esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr)) -#endif +// -------------------- Heap Related ----------------------- -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +bool xPortCheckValidTCBMem(const void *ptr); + +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +bool xPortcheckValidStackMem(const void *ptr); + +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) // --------------- Compatibility Includes ------------------ /* diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index 1417166b3f..a019d823d5 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -386,42 +386,6 @@ void vPortEndScheduler( void ) ; } -// ----------------------- Memory -------------------------- - -#define FREERTOS_SMP_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) - -void *pvPortMalloc( size_t xSize ) -{ - return heap_caps_malloc(xSize, FREERTOS_SMP_MALLOC_CAPS); -} - -void vPortFree( void *pv ) -{ - heap_caps_free(pv); -} - -void vPortInitialiseBlocks( void ) -{ - ; //Does nothing, heap is initialized separately in ESP-IDF -} - -size_t xPortGetFreeHeapSize( void ) -{ - return esp_get_free_heap_size(); -} - -#if( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) -void *pvPortMallocStack( size_t xSize ) -{ - return NULL; -} - -void vPortFreeStack( void *pv ) -{ - -} -#endif - // ------------------------ Stack -------------------------- // User exception dispatcher when exiting diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h b/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h index 684493e072..baffde6b5a 100644 --- a/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h +++ b/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h @@ -139,8 +139,6 @@ #endif #endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */ -#ifdef configUSE_FREERTOS_PROVIDED_HEAP - /* Used by heap_5.c to define the start address and size of each memory region * that together comprise the total FreeRTOS heap space. */ typedef struct HeapRegion @@ -189,29 +187,6 @@ void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; -#if( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) - void *pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION; - void vPortFreeStack( void *pv ) PRIVILEGED_FUNCTION; -#else - #define pvPortMallocStack pvPortMalloc - #define vPortFreeStack vPortFree -#endif -#else // configUSE_FREERTOS_PROVIDED_HEAP - -/* - * Map to the memory management routines required for the port. - * - * Note that libc standard malloc/free are also available for - * non-FreeRTOS-specific code, and behave the same as - * pvPortMalloc()/vPortFree(). - */ -#define pvPortMalloc malloc -#define vPortFree free -#define xPortGetFreeHeapSize esp_get_free_heap_size -#define xPortGetMinimumEverFreeHeapSize esp_get_minimum_free_heap_size - -#endif - /* * Setup the hardware ready for the scheduler to take control. This generally * sets up a tick interrupt and sets timers for the correct tick frequency. diff --git a/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h b/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h index bc573f3957..56aa9a762d 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h +++ b/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h @@ -51,18 +51,30 @@ static inline BaseType_t IRAM_ATTR xPortGetCoreID(void) return (BaseType_t) 0; } -static inline bool portVALID_TCB_MEM(const void *ptr) -{ - return true; -} +/** + * @brief Checks if a given piece of memory can be used to store a task's TCB + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a TCB + * @return false Otherwise + */ +bool xPortCheckValidTCBMem(const void *ptr); -static inline bool portVALID_STACK_MEM(const void *ptr) -{ - return true; -} +/** + * @brief Checks if a given piece of memory can be used to store a task's stack + * + * - Defined in heap_idf.c + * + * @param ptr Pointer to memory + * @return true Memory can be used to store a task stack + * @return false Otherwise + */ +bool xPortcheckValidStackMem(const void *ptr); -#define pvPortMallocTcbMem(size) pvPortMalloc(size) -#define pvPortMallocStackMem(size) pvPortMalloc(size) +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) BaseType_t xPortCheckIfInISR(void); diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h index 102e869f28..055ee33881 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h @@ -303,20 +303,6 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void) * - Maps to forward declared functions * ------------------------------------------------------------------------------------------------------------------ */ -// ----------------------- Memory -------------------------- - -/** - * @brief Task memory allocation macros - * - * @note Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force the stack - * memory to always be internal. - * @note [refactor-todo] Update portable.h to match v10.4.3 to use new malloc prototypes - */ -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define pvPortMallocTcbMem(size) pvPortMalloc(size) -#define pvPortMallocStackMem(size) pvPortMalloc(size) - // --------------------- Interrupts ------------------------ #define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK_FROM_ISR() @@ -446,7 +432,7 @@ FORCE_INLINE_ATTR bool xPortCanYield(void) /** * @brief Checks if a given piece of memory can be used to store a task's TCB * - * - Defined in port_common.c + * - Defined in heap_idf.c * * @param ptr Pointer to memory * @return true Memory can be used to store a TCB @@ -457,7 +443,7 @@ bool xPortCheckValidTCBMem(const void *ptr); /** * @brief Checks if a given piece of memory can be used to store a task's stack * - * - Defined in port_common.c + * - Defined in heap_idf.c * * @param ptr Pointer to memory * @return true Memory can be used to store a task stack @@ -465,8 +451,8 @@ bool xPortCheckValidTCBMem(const void *ptr); */ bool xPortcheckValidStackMem(const void *ptr); -#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) -#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) // --------------------- App-Trace ------------------------- diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h index 4dfa19fb62..a1adffbd4f 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h @@ -414,20 +414,6 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void); * - Maps to forward declared functions * ------------------------------------------------------------------------------------------------------------------ */ -// ----------------------- Memory -------------------------- - -/** - * @brief Task memory allocation macros - * - * @note Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force the stack - * memory to always be internal. - * @note [refactor-todo] Update portable.h to match v10.4.3 to use new malloc prototypes - */ -#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) -#define pvPortMallocTcbMem(size) heap_caps_malloc(size, portTcbMemoryCaps) -#define pvPortMallocStackMem(size) heap_caps_malloc(size, portStackMemoryCaps) - // --------------------- Interrupts ------------------------ /** @@ -656,7 +642,7 @@ void vPortCleanUpCoprocArea(void *pvTCB); /** * @brief Checks if a given piece of memory can be used to store a task's TCB * - * - Defined in port_common.c + * - Defined in heap_idf.c * * @param ptr Pointer to memory * @return true Memory can be used to store a TCB @@ -667,7 +653,7 @@ bool xPortCheckValidTCBMem(const void *ptr); /** * @brief Checks if a given piece of memory can be used to store a task's stack * - * - Defined in port_common.c + * - Defined in heap_idf.c * * @param ptr Pointer to memory * @return true Memory can be used to store a task stack @@ -675,8 +661,8 @@ bool xPortCheckValidTCBMem(const void *ptr); */ bool xPortcheckValidStackMem(const void *ptr); -#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) -#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) +#define portVALID_TCB_MEM(ptr) xPortCheckValidTCBMem(ptr) +#define portVALID_STACK_MEM(ptr) xPortcheckValidStackMem(ptr) // --------------------- App-Trace ------------------------- diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index c86cc3b0d4..d4f485625a 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -820,7 +820,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* Allocate space for the TCB. Where the memory comes from depends * on the implementation of the port malloc function and whether or * not static allocation is being used. */ - pxNewTCB = ( TCB_t * ) pvPortMallocTcbMem( sizeof( TCB_t ) ); + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) { @@ -877,14 +877,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* Allocate space for the TCB. Where the memory comes from depends on * the implementation of the port malloc function and whether or not static * allocation is being used. */ - pxNewTCB = ( TCB_t * ) pvPortMallocTcbMem( sizeof( TCB_t ) ); + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) { /* Allocate space for the stack used by the task being created. * The base of the stack memory stored in the TCB so the task can * be deleted later if required. */ - pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStackMem( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ if( pxNewTCB->pxStack == NULL ) { @@ -899,12 +899,12 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; StackType_t * pxStack; /* Allocate space for the stack used by the task being created. */ - pxStack = pvPortMallocStackMem( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ + pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ if( pxStack != NULL ) { /* Allocate space for the TCB. */ - pxNewTCB = ( TCB_t * ) pvPortMallocTcbMem( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ if( pxNewTCB != NULL ) { diff --git a/components/freertos/heap_idf.c b/components/freertos/heap_idf.c new file mode 100644 index 0000000000..3c22f8e7fd --- /dev/null +++ b/components/freertos/heap_idf.c @@ -0,0 +1,127 @@ +/* + * SPDX-FileCopyrightText: 2020 Amazon.com, Inc. or its affiliates + * + * SPDX-License-Identifier: MIT + * + * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD + */ + +/* + * FreeRTOS Kernel V10.4.3 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#include "sdkconfig.h" + +/* This file implements the heap related functions that are called by FreeRTOS. + * ESP-IDF provides its own heap containing memory with different capabilities + * (see esp_heap_caps.h). Thus, this file maps a subset of the ESP-IDF heap to + * act as the FreeRTOS heap. + * + * All dynamic allocation done by FreeRTOS should be placed in internal 8-bit + * accessible RAM (i.e., using the MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT flags). + * This is due to the fact that FreeRTOS objects (e.g., task stacks, TCBs, + * queues etc) must be accessible even if the cache is disabled. Therefore, the + * heap that is made available to FreeRTOS for dynamic allocation is a subset of + * the ESP-IDF heap (where all MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT memory is + * made available to FreeRTOS for dynamic allocation). + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +#include "esp_heap_caps.h" + +#if !CONFIG_IDF_TARGET_LINUX + /* Memory util functions are not implemented in the Linux simulator */ + #include "esp_memory_utils.h" +#endif /* CONFIG_IDF_TARGET_LINUX */ + +#define portFREERTOS_HEAP_CAPS ( MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT ) + +/*-----------------------------------------------------------*/ + +void * pvPortMalloc( size_t xWantedSize ) +{ + void * pvReturn = NULL; + + /* All dynamic allocation done by FreeRTOS goes through this function. If + * users need to allocate FreeRTOS objects into external RAM, they should + * use the "static" equivalents of FreeRTOS API to create FreeRTOS objects + * (e.g., queues). */ + pvReturn = heap_caps_malloc( xWantedSize, portFREERTOS_HEAP_CAPS ); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void * pv ) +{ + heap_caps_free( pv ); +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return heap_caps_get_free_size( portFREERTOS_HEAP_CAPS ); +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return heap_caps_get_minimum_free_size( portFREERTOS_HEAP_CAPS ); +} +/*-----------------------------------------------------------*/ + +bool xPortCheckValidTCBMem(const void *ptr) +{ + #if CONFIG_IDF_TARGET_LINUX + return true; + #else /* CONFIG_IDF_TARGET_LINUX */ + return esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr); + #endif /* CONFIG_IDF_TARGET_LINUX */ +} + +bool xPortcheckValidStackMem(const void *ptr) +{ + #if CONFIG_IDF_TARGET_LINUX + return true; + #else /* CONFIG_IDF_TARGET_LINUX */ + #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY + return esp_ptr_byte_accessible(ptr); + #else + return esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr); + #endif + #endif /* CONFIG_IDF_TARGET_LINUX */ +} diff --git a/components/freertos/linker_common.lf b/components/freertos/linker_common.lf index 97165d0cc0..7cbb6e17af 100644 --- a/components/freertos/linker_common.lf +++ b/components/freertos/linker_common.lf @@ -46,6 +46,23 @@ entries: # ------------------------------------------------------------------------------------------------------------------ FreeRTOS-openocd (noflash) + # ------------------------------------------------------------------------------------------------------------------ + # heap_idf.c + # Placement Rules: + # - Default: Place all functions in internal RAM. + # - CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH: Place functions in flash if they are never called from an ISR + # context (directly or indirectly). + # ------------------------------------------------------------------------------------------------------------------ + heap_idf (noflash_text) # Default all functions to internal RAM + if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: + heap_idf:pvPortMalloc (default) + heap_idf:vPortFree (default) + heap_idf:xPortGetFreeHeapSize (default) + heap_idf:xPortGetMinimumEverFreeHeapSize (default) + if FREERTOS_SMP = n: + heap_idf:xPortCheckValidTCBMem (default) + heap_idf:xPortcheckValidStackMem (default) + # ------------------------------------------------------------------------------------------------------------------ # port_common.c # Placement Rules: @@ -55,8 +72,5 @@ entries: # ------------------------------------------------------------------------------------------------------------------ port_common (noflash_text) # Default all functions to internal RAM if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: - if FREERTOS_SMP = n: - port_common:xPortCheckValidTCBMem (default) - port_common:xPortcheckValidStackMem (default) port_common:vApplicationGetIdleTaskMemory (default) port_common:vApplicationGetTimerTaskMemory (default) diff --git a/components/freertos/port_common.c b/components/freertos/port_common.c index 36e72248cc..d41a34fc75 100644 --- a/components/freertos/port_common.c +++ b/components/freertos/port_common.c @@ -16,32 +16,13 @@ * - These functions are common to all FreeRTOS ports (i.e., on all architectures and all FreeRTOS implementations). * ------------------------------------------------------------------------------------------------------------------ */ -// -------------------- Heap Related ----------------------- - -#if !CONFIG_FREERTOS_SMP // IDF-3997 -bool xPortCheckValidTCBMem(const void *ptr) -{ - return esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr); -} - -bool xPortcheckValidStackMem(const void *ptr) -{ -#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY - return esp_ptr_byte_accessible(ptr); -#else - return esp_ptr_internal(ptr) && esp_ptr_byte_accessible(ptr); -#endif -} -#endif - // ------------- FreeRTOS Static Allocation ---------------- /* These function are required by FreeRTOS when configSUPPORT_STATIC_ALLOCATION is enabled and is used by FreeRTOS to obtain memory for its IDLE/Timer tasks. -Like the pvPortMallocTcbMem() and pvPortMallocStackMem() macros, TCB and stack -memory MUST be placed in internal RAM. +We simply allocate the IDLE/Timer tasks memory from the FreeRTOS heap. */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, @@ -51,30 +32,20 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StaticTask_t *pxTCBBufferTemp; StackType_t *pxStackBufferTemp; - /* If the stack grows down then allocate the stack then the TCB so the stack + /* Allocate TCB and stack buffer from the FreeRTOS heap + * + * If the stack grows down then allocate the stack then the TCB so the stack * does not grow into the TCB. Likewise if the stack grows up then allocate * the TCB then the stack. */ #if (portSTACK_GROWTH > 0) { - //Allocate TCB and stack buffer in internal memory - #if CONFIG_FREERTOS_SMP // IDF-3997 - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE); - #else - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - pxStackBufferTemp = pvPortMallocStackMem(configMINIMAL_STACK_SIZE); - #endif /* CONFIG_FREERTOS_SMP */ + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); + pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE); } #else /* portSTACK_GROWTH */ { - //Allocate TCB and stack buffer in internal memory - #if CONFIG_FREERTOS_SMP // IDF-3997 - pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE); - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - #else - pxStackBufferTemp = pvPortMallocStackMem(configMINIMAL_STACK_SIZE); - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - #endif /* CONFIG_FREERTOS_SMP */ + pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE); + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); } #endif /* portSTACK_GROWTH */ @@ -93,30 +64,20 @@ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StaticTask_t *pxTCBBufferTemp; StackType_t *pxStackBufferTemp; - /* If the stack grows down then allocate the stack then the TCB so the stack + /* Allocate TCB and stack buffer from the FreeRTOS heap + * + * If the stack grows down then allocate the stack then the TCB so the stack * does not grow into the TCB. Likewise if the stack grows up then allocate * the TCB then the stack. */ #if (portSTACK_GROWTH > 0) { - //Allocate TCB and stack buffer in internal memory - #if CONFIG_FREERTOS_SMP // IDF-3997 - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); - #else - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH); - #endif /* CONFIG_FREERTOS_SMP */ + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); + pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); } #else /* portSTACK_GROWTH */ { - //Allocate TCB and stack buffer in internal memory - #if CONFIG_FREERTOS_SMP // IDF-3997 - pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - #else - pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH); - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - #endif /* CONFIG_FREERTOS_SMP */ + pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); + pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); } #endif /* portSTACK_GROWTH */ diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_task_delete.c b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_task_delete.c index b09d841e6c..86714e982c 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_task_delete.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_task_delete.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,7 +31,7 @@ #define NO_OF_TSKS 3 #define DELAY_TICKS 2 /* Caps of all memory which is allocated from when a task is created */ -#define HEAP_CAPS (portTcbMemoryCaps | portStackMemoryCaps) +#define HEAP_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #define DELAY_US_ITERATIONS 1000 diff --git a/docs/en/api-reference/system/freertos.rst b/docs/en/api-reference/system/freertos.rst index f589fbbee0..8c548cf18f 100644 --- a/docs/en/api-reference/system/freertos.rst +++ b/docs/en/api-reference/system/freertos.rst @@ -117,3 +117,11 @@ FreeRTOS Additions ------------------ ESP-IDF provides some supplemental features to FreeRTOS such as Ring Buffers, ESP-IDF style Tick and Idle Hooks, and TLSP deletion callbacks. See :doc:`freertos_additions` for more details. + +FreeRTOS Heap +------------- + +Vanilla FreeRTOS provides its own `selection of heap implementations `_. However, ESP-IDF already implements its own heap (see :doc:`/api-reference/system/mem_alloc`), thus ESP-IDF does not make use of the heap implementations provided by Vanilla FreeRTOS. All FreeRTOS ports in ESP-IDF map FreeRTOS memory allocation/free calls (e.g., ``pvPortMalloc()`` and ``pvPortFree()``) to ESP-IDF heap API (i.e., :cpp:func:`heap_caps_malloc` and :cpp:func:`heap_caps_free`). However, the FreeRTOS ports ensure that all dynamic memory allocated by FreeRTOS is placed in internal memory. + +.. note:: + If users wish to place FreeRTOS objects in external memory, users should allocate those objects manually using :cpp:func:`heap_caps_malloc`, then create the object using the object's ``...CreateStatic()`` function.