diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index 78a8e4ae4e..58a5babe12 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -7,7 +7,7 @@ endif() idf_build_get_property(target IDF_TARGET) if(CONFIG_FREERTOS_SMP) - set(ldfragments linker_smp.lf) + set(ldfragments linker_smp.lf linker_common.lf) if(CONFIG_IDF_TARGET_ARCH_XTENSA) set(srcs "FreeRTOS-Kernel-SMP/portable/xtensa/port.c" @@ -50,6 +50,7 @@ if(CONFIG_FREERTOS_SMP) endif() list(APPEND srcs + "port_common.c" "FreeRTOS-Kernel-SMP/croutine.c" "FreeRTOS-Kernel-SMP/event_groups.c" "FreeRTOS-Kernel-SMP/list.c" @@ -57,6 +58,7 @@ if(CONFIG_FREERTOS_SMP) "FreeRTOS-Kernel-SMP/tasks.c" "FreeRTOS-Kernel-SMP/timers.c" "FreeRTOS-Kernel-SMP/stream_buffer.c" + "app_startup.c" "FreeRTOS-openocd.c" ) @@ -69,7 +71,7 @@ if(CONFIG_FREERTOS_SMP) endif() else() - set(ldfragments linker.lf) + set(ldfragments linker.lf linker_common.lf) if(CONFIG_IDF_TARGET_ARCH_XTENSA) set(srcs "FreeRTOS-Kernel/portable/xtensa/port.c" @@ -112,7 +114,7 @@ else() endif() list(APPEND srcs - "FreeRTOS-Kernel/portable/port_common.c" + "port_common.c" "FreeRTOS-Kernel/portable/port_systick.c" "FreeRTOS-Kernel/croutine.c" "FreeRTOS-Kernel/event_groups.c" @@ -121,6 +123,7 @@ else() "FreeRTOS-Kernel/tasks.c" "FreeRTOS-Kernel/timers.c" "FreeRTOS-Kernel/stream_buffer.c" + "app_startup.c" "FreeRTOS-openocd.c" "esp_additions/freertos_v8_compat.c") diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 7b03a67bce..b4483209f0 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -35,24 +35,17 @@ #include "hal/systimer_hal.h" #include "hal/systimer_ll.h" #endif - #ifdef CONFIG_PM_TRACE #include "esp_private/pm_trace.h" #endif //CONFIG_PM_TRACE -#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME -#include "esp_gdbstub.h" -#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - _Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16"); /* ---------------------------------------------------- Variables ------------------------------------------------------ * * ------------------------------------------------------------------------------------------------------------------ */ -static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but - -BaseType_t uxSchedulerRunning = 0; +BaseType_t uxSchedulerRunning = 0; // Duplicate of xSchedulerRunning, accessible to port files volatile UBaseType_t uxInterruptNesting = 0; portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED; portMUX_TYPE port_xISRLock = portMUX_INITIALIZER_UNLOCKED; @@ -229,83 +222,7 @@ IRAM_ATTR void SysTickIsrHandler(void *arg) #endif // CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER -// --------------------- App Start-up ---------------------- -extern void app_main(void); - -static void main_task(void *args) -{ -#if !CONFIG_FREERTOS_UNICORE - // Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack - while (uxSchedulerRunning == 0) { - ; - } -#endif - - // [refactor-todo] check if there is a way to move the following block to esp_system startup - heap_caps_enable_nonos_stack_heaps(); - - // Now we have startup stack RAM available for heap, enable any DMA pool memory -#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL - if (g_spiram_ok) { - esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL); - if (r != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r); - abort(); - } - } -#endif - - //Initialize task wdt if configured to do so -#if CONFIG_ESP_TASK_WDT_INIT - esp_task_wdt_config_t twdt_config = { - .timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000, - .idle_core_mask = 0, -#if CONFIG_ESP_TASK_WDT_PANIC - .trigger_panic = true, -#endif - }; -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 - twdt_config.idle_core_mask |= (1 << 0); -#endif -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 - twdt_config.idle_core_mask |= (1 << 1); -#endif - ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config)); -#endif // CONFIG_ESP_TASK_WDT_INIT - - app_main(); - vTaskDelete(NULL); -} - -void esp_startup_start_app_common(void) -{ -#if CONFIG_ESP_INT_WDT_INIT - esp_int_wdt_init(); - //Initialize the interrupt watch dog for CPU0. - esp_int_wdt_cpu_init(); -#endif - - esp_crosscore_int_init(); - -#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - esp_gdbstub_init(); -#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - - portBASE_TYPE res = xTaskCreatePinnedToCore(main_task, "main", - ESP_TASK_MAIN_STACK, NULL, - ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE); - assert(res == pdTRUE); - (void)res; -} - -void esp_startup_start_app(void) -{ - esp_startup_start_app_common(); - - ESP_LOGI(TAG, "Starting scheduler."); - vTaskStartScheduler(); -} /* ---------------------------------------------- Port Implementations ------------------------------------------------- * Implementations of Porting Interface functions @@ -471,52 +388,6 @@ void vPortFreeStack( void *pv ) } #endif -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) -void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, - StackType_t **ppxIdleTaskStackBuffer, - uint32_t *pulIdleTaskStackSize ) -{ - StackType_t *pxStackBufferTemp; - StaticTask_t *pxTCBBufferTemp; - /* Stack always grows downwards (from high address to low address) on all - * ESP RISC-V targets. Given that the heap allocator likely allocates memory - * from low to high address, we allocate the stack first and then the TCB so - * that the stack does not grow downwards into the TCB. - * - * Allocate TCB and stack buffer in internal memory. */ - pxStackBufferTemp = pvPortMalloc(CONFIG_FREERTOS_IDLE_TASK_STACKSIZE); - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - assert(pxStackBufferTemp != NULL); - assert(pxTCBBufferTemp != NULL); - // Write back pointers - *ppxIdleTaskStackBuffer = pxStackBufferTemp; - *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; - *pulIdleTaskStackSize = CONFIG_FREERTOS_IDLE_TASK_STACKSIZE; -} - -void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, - StackType_t **ppxTimerTaskStackBuffer, - uint32_t *pulTimerTaskStackSize ) -{ - StackType_t *pxStackBufferTemp; - StaticTask_t *pxTCBBufferTemp; - /* Stack always grows downwards (from high address to low address) on all - * ESP RISC-V targets. Given that the heap allocator likely allocates memory - * from low to high address, we allocate the stack first and then the TCB so - * that the stack does not grow downwards into the TCB. - * - * Allocate TCB and stack buffer in internal memory. */ - pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - assert(pxStackBufferTemp != NULL); - assert(pxTCBBufferTemp != NULL); - // Write back pointers - *ppxTimerTaskStackBuffer = pxStackBufferTemp; - *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; - *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; -} -#endif //( configSUPPORT_STATIC_ALLOCATION == 1 ) - // ------------------------ Stack -------------------------- #if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER /** diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index fcf8b3b23d..e6d24fcac9 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -31,18 +31,6 @@ #include "esp_freertos_hooks.h" #include "esp_intr_alloc.h" #include "esp_memory_utils.h" -#include "esp_chip_info.h" -#if CONFIG_SPIRAM -/* Required by esp_psram_extram_reserve_dma_pool() */ -#include "esp_psram.h" -#include "esp_private/esp_psram_extram.h" -#endif -#ifdef CONFIG_APPTRACE_ENABLE -#include "esp_app_trace.h" -#endif -#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME -#include "esp_gdbstub.h" /* Required by esp_gdbstub_init() */ -#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME #ifdef CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER #include "soc/periph_defs.h" #include "soc/system_reg.h" @@ -55,7 +43,7 @@ _Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16") /* OS state variables */ -volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; +volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Indicates whether scheduler is running on a per-core basis unsigned int port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit //FreeRTOS SMP Locks portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED; @@ -307,121 +295,6 @@ IRAM_ATTR void SysTickIsrHandler(void *arg) #endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT -// --------------------- App Start-up ---------------------- - -static const char *TAG = "cpu_start"; - -extern void app_main(void); - -static void main_task(void *args) -{ -#if !CONFIG_FREERTOS_UNICORE - // Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack - while (port_xSchedulerRunning[1] == 0) { - ; - } -#endif - - // [refactor-todo] check if there is a way to move the following block to esp_system startup - heap_caps_enable_nonos_stack_heaps(); - - // Now we have startup stack RAM available for heap, enable any DMA pool memory -#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL - if (esp_psram_is_initialized()) { - esp_err_t r = esp_psram_extram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL); - if (r != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r); - abort(); - } - } -#endif - - //Initialize TWDT if configured to do so -#if CONFIG_ESP_TASK_WDT_INIT - esp_task_wdt_config_t twdt_config = { - .timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000, - .idle_core_mask = 0, -#if CONFIG_ESP_TASK_WDT_PANIC - .trigger_panic = true, -#endif - }; -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 - twdt_config.idle_core_mask |= (1 << 0); -#endif -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 - twdt_config.idle_core_mask |= (1 << 1); -#endif - ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config)); -#endif // CONFIG_ESP_TASK_WDT - - app_main(); - vTaskDelete(NULL); -} - -void esp_startup_start_app_common(void) -{ -#if CONFIG_ESP_INT_WDT - esp_int_wdt_init(); - //Initialize the interrupt watch dog for CPU0. - esp_int_wdt_cpu_init(); -#endif - - esp_crosscore_int_init(); - -#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - esp_gdbstub_init(); -#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - - portBASE_TYPE res = xTaskCreatePinnedToCore(main_task, "main", - ESP_TASK_MAIN_STACK, NULL, - ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE); - assert(res == pdTRUE); - (void)res; -} - -void esp_startup_start_app_other_cores(void) -{ - // For now, we only support up to two core: 0 and 1. - if (xPortGetCoreID() >= 2) { - abort(); - } - - // Wait for FreeRTOS initialization to finish on PRO CPU - while (port_xSchedulerRunning[0] == 0) { - ; - } - -#if CONFIG_APPTRACE_ENABLE - // [refactor-todo] move to esp_system initialization - esp_err_t err = esp_apptrace_init(); - assert(err == ESP_OK && "Failed to init apptrace module on APP CPU!"); -#endif - -#if CONFIG_ESP_INT_WDT - //Initialize the interrupt watch dog for CPU1. - esp_int_wdt_cpu_init(); -#endif - - esp_crosscore_int_init(); - - ESP_EARLY_LOGI(TAG, "Starting scheduler on APP CPU."); - xPortStartScheduler(); - abort(); /* Only get to here if FreeRTOS somehow very broken */ -} - -void esp_startup_start_app(void) -{ -#if !CONFIG_ESP_INT_WDT -#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX - assert(!soc_has_cache_lock_bug() && "ESP32 Rev 3 + Dual Core + PSRAM requires INT WDT enabled in project config!"); -#endif -#endif - - esp_startup_start_app_common(); - - ESP_EARLY_LOGI(TAG, "Starting scheduler on PRO CPU."); - vTaskStartScheduler(); -} /* ---------------------------------------------- Port Implementations ------------------------------------------------- @@ -535,52 +408,6 @@ void vPortFreeStack( void *pv ) } #endif -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) -void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, - StackType_t **ppxIdleTaskStackBuffer, - uint32_t *pulIdleTaskStackSize ) -{ - StackType_t *pxStackBufferTemp; - StaticTask_t *pxTCBBufferTemp; - /* Stack always grows downwards (from high address to low address) on all - * ESP Xtensa targets. Given that the heap allocator likely allocates memory - * from low to high address, we allocate the stack first and then the TCB so - * that the stack does not grow downwards into the TCB. - * - * Allocate TCB and stack buffer in internal memory. */ - pxStackBufferTemp = pvPortMalloc(CONFIG_FREERTOS_IDLE_TASK_STACKSIZE); - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - assert(pxStackBufferTemp != NULL); - assert(pxTCBBufferTemp != NULL); - // Write back pointers - *ppxIdleTaskStackBuffer = pxStackBufferTemp; - *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; - *pulIdleTaskStackSize = CONFIG_FREERTOS_IDLE_TASK_STACKSIZE; -} - -void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, - StackType_t **ppxTimerTaskStackBuffer, - uint32_t *pulTimerTaskStackSize ) -{ - StaticTask_t *pxTCBBufferTemp; - StackType_t *pxStackBufferTemp; - /* Stack always grows downwards (from high address to low address) on all - * ESP Xtensa targets. Given that the heap allocator likely allocates memory - * from low to high address, we allocate the stack first and then the TCB so - * that the stack does not grow downwards into the TCB. - * - * Allocate TCB and stack buffer in internal memory. */ - pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH); - pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t)); - assert(pxStackBufferTemp != NULL); - assert(pxTCBBufferTemp != NULL); - // Write back pointers - *ppxTimerTaskStackBuffer = pxStackBufferTemp; - *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; - *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; -} -#endif //( configSUPPORT_STATIC_ALLOCATION == 1 ) - // ------------------------ Stack -------------------------- // User exception dispatcher when exiting diff --git a/components/freertos/FreeRTOS-Kernel/portable/port_common.c b/components/freertos/FreeRTOS-Kernel/portable/port_common.c deleted file mode 100644 index 420ad29ded..0000000000 --- a/components/freertos/FreeRTOS-Kernel/portable/port_common.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "FreeRTOS.h" -#include "task.h" -#include "portmacro.h" -#include "esp_private/esp_int_wdt.h" -#include "esp_system.h" -#include "esp_heap_caps_init.h" -#include "esp_task_wdt.h" -#include "esp_task.h" -#include "esp_private/crosscore_int.h" -#include "esp_log.h" -#include "esp_memory_utils.h" -#include "esp_freertos_hooks.h" -#include "sdkconfig.h" -#include "esp_freertos_hooks.h" - -#if CONFIG_SPIRAM -#include "esp_psram.h" -#include "esp_private/esp_psram_extram.h" -#endif - -#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL -static const char* TAG = "cpu_start"; -#endif - -/* Architecture-agnostic parts of the FreeRTOS ESP-IDF port layer can go here. - * - * The actual call flow will be to call esp_startup_start_app() in /port.c, - * which will then call esp_startup_start_app_common() - */ - -// Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting -volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; - -// For now, running FreeRTOS on one core and a bare metal on the other (or other OSes) -// is not supported. For now CONFIG_FREERTOS_UNICORE and CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE -// should mirror each other's values. -// -// And since this should be true, we can just check for CONFIG_FREERTOS_UNICORE. -#if CONFIG_FREERTOS_UNICORE != CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE - #error "FreeRTOS and system configuration mismatch regarding the use of multiple cores." -#endif - -static void main_task(void* args); - -#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME -void esp_gdbstub_init(void); -#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - -extern void app_main(void); - -void esp_startup_start_app_common(void) -{ -#if CONFIG_ESP_INT_WDT - esp_int_wdt_init(); - //Initialize the interrupt watch dog for CPU0. - esp_int_wdt_cpu_init(); -#endif - - esp_crosscore_int_init(); - -#if CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME && !CONFIG_IDF_TARGET_ESP32C2 - esp_gdbstub_init(); -#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME - - portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main", - ESP_TASK_MAIN_STACK, NULL, - ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE); - assert(res == pdTRUE); - (void)res; -} - -#if !CONFIG_FREERTOS_UNICORE -static volatile bool s_other_cpu_startup_done = false; -static bool other_cpu_startup_idle_hook_cb(void) -{ - s_other_cpu_startup_done = true; - return true; -} -#endif - -static void main_task(void* args) -{ -#if !CONFIG_FREERTOS_UNICORE - // Wait for FreeRTOS initialization to finish on other core, before replacing its startup stack - esp_register_freertos_idle_hook_for_cpu(other_cpu_startup_idle_hook_cb, !xPortGetCoreID()); - while (!s_other_cpu_startup_done) { - ; - } - esp_deregister_freertos_idle_hook_for_cpu(other_cpu_startup_idle_hook_cb, !xPortGetCoreID()); -#endif - - // [refactor-todo] check if there is a way to move the following block to esp_system startup - heap_caps_enable_nonos_stack_heaps(); - - // Now we have startup stack RAM available for heap, enable any DMA pool memory -#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL - if (esp_psram_is_initialized()) { - esp_err_t r = esp_psram_extram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL); - if (r != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r); - abort(); - } - } -#endif - - //Initialize TWDT if configured to do so -#if CONFIG_ESP_TASK_WDT_INIT - esp_task_wdt_config_t twdt_config = { - .timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000, - .idle_core_mask = 0, -#if CONFIG_ESP_TASK_WDT_PANIC - .trigger_panic = true, -#endif - }; -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 - twdt_config.idle_core_mask |= (1 << 0); -#endif -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 - twdt_config.idle_core_mask |= (1 << 1); -#endif - ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config)); -#endif // CONFIG_ESP_TASK_WDT - - app_main(); - vTaskDelete(NULL); -} - -// -------------------- Heap Related ----------------------- - -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 -} - -// ------------- FreeRTOS Static Allocation ---------------- - -/* -This function is required by FreeRTOS when configSUPPORT_STATIC_ALLOCATION is -enabled and is used by FreeRTOS to obtain memory for its IDLE tasks. - -Like the pvPortMallocTcbMem() and pvPortMallocStackMem() macros, TCB and stack -memory MUST be placed in internal RAM. -*/ -void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, - StackType_t **ppxIdleTaskStackBuffer, - uint32_t *pulIdleTaskStackSize ) -{ - StaticTask_t *pxTCBBufferTemp; - StackType_t *pxStackBufferTemp; - - /* 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 - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - pxStackBufferTemp = pvPortMallocStackMem(configIDLE_TASK_STACK_SIZE); - } - #else /* portSTACK_GROWTH */ - { - //Allocate TCB and stack buffer in internal memory - pxStackBufferTemp = pvPortMallocStackMem(configIDLE_TASK_STACK_SIZE); - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - } - #endif /* portSTACK_GROWTH */ - - assert(pxTCBBufferTemp != NULL); - assert(pxStackBufferTemp != NULL); - //Write back pointers - *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; - *ppxIdleTaskStackBuffer = pxStackBufferTemp; - *pulIdleTaskStackSize = configIDLE_TASK_STACK_SIZE; -} - -/* -This function is required by FreeRTOS when configSUPPORT_STATIC_ALLOCATION is -enabled and is used by the FreeRTOS Timer to obtain memory for its daemone task. - - -Like the pvPortMallocTcbMem() and pvPortMallocStackMem() macros, TCB and stack -memory MUST be placed in internal RAM. -*/ -void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, - StackType_t **ppxTimerTaskStackBuffer, - uint32_t *pulTimerTaskStackSize ) -{ - StaticTask_t *pxTCBBufferTemp; - StackType_t *pxStackBufferTemp; - - /* 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 - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH); - } - #else /* portSTACK_GROWTH */ - { - //Allocate TCB and stack buffer in internal memory - pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH); - pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); - } - #endif /* portSTACK_GROWTH */ - - assert(pxTCBBufferTemp != NULL); - assert(pxStackBufferTemp != NULL); - //Write back pointers - *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; - *ppxTimerTaskStackBuffer = pxStackBufferTemp; - *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; -} diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 948a6fddf5..d4206ccaa3 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -63,8 +63,6 @@ _Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16") * * ------------------------------------------------------------------------------------------------------------------ */ -static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but - /** * @brief A variable is used to keep track of the critical section nesting. * @note This variable has to be stored as part of the task context and must be initialized to a non zero value @@ -73,7 +71,7 @@ static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate t */ static UBaseType_t uxCriticalNesting = 0; static UBaseType_t uxSavedInterruptState = 0; -BaseType_t uxSchedulerRunning = 0; +BaseType_t uxSchedulerRunning = 0; // Duplicate of xSchedulerRunning, accessible to port files UBaseType_t uxInterruptNesting = 0; BaseType_t xPortSwitchFlag = 0; __attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE]; @@ -381,16 +379,3 @@ void vPortSetStackWatchpoint(void *pxStackStart) /* ---------------------------------------------- Misc Implementations ------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ */ - -// --------------------- App Start-up ---------------------- - -/* [refactor-todo]: See if we can include this through a header */ -extern void esp_startup_start_app_common(void); - -void esp_startup_start_app(void) -{ - esp_startup_start_app_common(); - - ESP_LOGI(TAG, "Starting scheduler."); - vTaskStartScheduler(); -} diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 0b7e61a41d..d382ec4c20 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -68,15 +68,11 @@ #include "esp_private/esp_int_wdt.h" #include "esp_system.h" #include "esp_log.h" -#ifdef CONFIG_APPTRACE_ENABLE -#include "esp_app_trace.h" /* Required for esp_apptrace_init. [refactor-todo] */ -#endif #include "FreeRTOS.h" /* This pulls in portmacro.h */ #include "task.h" /* Required for TaskHandle_t, tskNO_AFFINITY, and vTaskStartScheduler */ #include "port_systick.h" #include "esp_cpu.h" #include "esp_memory_utils.h" -#include "esp_chip_info.h" _Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16"); @@ -87,8 +83,7 @@ _Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_A * * ------------------------------------------------------------------------------------------------------------------ */ -static const char *TAG = "cpu_start"; /* [refactor-todo]: might be appropriate to change in the future, but for now maintain the same log output */ -extern volatile int port_xSchedulerRunning[portNUM_PROCESSORS]; +volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Indicates whether scheduler is running on a per-core basis unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit BaseType_t port_uxCriticalNesting[portNUM_PROCESSORS] = {0}; BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0}; @@ -445,53 +440,3 @@ void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings ) _xt_coproc_release( xMPUSettings->coproc_area ); } #endif /* portUSING_MPU_WRAPPERS */ - -// --------------------- App Start-up ---------------------- - -#if !CONFIG_FREERTOS_UNICORE -void esp_startup_start_app_other_cores(void) -{ - // For now, we only support up to two core: 0 and 1. - if (xPortGetCoreID() >= 2) { - abort(); - } - - // Wait for FreeRTOS initialization to finish on PRO CPU - while (port_xSchedulerRunning[0] == 0) { - ; - } - -#if CONFIG_APPTRACE_ENABLE - // [refactor-todo] move to esp_system initialization - esp_err_t err = esp_apptrace_init(); - assert(err == ESP_OK && "Failed to init apptrace module on APP CPU!"); -#endif - -#if CONFIG_ESP_INT_WDT - //Initialize the interrupt watch dog for CPU1. - esp_int_wdt_cpu_init(); -#endif - - esp_crosscore_int_init(); - - ESP_EARLY_LOGI(TAG, "Starting scheduler on APP CPU."); - xPortStartScheduler(); - abort(); /* Only get to here if FreeRTOS somehow very broken */ -} -#endif // !CONFIG_FREERTOS_UNICORE - -extern void esp_startup_start_app_common(void); - -void esp_startup_start_app(void) -{ -#if !CONFIG_ESP_INT_WDT -#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX - assert(!soc_has_cache_lock_bug() && "ESP32 Rev 3 + Dual Core + PSRAM requires INT WDT enabled in project config!"); -#endif -#endif - - esp_startup_start_app_common(); - - ESP_LOGI(TAG, "Starting scheduler on PRO CPU."); - vTaskStartScheduler(); -} diff --git a/components/freertos/FreeRTOS-openocd.c b/components/freertos/FreeRTOS-openocd.c index 89e1374634..0395ea2bc3 100644 --- a/components/freertos/FreeRTOS-openocd.c +++ b/components/freertos/FreeRTOS-openocd.c @@ -1,9 +1,10 @@ - /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 - * + */ + +/* * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer * present in the kernel, so it has to be supplied by other means for * OpenOCD's threads awareness. @@ -15,7 +16,6 @@ */ #include "FreeRTOS.h" -#include "esp_attr.h" #include "sdkconfig.h" #ifdef __GNUC__ @@ -25,5 +25,5 @@ #endif #ifdef CONFIG_FREERTOS_DEBUG_OCDAWARE -const int USED DRAM_ATTR uxTopUsedPriority = configMAX_PRIORITIES - 1; //will be removed +const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1; //will be removed #endif diff --git a/components/freertos/app_startup.c b/components/freertos/app_startup.c new file mode 100644 index 0000000000..85319806bd --- /dev/null +++ b/components/freertos/app_startup.c @@ -0,0 +1,211 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include +#include "esp_task.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/portmacro.h" +#include "esp_private/esp_int_wdt.h" +#include "esp_private/crosscore_int.h" +#include "esp_task_wdt.h" +#include "esp_freertos_hooks.h" +#include "esp_heap_caps_init.h" +#include "esp_chip_info.h" +#if CONFIG_SPIRAM +/* Required by esp_psram_extram_reserve_dma_pool() */ +#include "esp_psram.h" +#include "esp_private/esp_psram_extram.h" +#endif +#ifdef CONFIG_APPTRACE_ENABLE +#include "esp_app_trace.h" /* Required for esp_apptrace_init. [refactor-todo] */ +#endif +#ifdef CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME +#include "esp_gdbstub.h" /* Required by esp_gdbstub_init() */ +#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME + +/* ------------------------------------------------- App/OS Startup ---------------------------------------------------- + * - Functions related to application and FreeRTOS startup + * - This startup is common to all architectures (e.g. RISC-V and Xtensa) and all FreeRTOS implementations (i.e., IDF + * FreeRTOS and Amazon SMP FreeRTOS). + * - Application startup flow as follows: + * - For CPU 0 + * - CPU0 completes CPU startup (in startup.c), then calls esp_startup_start_app() + * - esp_startup_start_app() registers some daemon services for CPU0 then starts FreeRTOS + * - For CPUx (1 to N-1) + * - CPUx completes CPU startup in startup.c, then calls esp_startup_start_app_other_cores() + * - esp_startup_start_app_other_cores(), registers some daemon services for CPUx, waits for CPU0 to start + * FreeRTOS, then yields (via xPortStartScheduler()) to schedule a task. + * ------------------------------------------------------------------------------------------------------------------ */ + +// ----------------------- Checks -------------------------- + +/* +For now, AMP is not supported (i.e., running FreeRTOS on one core and a bare metal/other OS on the other). Therefore, +CONFIG_FREERTOS_UNICORE and CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE should be identical. We add a check for this here. +*/ +#if CONFIG_FREERTOS_UNICORE != CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + #error "AMP not supported. FreeRTOS number of cores and system number of cores must be identical" +#endif + +// -------------------- Declarations ----------------------- + +static void main_task(void* args); +static const char* APP_START_TAG = "app_start"; + +// ------------------ CPU0 App Startup --------------------- + +void esp_startup_start_app(void) +{ +#if CONFIG_ESP_INT_WDT + esp_int_wdt_init(); + // Initialize the interrupt watch dog for CPU0. + esp_int_wdt_cpu_init(); +#elif CONFIG_ESP32_ECO3_CACHE_LOCK_FIX + // If the INT WDT isn't enabled on ESP32 ECO3, issue an error regarding the cache lock bug + assert(!soc_has_cache_lock_bug() && "ESP32 Rev 3 + Dual Core + PSRAM requires INT WDT enabled in project config!"); +#endif + + // Initialize the cross-core interrupt on CPU0 + esp_crosscore_int_init(); + +#if CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME && !CONFIG_IDF_TARGET_ESP32C2 + void esp_gdbstub_init(void); + esp_gdbstub_init(); +#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME + + BaseType_t res = xTaskCreatePinnedToCore(main_task, "main", + ESP_TASK_MAIN_STACK, NULL, + ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE); + assert(res == pdTRUE); + (void)res; + + /* + If a particular FreeRTOS port has port/arch specific OS startup behavior, they can implement a function of type + "void port_start_app_hook(void)" in their `port.c` files. This function will be called below, thus allowing each + FreeRTOS port to implement port specific app startup behavior. + */ + void __attribute__((weak)) port_start_app_hook(void); + if (port_start_app_hook != NULL) { + port_start_app_hook(); + } + + ESP_EARLY_LOGI(APP_START_TAG, "Starting scheduler on CPU0"); + vTaskStartScheduler(); +} + +// --------------- CPU[1:N-1] App Startup ------------------ + +#if !CONFIG_FREERTOS_UNICORE +void esp_startup_start_app_other_cores(void) +{ + // For now, we only support up to two core: 0 and 1. + if (xPortGetCoreID() >= 2) { + abort(); + } + + // Wait for CPU0 to start FreeRTOS before progressing + extern volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS]; + while (port_xSchedulerRunning[0] == 0) { + ; + } + +#if CONFIG_APPTRACE_ENABLE + // [refactor-todo] move to esp_system initialization + esp_err_t err = esp_apptrace_init(); + assert(err == ESP_OK && "Failed to init apptrace module on APP CPU!"); +#endif + +#if CONFIG_ESP_INT_WDT + // Initialize the interrupt watch dog for CPU1. + esp_int_wdt_cpu_init(); +#endif + + // Initialize the cross-core interrupt on CPU1 + esp_crosscore_int_init(); + + ESP_EARLY_LOGI(APP_START_TAG, "Starting scheduler on CPU%d", xPortGetCoreID()); + xPortStartScheduler(); + abort(); // Only get to here if FreeRTOS somehow very broken +} +#endif // !CONFIG_FREERTOS_UNICORE + +/* ---------------------------------------------------- Main Task ------------------------------------------------------ + * - main_task is a daemon task created by CPU0 before it starts FreeRTOS + * - Pinned to CPU(ESP_TASK_MAIN_CORE) + * - Priority of ESP_TASK_MAIN_PRIO + * - Used to dispatch "void app_main(void)" provided by the application + * - main_task will self delete if app_main returns + * ------------------------------------------------------------------------------------------------------------------ */ + +static const char* MAIN_TAG = "main_task"; + +#if !CONFIG_FREERTOS_UNICORE +static volatile bool s_other_cpu_startup_done = false; +static bool other_cpu_startup_idle_hook_cb(void) +{ + s_other_cpu_startup_done = true; + return true; +} +#endif + +static void main_task(void* args) +{ + ESP_LOGI(MAIN_TAG, "Started on CPU%d", xPortGetCoreID()); +#if !CONFIG_FREERTOS_UNICORE + // Wait for FreeRTOS initialization to finish on other core, before replacing its startup stack + esp_register_freertos_idle_hook_for_cpu(other_cpu_startup_idle_hook_cb, !xPortGetCoreID()); + while (!s_other_cpu_startup_done) { + ; + } + esp_deregister_freertos_idle_hook_for_cpu(other_cpu_startup_idle_hook_cb, !xPortGetCoreID()); +#endif + + // [refactor-todo] check if there is a way to move the following block to esp_system startup + heap_caps_enable_nonos_stack_heaps(); + + // Now we have startup stack RAM available for heap, enable any DMA pool memory +#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL + if (esp_psram_is_initialized()) { + esp_err_t r = esp_psram_extram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL); + if (r != ESP_OK) { + ESP_LOGE(MAIN_TAG, "Could not reserve internal/DMA pool (error 0x%x)", r); + abort(); + } + } +#endif + + // Initialize TWDT if configured to do so +#if CONFIG_ESP_TASK_WDT_INIT + esp_task_wdt_config_t twdt_config = { + .timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000, + .idle_core_mask = 0, +#if CONFIG_ESP_TASK_WDT_PANIC + .trigger_panic = true, +#endif + }; +#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 + twdt_config.idle_core_mask |= (1 << 0); +#endif +#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 + twdt_config.idle_core_mask |= (1 << 1); +#endif + ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config)); +#endif // CONFIG_ESP_TASK_WDT + + /* + Note: Be careful when changing the "Calling app_main()" log below as multiple pytest scripts expect this log as a + start-of-application marker. + */ + ESP_LOGI(MAIN_TAG, "Calling app_main()"); + extern void app_main(void); + app_main(); + ESP_LOGI(MAIN_TAG, "Returned from app_main()"); + vTaskDelete(NULL); +} diff --git a/components/freertos/esp_additions/include/freertos/FreeRTOSConfig.h b/components/freertos/esp_additions/include/freertos/FreeRTOSConfig.h index c9651b0b18..5065a781ad 100644 --- a/components/freertos/esp_additions/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/esp_additions/include/freertos/FreeRTOSConfig.h @@ -201,7 +201,7 @@ This file get's pulled into assembly sources. Therefore, some includes need to b #define INCLUDE_xSemaphoreGetMutexHolder 1 #define INCLUDE_xTaskGetHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#define INCLUDE_uxTaskGetStackHighWaterMark2 1 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index 173a62af78..34dc1e7ad5 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -1,133 +1,243 @@ +# ---------------------------------------------------------------------------------------------------------------------- # Linker fragment file for IDF FreeRTOS (i.e., CONFIG_FREERTOS_SMP=n) -[mapping:freertos] +# Flash function placements are listed per source file, in the order that they appear in the source file. +# +# 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). +# - Some functions that are called often (such as critical sections) are placed in internal RAM for speed. +# ---------------------------------------------------------------------------------------------------------------------- + +[mapping:freertos_idf] archive: libfreertos.a entries: - * (noflash_text) - if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: - # vTaskGetSnapshot is omitted on purpose: as it is used to by the Task Watchdog (TWDT) interrupt - # handler, we want to always keep it in IRAM - tasks: pxTaskGetNext (default) - tasks: uxTaskGetSnapshotAll (default) - tasks: pxGetNextTaskList (default) + * (noflash_text) # Default all FreeRTOS functions to IRAM if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: - port: pxPortInitialiseStack (default) - port: xPortStartScheduler (default) - if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y : - port: vPortReleaseTaskMPUSettings (default) - tasks: xTaskCreateRestricted (default) - port: vPortStoreTaskMPUSettings (default) - tasks: vTaskAllocateMPURegions (default) - tasks: prvTaskCheckFreeStackSpace (default) - tasks: prvInitialiseNewTask (default) - tasks: prvInitialiseTaskLists (default) - tasks: prvDeleteTCB (default) - tasks: prvCheckTasksWaitingTermination (default) - tasks: prvIdleTask (default) - tasks: prvAddNewTaskToReadyList (default) - tasks: xTaskCreatePinnedToCore (default) - tasks: xTaskCreateStaticPinnedToCore (default) - tasks: vTaskResume (default) - tasks: vTaskStartScheduler (default) - tasks: vTaskSuspendAll (default) - tasks: uxTaskGetNumberOfTasks (default) - tasks: xTaskGetIdleTaskHandle (default) - tasks: vTaskRemoveFromUnorderedEventList (default) - tasks: uxTaskPriorityGet (default) - tasks: vTaskPrioritySet (default) - tasks: prvTaskPriorityRaise (default) - tasks: prvTaskPriorityRestore (default) - tasks: vTaskSetThreadLocalStoragePointerAndDelCallback (default) - tasks: pvTaskGetThreadLocalStoragePointer (default) - tasks: xTaskGetCurrentTaskHandleForCPU (default) - tasks: vTaskDelete (default) - tasks: vTaskDelayUntil (default) - tasks: xTaskDelayUntil (default) - tasks: vTaskDelay (default) - tasks: vTaskSuspend (default) - tasks: xTaskResumeAll (default) - tasks: uxTaskResetEventItemValue (default) - tasks: ulTaskNotifyTake (default) - tasks: ulTaskGenericNotifyTake (default) - tasks: xTaskNotifyWait (default) - tasks: xTaskGenericNotifyWait (default) - tasks: xTaskGenericNotify (default) - tasks: eTaskGetState (default) - tasks: pxTaskGetStackStart (default) - tasks: uxTaskGetStackHighWaterMark (default) - tasks: vTaskEndScheduler (default) - tasks: vTaskMissedYield (default) - tasks: vTaskSetThreadLocalStoragePointer (default) - tasks: xTaskGetAffinity (default) - tasks: xTaskGetIdleTaskHandleForCPU (default) + # -------------------------------------------------------------------------------------------------------------- + # event_groups.c + # - Exclude all ...FromISR() functions and their dependents + # -------------------------------------------------------------------------------------------------------------- + event_groups:xEventGroupCreateStatic (default) + event_groups:xEventGroupCreate (default) + event_groups:xEventGroupSync (default) + event_groups:xEventGroupWaitBits (default) + event_groups:xEventGroupClearBits (default) + event_groups:xEventGroupSetBits (default) + event_groups:vEventGroupDelete (default) + event_groups:vEventGroupSetBitsCallback (default) + event_groups:vEventGroupClearBitsCallback (default) + event_groups:prvTestWaitCondition (default) if FREERTOS_USE_TRACE_FACILITY = y: - tasks: uxTaskGetSystemState (default) - tasks: uxTaskGetTaskNumber (default) - tasks: vTaskSetTaskNumber (default) - if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: - tasks: vTaskList (default) - if FREERTOS_GENERATE_RUN_TIME_STATS = y: - tasks: vTaskGetRunTimeStats (default) - timers: prvInsertTimerInActiveList (default) - timers: prvCheckForValidListAndQueue (default) - timers: prvInitialiseNewTimer (default) - timers: prvTimerTask (default) - timers: prvSwitchTimerLists (default) - timers: prvSampleTimeNow (default) - timers: prvProcessExpiredTimer (default) - timers: prvProcessTimerOrBlockTask (default) - timers: prvProcessReceivedCommands (default) - timers: xTimerCreateTimerTask (default) - timers: xTimerCreate (default) - timers: xTimerCreateStatic (default) - timers: xTimerGenericCommand (default) - timers: xTimerGetPeriod (default) - timers: xTimerGetExpiryTime (default) - timers: xTimerIsTimerActive (default) - timers: pvTimerGetTimerID (default) - timers: vTimerSetTimerID (default) - timers: prvGetNextExpireTime (default) + event_groups: uxEventGroupGetNumber (default) + event_groups: vEventGroupSetNumber (default) + # -------------------------------------------------------------------------------------------------------------- + # list.c + # - List/List Item initialization functions are never called from ISR + # -------------------------------------------------------------------------------------------------------------- + list:vListInitialise (default) + list:vListInitialiseItem (default) + # -------------------------------------------------------------------------------------------------------------- + # queue.c + # - Keep all ...FromISR() functions (and their prv... calls) in internal RAM + # - All other functions can be moved to flash + # -------------------------------------------------------------------------------------------------------------- + queue:xQueueGenericReset (default) + queue:xQueueGenericCreateStatic (default) + queue:xQueueGenericCreate (default) + queue:prvInitialiseNewQueue (default) + queue:prvInitialiseMutex (default) + queue:xQueueCreateMutex (default) + queue:xQueueCreateMutexStatic (default) + queue:xQueueGetMutexHolder (default) + queue:xQueueGiveMutexRecursive (default) + queue:xQueueTakeMutexRecursive (default) + queue:xQueueCreateCountingSemaphoreStatic (default) + queue:xQueueCreateCountingSemaphore (default) + queue:xQueueGenericSend (default) + queue:xQueueReceive (default) + queue:xQueueSemaphoreTake (default) + queue:xQueuePeek (default) + queue:uxQueueMessagesWaiting (default) + queue:uxQueueSpacesAvailable (default) + queue:vQueueDelete (default) if FREERTOS_USE_TRACE_FACILITY = y: - timers: uxTimerGetTimerNumber (default) - timers: vTimerSetTimerNumber (default) - event_groups: prvTestWaitCondition (default) - event_groups: xEventGroupCreate (default) - event_groups: xEventGroupCreateStatic (default) - event_groups: xEventGroupWaitBits (default) - event_groups: xEventGroupClearBits (default) - event_groups: xEventGroupSetBits (default) - event_groups: xEventGroupSync (default) - event_groups: vEventGroupDelete (default) - queue: prvIsQueueFull (default) - queue: prvInitialiseNewQueue (default) - queue: prvInitialiseMutex (default) - queue: uxQueueSpacesAvailable (default) - queue: xQueueGenericReset (default) - queue: xQueueGenericCreate (default) - queue: xQueueGetMutexHolder (default) - queue: xQueueCreateCountingSemaphore (default) - queue: xQueueGenericSend (default) - queue: xQueueCreateMutex (default) - queue: xQueueGiveMutexRecursive (default) - queue: xQueueTakeMutexRecursive (default) - queue: uxQueueMessagesWaiting (default) - queue: vQueueDelete (default) - queue: vQueueWaitForMessageRestricted (default) - queue: xQueueCreateSet (default) - queue: xQueueAddToSet (default) - queue: xQueueRemoveFromSet (default) - queue: xQueueSelectFromSet (default) - queue: xQueueGenericCreateStatic (default) - queue: xQueueCreateMutexStatic (default) - queue: xQueueCreateCountingSemaphoreStatic (default) + queue:uxQueueGetQueueNumber (default) + queue:vQueueSetQueueNumber (default) + queue:ucQueueGetQueueType (default) + queue:prvGetDisinheritPriorityAfterTimeout (default) + queue:prvUnlockQueue (default) + queue:prvIsQueueEmpty (default) + queue:prvIsQueueFull (default) if FREERTOS_QUEUE_REGISTRY_SIZE > 0: - queue: pcQueueGetName (default) - queue: vQueueAddToRegistry (default) - queue: vQueueUnregisterQueue (default) + queue:vQueueAddToRegistry (default) + queue:pcQueueGetName (default) + queue:vQueueUnregisterQueue (default) + queue:vQueueWaitForMessageRestricted (default) + queue:xQueueCreateSet (default) + queue:xQueueAddToSet (default) + queue:xQueueRemoveFromSet (default) + queue:xQueueSelectFromSet (default) + # -------------------------------------------------------------------------------------------------------------- + # stream_buffer.c + # -------------------------------------------------------------------------------------------------------------- + stream_buffer:xStreamBufferGenericCreate (default) + stream_buffer:xStreamBufferGenericCreateStatic (default) + stream_buffer:vStreamBufferDelete (default) + stream_buffer:xStreamBufferReset (default) + stream_buffer:xStreamBufferSetTriggerLevel (default) + stream_buffer:xStreamBufferBytesAvailable (default) + stream_buffer:xStreamBufferSend (default) + stream_buffer:xStreamBufferReceive (default) + stream_buffer:xStreamBufferNextMessageLengthBytes (default) + stream_buffer:xStreamBufferIsEmpty (default) + stream_buffer:xStreamBufferIsFull (default) + stream_buffer:prvWriteBytesToBuffer (default) + stream_buffer:prvReadBytesFromBuffer (default) + stream_buffer:prvInitialiseNewStreamBuffer (default) if FREERTOS_USE_TRACE_FACILITY = y: - queue: uxQueueGetQueueNumber (default) - queue: vQueueSetQueueNumber (default) - queue: ucQueueGetQueueType (default) - port_common:main_task (default) - port: esp_startup_start_app (default) - if ESP_SYSTEM_SINGLE_CORE_MODE = n: - port: esp_startup_start_app_other_cores (default) + stream_buffer:uxStreamBufferGetStreamBufferNumber (default) + stream_buffer:vStreamBufferSetStreamBufferNumber (default) + stream_buffer:ucStreamBufferGetStreamBufferType (default) + # -------------------------------------------------------------------------------------------------------------- + # tasks.c + # - Tickless idle functions (i.e., step tick) are left in internal RAM for speed + # - The following functions are called when the cache is disabled, thus they are excluded from the list below + # (i.e., called after "spi_flash_disable_interrupts_caches_and_other_cpu()" is called). + # - "xTaskGetSchedulerState" + # - "xTaskGetTickCount" + # -------------------------------------------------------------------------------------------------------------- + tasks:xTaskCreateStaticPinnedToCore (default) + tasks:xTaskCreatePinnedToCore (default) + tasks:prvInitialiseNewTask (default) + tasks:prvAddNewTaskToReadyList (default) + tasks:vTaskDelete (default) + tasks:vTaskDelayUntil (default) + tasks:xTaskDelayUntil (default) + tasks:vTaskDelay (default) + tasks:eTaskGetState (default) + tasks:uxTaskPriorityGet (default) + tasks:vTaskPrioritySet (default) + tasks:vTaskSuspend (default) + tasks:vTaskResume (default) + tasks:vTaskStartScheduler (default) + tasks:vTaskEndScheduler (default) + tasks:vTaskSuspendAll (default) + if CONFIG_FREERTOS_USE_TICKLESS_IDLE = y: + tasks:prvGetExpectedIdleTime (default) + tasks:xTaskResumeAll (default) + tasks:uxTaskGetNumberOfTasks (default) + tasks:pcTaskGetName (default) + tasks:prvSearchForNameWithinSingleList (default) + tasks:xTaskGetHandle (default) + tasks:xTaskGetIdleTaskHandle (default) + tasks:xTaskGetIdleTaskHandleForCPU (default) + tasks:xTaskAbortDelay (default) + # IDF-6410 Application tags not supported yet + #tasks:vTaskSetApplicationTaskTag (default) + #tasks:xTaskGetApplicationTaskTag (default) + #tasks:xTaskCallApplicationTaskHook (default) + tasks:vTaskPlaceOnEventList (default) + tasks:vTaskPlaceOnUnorderedEventList (default) + tasks:vTaskPlaceOnEventListRestricted (default) + tasks:vTaskRemoveFromUnorderedEventList (default) + tasks:vTaskSetTimeOutState (default) + tasks:vTaskInternalSetTimeOutState (default) + tasks:xTaskCheckForTimeOut (default) + tasks:vTaskMissedYield (default) + tasks:prvIdleTask (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default) + tasks:prvDeleteTLS (default) + if FREERTOS_THREAD_LOCAL_STORAGE_POINTERS != 0: + tasks:vTaskSetThreadLocalStoragePointer (default) + tasks:pvTaskGetThreadLocalStoragePointer (default) + tasks:prvInitialiseTaskLists (default) + tasks:prvCheckTasksWaitingTermination (default) + tasks:xTaskGetAffinity (default) + tasks:prvTaskCheckFreeStackSpace (default) + tasks:uxTaskGetStackHighWaterMark (default) + tasks:pxTaskGetStackStart (default) + tasks:prvDeleteTCB (default) + tasks:xTaskGetCurrentTaskHandle (default) + tasks:xTaskGetCurrentTaskHandleForCPU (default) + tasks:xTaskPriorityInherit (default) + tasks:xTaskPriorityDisinherit (default) + tasks:vTaskPriorityDisinheritAfterTimeout (default) + if FREERTOS_USE_TRACE_FACILITY = y && FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: + tasks:prvWriteNameToBuffer (default) + tasks:vTaskList (default) + if FREERTOS_GENERATE_RUN_TIME_STATS = y && FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: + tasks:vTaskGetRunTimeStats (default) + tasks:uxTaskResetEventItemValue (default) + tasks:pvTaskIncrementMutexHeldCount (default) + tasks:ulTaskNotifyTake (default) + tasks:ulTaskGenericNotifyTake (default) + tasks:xTaskNotifyWait (default) + tasks:xTaskGenericNotifyWait (default) + tasks:xTaskGenericNotify (default) + tasks:xTaskGenericNotifyStateClear (default) + tasks:ulTaskGenericNotifyValueClear (default) + if FREERTOS_GENERATE_RUN_TIME_STATS = y: + tasks:ulTaskGetIdleRunTimeCounter (default) + tasks:prvAddCurrentTaskToDelayedList (default) + if FREERTOS_USE_TRACE_FACILITY = y: + tasks:uxTaskGetSystemState (default) + tasks:uxTaskGetTaskNumber (default) + tasks:vTaskSetTaskNumber (default) + tasks:vTaskGetInfo (default) + tasks:prvListTasksWithinSingleList (default) + # -------------------------------------------------------------------------------------------------------------- + # timers.c + # - xTimerGenericCommand() is used for ISR calls as well. Thus leave it (and its dependents) in internal RAM + # -------------------------------------------------------------------------------------------------------------- + timers:xTimerCreateTimerTask (default) + timers:xTimerCreate (default) + timers:xTimerCreateStatic (default) + timers:prvInitialiseNewTimer (default) + timers:xTimerGenericCommand (default) + timers:xTimerGetTimerDaemonTaskHandle (default) + timers:xTimerGetPeriod (default) + timers:vTimerSetReloadMode (default) + timers:uxTimerGetReloadMode (default) + timers:xTimerGetExpiryTime (default) + timers:pcTimerGetName (default) + timers:prvProcessExpiredTimer (default) + timers:prvTimerTask (default) + timers:prvProcessTimerOrBlockTask (default) + timers:prvGetNextExpireTime (default) + timers:prvSampleTimeNow (default) + timers:prvInsertTimerInActiveList (default) + timers:prvProcessReceivedCommands (default) + timers:prvSwitchTimerLists (default) + timers:prvCheckForValidListAndQueue (default) + timers:xTimerIsTimerActive (default) + timers:pvTimerGetTimerID (default) + timers:vTimerSetTimerID (default) + timers:xTimerPendFunctionCall (default) + if FREERTOS_USE_TRACE_FACILITY = y: + timers:uxTimerGetTimerNumber (default) + timers:vTimerSetTimerNumber (default) + # -------------------------------------------------------------------------------------------------------------- + # portable/xtensa/port.c + # - Most functions are called from an ISR context, except for scheduler/task init/deinit functions + # - MPU/Coproc currently only exists on ESP32/S3 + # -------------------------------------------------------------------------------------------------------------- + if IDF_TARGET_ARCH_XTENSA = y: + port:xPortStartScheduler (default) + port:vPortEndScheduler (default) + if FREERTOS_TASK_FUNCTION_WRAPPER = y: + port:vPortTaskWrapper (default) + port:pxPortInitialiseStack (default) + port:xPortGetTickRateHz (default) + # -------------------------------------------------------------------------------------------------------------- + # portable/riscv/port.c + # - Most functions are called from an ISR context, except for scheduler/task init/deinit functions + # -------------------------------------------------------------------------------------------------------------- + if IDF_TARGET_ARCH_RISCV = y: + port:xPortStartScheduler (default) + port:vPortEndScheduler (default) + if FREERTOS_TASK_FUNCTION_WRAPPER = y: + port:vPortTaskWrapper (default) + port:pxPortInitialiseStack (default) + port:xPortGetTickRateHz (default) diff --git a/components/freertos/linker_common.lf b/components/freertos/linker_common.lf new file mode 100644 index 0000000000..97165d0cc0 --- /dev/null +++ b/components/freertos/linker_common.lf @@ -0,0 +1,62 @@ +# Linker fragment file for common FreeRTOS files (i.e., both "port_common.c" and "esp_additions/..." +# Flash function placements are listed per source file, in the order that they appear in the source file. + +[mapping:freertos_common] +archive: libfreertos.a +entries: + # ------------------------------------------------------------------------------------------------------------------ + # esp_additions/private_include/freertos_tasks_c_additions.h + # Placement Rules (Task Snapshot): + # - Default: Place all functions in internal RAM. + # - CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH: Place functions in flash + # - vTaskGetSnapshot is omitted on purpose as it is used to by the Task Watchdog (TWDT) interrupt handler, we want + # to always keep it in IRAM + # Placement Rules (FreeRTOS API Additions): + # - 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). + # ------------------------------------------------------------------------------------------------------------------ + # Task Snapshot + if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: + tasks:pxGetNextTaskList (default) + tasks:pxTaskGetNext (default) + tasks:uxTaskGetSnapshotAll (default) + # FreeRTOS API Additions + if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: + if FREERTOS_SMP = y: + tasks:xTaskCreatePinnedToCore (default) + tasks:xTaskCreateStaticPinnedToCore (default) + tasks:xTaskGetCurrentTaskHandleForCPU (default) + tasks:xTaskGetIdleTaskHandleForCPU (default) + tasks:xTaskGetAffinity (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default) + tasks:prvTaskPriorityRaise (default) + tasks:prvTaskPriorityRestore (default) + + # ------------------------------------------------------------------------------------------------------------------ + # app_startup.c + # Placement Rules: Functions always in flash as they are never called from an ISR + # ------------------------------------------------------------------------------------------------------------------ + app_startup (default) # Place functions (but not Data and BSS) to flash + + # ------------------------------------------------------------------------------------------------------------------ + # FreeRTOS-openocd.c + # Placement Rules: All functions/data in internal RAM as they are called/used by OpenOCD + # ------------------------------------------------------------------------------------------------------------------ + FreeRTOS-openocd (noflash) + + # ------------------------------------------------------------------------------------------------------------------ + # port_common.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). + # ------------------------------------------------------------------------------------------------------------------ + 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/linker_smp.lf b/components/freertos/linker_smp.lf index 01f7c5b211..38800be64d 100644 --- a/components/freertos/linker_smp.lf +++ b/components/freertos/linker_smp.lf @@ -1,178 +1,242 @@ +# ---------------------------------------------------------------------------------------------------------------------- # Linker fragment file for SMP FreeRTOS (i.e., CONFIG_FREERTOS_SMP=y) -[mapping:freertos] +# Flash function placements are listed per source file, in the order that they appear in the source file. +# +# 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). +# - Some functions that are called often (such as critical sections) are placed in internal RAM for speed. +# ---------------------------------------------------------------------------------------------------------------------- + +[mapping:freertos_smp] archive: libfreertos.a entries: - # Default all FreeRTOS functions to IRAM - * (noflash_text) - # Todo: Check if flash placements are missing or can be further optimized IDF-5259 + * (noflash_text) # Default all FreeRTOS functions to IRAM if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: + # -------------------------------------------------------------------------------------------------------------- # event_groups.c - event_groups: xEventGroupCreateStatic (default) - event_groups: xEventGroupCreate (default) - event_groups: xEventGroupSync (default) - event_groups: xEventGroupWaitBits (default) - event_groups: xEventGroupClearBits (default) - event_groups: xEventGroupSetBits (default) - event_groups: vEventGroupDelete (default) - event_groups: vEventGroupSetBitsCallback (default) - event_groups: vEventGroupClearBitsCallback (default) - event_groups: prvTestWaitCondition (default) + # - Exclude all ...FromISR() functions and their dependents + # -------------------------------------------------------------------------------------------------------------- + event_groups:xEventGroupCreateStatic (default) + event_groups:xEventGroupCreate (default) + event_groups:xEventGroupSync (default) + event_groups:xEventGroupWaitBits (default) + event_groups:xEventGroupClearBits (default) + event_groups:xEventGroupSetBits (default) + event_groups:vEventGroupDelete (default) + event_groups:vEventGroupSetBitsCallback (default) + event_groups:vEventGroupClearBitsCallback (default) + event_groups:prvTestWaitCondition (default) if FREERTOS_USE_TRACE_FACILITY = y: event_groups: uxEventGroupGetNumber (default) event_groups: vEventGroupSetNumber (default) + # -------------------------------------------------------------------------------------------------------------- # list.c + # - List/List Item initialization functions are never called from ISR + # -------------------------------------------------------------------------------------------------------------- + list:vListInitialise (default) + list:vListInitialiseItem (default) + # -------------------------------------------------------------------------------------------------------------- # queue.c - queue: xQueueGenericReset (default) - queue: xQueueGenericCreateStatic (default) - queue: xQueueGenericCreate (default) - queue: prvInitialiseNewQueue (default) - queue: prvInitialiseMutex (default) - queue: xQueueCreateMutex (default) - queue: xQueueCreateMutexStatic (default) - queue: xQueueGetMutexHolder (default) - queue: xQueueGiveMutexRecursive (default) - queue: xQueueTakeMutexRecursive (default) - queue: xQueueCreateCountingSemaphoreStatic (default) - queue: xQueueCreateCountingSemaphore (default) - queue: xQueueGenericSend (default) - queue: xQueueReceive (default) - queue: xQueueSemaphoreTake (default) - queue: xQueuePeek (default) - queue: uxQueueMessagesWaiting (default) - queue: uxQueueSpacesAvailable (default) - queue: vQueueDelete (default) + # - Keep all ...FromISR() functions (and their prv... calls) in internal RAM + # - All other functions can be moved to flash + # -------------------------------------------------------------------------------------------------------------- + queue:xQueueGenericReset (default) + queue:xQueueGenericCreateStatic (default) + queue:xQueueGenericCreate (default) + queue:prvInitialiseNewQueue (default) + queue:prvInitialiseMutex (default) + queue:xQueueCreateMutex (default) + queue:xQueueCreateMutexStatic (default) + queue:xQueueGetMutexHolder (default) + queue:xQueueGiveMutexRecursive (default) + queue:xQueueTakeMutexRecursive (default) + queue:xQueueCreateCountingSemaphoreStatic (default) + queue:xQueueCreateCountingSemaphore (default) + queue:xQueueGenericSend (default) + queue:xQueueReceive (default) + queue:xQueueSemaphoreTake (default) + queue:xQueuePeek (default) + queue:uxQueueMessagesWaiting (default) + queue:uxQueueSpacesAvailable (default) + queue:vQueueDelete (default) if FREERTOS_USE_TRACE_FACILITY = y: - queue: uxQueueGetQueueNumber (default) - queue: vQueueSetQueueNumber (default) - queue: ucQueueGetQueueType (default) - queue: prvGetDisinheritPriorityAfterTimeout (default) - queue: prvUnlockQueue (default) - queue: prvIsQueueEmpty (default) - queue: prvIsQueueFull (default) + queue:uxQueueGetQueueNumber (default) + queue:vQueueSetQueueNumber (default) + queue:ucQueueGetQueueType (default) + queue:prvGetDisinheritPriorityAfterTimeout (default) + queue:prvUnlockQueue (default) + queue:prvIsQueueEmpty (default) + queue:prvIsQueueFull (default) if FREERTOS_QUEUE_REGISTRY_SIZE > 0: - queue: vQueueAddToRegistry (default) - queue: pcQueueGetName (default) - queue: vQueueUnregisterQueue (default) - queue: vQueueWaitForMessageRestricted (default) - queue: xQueueCreateSet (default) - queue: xQueueAddToSet (default) - queue: xQueueRemoveFromSet (default) - queue: xQueueSelectFromSet (default) + queue:vQueueAddToRegistry (default) + queue:pcQueueGetName (default) + queue:vQueueUnregisterQueue (default) + queue:vQueueWaitForMessageRestricted (default) + queue:xQueueCreateSet (default) + queue:xQueueAddToSet (default) + queue:xQueueRemoveFromSet (default) + queue:xQueueSelectFromSet (default) + # -------------------------------------------------------------------------------------------------------------- # stream_buffer.c - # tasks.c: Vanilla - tasks: xTaskCreateStatic (default) - tasks: xTaskCreate (default) + # -------------------------------------------------------------------------------------------------------------- + stream_buffer:xStreamBufferGenericCreate (default) + stream_buffer:xStreamBufferGenericCreateStatic (default) + stream_buffer:vStreamBufferDelete (default) + stream_buffer:xStreamBufferReset (default) + stream_buffer:xStreamBufferSetTriggerLevel (default) + stream_buffer:xStreamBufferBytesAvailable (default) + stream_buffer:xStreamBufferSend (default) + stream_buffer:xStreamBufferReceive (default) + stream_buffer:xStreamBufferNextMessageLengthBytes (default) + stream_buffer:xStreamBufferIsEmpty (default) + stream_buffer:xStreamBufferIsFull (default) + stream_buffer:prvWriteBytesToBuffer (default) + stream_buffer:prvReadBytesFromBuffer (default) + stream_buffer:prvInitialiseNewStreamBuffer (default) + if FREERTOS_USE_TRACE_FACILITY = y: + stream_buffer:uxStreamBufferGetStreamBufferNumber (default) + stream_buffer:vStreamBufferSetStreamBufferNumber (default) + stream_buffer:ucStreamBufferGetStreamBufferType (default) + # -------------------------------------------------------------------------------------------------------------- + # tasks.c + # - The following functions are called when the cache is disabled, thus they are excluded from the list below + # (i.e., called after "spi_flash_disable_interrupts_caches_and_other_cpu()" is called). + # - "xTaskGetSchedulerState" + # - "xTaskGetTickCount" + # -------------------------------------------------------------------------------------------------------------- + tasks:xTaskCreateStatic (default) + tasks:xTaskCreate (default) if FREERTOS_UNICORE = n: - tasks: xTaskCreateStaticAffinitySet (default) - tasks: xTaskCreateAffinitySet (default) - tasks: vTaskCoreAffinitySet (default) - tasks: vTaskCoreAffinityGet (default) - tasks: prvMinimalIdleTask (default) - tasks: prvInitialiseNewTask (default) - tasks: prvAddNewTaskToReadyList (default) - tasks: vTaskDelete (default) - tasks: xTaskDelayUntil (default) - tasks: vTaskDelay (default) - tasks: eTaskGetState (default) - tasks: uxTaskPriorityGet (default) - tasks: vTaskPrioritySet (default) - tasks: prvTaskPriorityRaise (default) - tasks: prvTaskPriorityRestore (default) - tasks: vTaskSuspend (default) - tasks: vTaskResume (default) - tasks: prvCreateIdleTasks (default) - tasks: vTaskStartScheduler (default) - tasks: vTaskEndScheduler (default) - tasks: vTaskSuspendAll (default) - #Todo: prvGetExpectedIdleTime - tasks: xTaskResumeAll (default) - tasks: uxTaskGetNumberOfTasks (default) - tasks: pcTaskGetName (default) - tasks: prvSearchForNameWithinSingleList (default) - tasks: xTaskGetHandle (default) + tasks:xTaskCreateStaticAffinitySet (default) + tasks:xTaskCreateAffinitySet (default) + tasks:vTaskCoreAffinitySet (default) + tasks:vTaskCoreAffinityGet (default) + tasks:prvMinimalIdleTask (default) + tasks:prvInitialiseNewTask (default) + tasks:prvAddNewTaskToReadyList (default) + tasks:vTaskDelete (default) + tasks:xTaskDelayUntil (default) + tasks:vTaskDelay (default) + tasks:eTaskGetState (default) + tasks:uxTaskPriorityGet (default) + tasks:vTaskPrioritySet (default) + tasks:vTaskSuspend (default) + tasks:vTaskResume (default) + tasks:prvCreateIdleTasks (default) + tasks:vTaskStartScheduler (default) + tasks:vTaskEndScheduler (default) + tasks:vTaskSuspendAll (default) + #Todo:prvGetExpectedIdleTime + tasks:xTaskResumeAll (default) + tasks:uxTaskGetNumberOfTasks (default) + tasks:pcTaskGetName (default) + tasks:prvSearchForNameWithinSingleList (default) + tasks:xTaskGetHandle (default) if FREERTOS_USE_TRACE_FACILITY = y: - tasks: uxTaskGetSystemState (default) - tasks: uxTaskGetTaskNumber (default) - tasks: vTaskSetTaskNumber (default) - tasks: vTaskGetInfo (default) - tasks: prvListTasksWithinSingleList (default) - tasks: prvTaskCheckFreeStackSpace (default) - tasks: xTaskGetIdleTaskHandle (default) - tasks: xTaskAbortDelay (default) - tasks: vTaskPlaceOnEventList (default) - tasks: vTaskRemoveFromUnorderedEventList (default) - tasks: vTaskPlaceOnEventListRestricted (default) - tasks: vTaskSetTimeOutState (default) - tasks: vTaskInternalSetTimeOutState (default) - tasks: xTaskCheckForTimeOut (default) - tasks: vTaskMissedYield (default) - tasks: prvIdleTask (default) + tasks:uxTaskGetSystemState (default) + tasks:uxTaskGetTaskNumber (default) + tasks:vTaskSetTaskNumber (default) + tasks:vTaskGetInfo (default) + tasks:prvListTasksWithinSingleList (default) + tasks:prvTaskCheckFreeStackSpace (default) + tasks:xTaskGetIdleTaskHandle (default) + tasks:xTaskAbortDelay (default) + tasks:vTaskPlaceOnEventList (default) + tasks:vTaskRemoveFromUnorderedEventList (default) + tasks:vTaskPlaceOnEventListRestricted (default) + tasks:vTaskSetTimeOutState (default) + tasks:vTaskInternalSetTimeOutState (default) + tasks:xTaskCheckForTimeOut (default) + tasks:vTaskMissedYield (default) + tasks:prvIdleTask (default) if FREERTOS_THREAD_LOCAL_STORAGE_POINTERS > 0: - tasks: vTaskSetThreadLocalStoragePointer (default) - tasks: pvTaskGetThreadLocalStoragePointer (default) - tasks: prvInitialiseTaskLists (default) - tasks: prvCheckTasksWaitingTermination (default) - tasks: uxTaskGetStackHighWaterMark (default) - tasks: prvDeleteTCB (default) + tasks:vTaskSetThreadLocalStoragePointer (default) + tasks:pvTaskGetThreadLocalStoragePointer (default) + tasks:prvInitialiseTaskLists (default) + tasks:prvCheckTasksWaitingTermination (default) + tasks:uxTaskGetStackHighWaterMark (default) + tasks:prvDeleteTCB (default) if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS = y: - tasks: prvWriteNameToBuffer (default) - tasks: vTaskList (default) + tasks:prvWriteNameToBuffer (default) + tasks:vTaskList (default) if FREERTOS_GENERATE_RUN_TIME_STATS = y: - tasks: vTaskGetRunTimeStats (default) - tasks: ulTaskGetIdleRunTimeCounter (default) - tasks: uxTaskResetEventItemValue (default) - tasks: pvTaskIncrementMutexHeldCount (default) - tasks: ulTaskGenericNotifyTake (default) - tasks: xTaskGenericNotifyWait (default) - tasks: xTaskGenericNotify (default) - tasks: xTaskGenericNotifyStateClear (default) - tasks: ulTaskGenericNotifyValueClear (default) - # tasks.c: Additions - if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: - tasks: non_ready_task_lists (default) - tasks: pxGetNextTaskList (default) - tasks: pxTaskGetNext (default) - tasks: vTaskGetSnapshot (default) - tasks: uxTaskGetSnapshotAll (default) - tasks: xTaskCreatePinnedToCore (default) - tasks: xTaskCreateStaticPinnedToCore (default) - tasks: xTaskGetCurrentTaskHandleForCPU (default) - tasks: xTaskGetIdleTaskHandleForCPU (default) - tasks: xTaskGetAffinity (default) - if FREERTOS_TLSP_DELETION_CALLBACKS = y: - tasks: vTaskSetThreadLocalStoragePointerAndDelCallback (default) - # port - port: pxPortInitialiseStack (default) - port: xPortStartScheduler (default) - port: main_task (default) - port: esp_startup_start_app (default) - if ESP_SYSTEM_SINGLE_CORE_MODE = n: - port:esp_startup_start_app_other_cores (default) + tasks:vTaskGetRunTimeStats (default) + tasks:ulTaskGetIdleRunTimeCounter (default) + tasks:uxTaskResetEventItemValue (default) + tasks:pvTaskIncrementMutexHeldCount (default) + tasks:ulTaskGenericNotifyTake (default) + tasks:xTaskGenericNotifyWait (default) + tasks:xTaskGenericNotify (default) + tasks:xTaskGenericNotifyStateClear (default) + tasks:ulTaskGenericNotifyValueClear (default) + # -------------------------------------------------------------------------------------------------------------- # timers.c - timers: xTimerCreateTimerTask (default) - timers: xTimerCreate (default) - timers: xTimerCreateStatic (default) - timers: prvInitialiseNewTimer (default) - timers: xTimerGenericCommandFromTask (default) - timers: xTimerGetTimerDaemonTaskHandle (default) - timers: xTimerGetPeriod (default) - timers: vTimerSetReloadMode (default) - timers: uxTimerGetReloadMode (default) - timers: xTimerGetExpiryTime (default) - timers: pcTimerGetName (default) - timers: prvProcessExpiredTimer (default) - timers: prvTimerTask (default) - timers: prvProcessTimerOrBlockTask (default) - timers: prvGetNextExpireTime (default) - timers: prvSampleTimeNow (default) - timers: prvInsertTimerInActiveList (default) - timers: prvProcessReceivedCommands (default) - timers: prvSwitchTimerLists (default) - timers: prvCheckForValidListAndQueue (default) - timers: xTimerIsTimerActive (default) - timers: pvTimerGetTimerID (default) - timers: vTimerSetTimerID (default) - timers: xTimerPendFunctionCall (default) + # - Only timer function called from ISR is xTimerGenericCommandFromISR() and its dependents + # -------------------------------------------------------------------------------------------------------------- + timers:xTimerCreateTimerTask (default) + timers:xTimerCreate (default) + timers:xTimerCreateStatic (default) + timers:prvInitialiseNewTimer (default) + timers:xTimerGenericCommandFromTask (default) + timers:xTimerGetTimerDaemonTaskHandle (default) + timers:xTimerGetPeriod (default) + timers:vTimerSetReloadMode (default) + timers:uxTimerGetReloadMode (default) + timers:xTimerGetExpiryTime (default) + timers:pcTimerGetName (default) + timers:prvProcessExpiredTimer (default) + timers:prvTimerTask (default) + timers:prvProcessTimerOrBlockTask (default) + timers:prvGetNextExpireTime (default) + timers:prvSampleTimeNow (default) + timers:prvInsertTimerInActiveList (default) + timers:prvProcessReceivedCommands (default) + timers:prvSwitchTimerLists (default) + timers:prvCheckForValidListAndQueue (default) + timers:xTimerIsTimerActive (default) + timers:pvTimerGetTimerID (default) + timers:vTimerSetTimerID (default) + timers:xTimerPendFunctionCall (default) if FREERTOS_USE_TRACE_FACILITY = y: - timers: uxTimerGetTimerNumber (default) - timers: vTimerSetTimerNumber (default) + timers:uxTimerGetTimerNumber (default) + timers:vTimerSetTimerNumber (default) + # -------------------------------------------------------------------------------------------------------------- + # portable/xtensa/port.c + # - Most functions are called from an ISR context, except for scheduler/task init/deinit functions + # -------------------------------------------------------------------------------------------------------------- + if IDF_TARGET_ARCH_XTENSA = y: + port:vPortSetupTimer (default) + port:xPortStartScheduler (default) + port:vPortEndScheduler (default) + port:pvPortMalloc (default) + port:vPortFree (default) + port:vPortInitialiseBlocks (default) + port:xPortGetFreeHeapSize (default) + if FREERTOS_TASK_FUNCTION_WRAPPER = y: + port:vPortTaskWrapper (default) + port:pxPortInitialiseStack (default) + if FREERTOS_UNICORE = n: + port:vPortCleanUpCoprocArea (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + port:vPortTLSPointersDelCb (default) + port:vPortCleanUpTCB (default) + # -------------------------------------------------------------------------------------------------------------- + # portable/riscv/port.c + # - Most functions are called from an ISR context, except for scheduler/task init/deinit functions + # -------------------------------------------------------------------------------------------------------------- + if IDF_TARGET_ARCH_RISCV = y: + port:vPortSetupTimer (default) + port:xPortStartScheduler (default) + port:vPortEndScheduler (default) + port:pvPortMalloc (default) + port:vPortFree (default) + port:vPortInitialiseBlocks (default) + port:xPortGetFreeHeapSize (default) + if FREERTOS_TASK_FUNCTION_WRAPPER = y: + port:vPortTaskWrapper (default) + port:pxPortInitialiseStack (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + port:vPortTLSPointersDelCb (default) + port:vPortCleanUpTCB (default) diff --git a/components/freertos/port_common.c b/components/freertos/port_common.c new file mode 100644 index 0000000000..0580203e7e --- /dev/null +++ b/components/freertos/port_common.c @@ -0,0 +1,134 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "FreeRTOS.h" +#include "task.h" +#include "esp_system.h" +#include "esp_memory_utils.h" +#include "sdkconfig.h" + +/* ----------------------------------------- Port Implementations (Common) -------------------------------------------- + * - Common FreeRTOS port function implementations + * - 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. +*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize ) +{ + StaticTask_t *pxTCBBufferTemp; + StackType_t *pxStackBufferTemp; + + /* 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(configIDLE_TASK_STACK_SIZE); + #endif /* CONFIG_FREERTOS_SMP */ + } + #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(configIDLE_TASK_STACK_SIZE); + pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t)); + #endif /* CONFIG_FREERTOS_SMP */ + } + #endif /* portSTACK_GROWTH */ + + assert(pxTCBBufferTemp != NULL); + assert(pxStackBufferTemp != NULL); + //Write back pointers + *ppxIdleTaskTCBBuffer = pxTCBBufferTemp; + *ppxIdleTaskStackBuffer = pxStackBufferTemp; +#if CONFIG_FREERTOS_SMP + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +#else + *pulIdleTaskStackSize = configIDLE_TASK_STACK_SIZE; +#endif /* CONFIG_FREERTOS_SMP */ +} + +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize ) +{ + StaticTask_t *pxTCBBufferTemp; + StackType_t *pxStackBufferTemp; + + /* 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 */ + } + #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 */ + } + #endif /* portSTACK_GROWTH */ + + assert(pxTCBBufferTemp != NULL); + assert(pxStackBufferTemp != NULL); + //Write back pointers + *ppxTimerTaskTCBBuffer = pxTCBBufferTemp; + *ppxTimerTaskStackBuffer = pxStackBufferTemp; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} +#endif // configSUPPORT_STATIC_ALLOCATION == 1 diff --git a/examples/build_system/cmake/plugins/pytest_plugins.py b/examples/build_system/cmake/plugins/pytest_plugins.py index dc1d261269..beedccb790 100644 --- a/examples/build_system/cmake/plugins/pytest_plugins.py +++ b/examples/build_system/cmake/plugins/pytest_plugins.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import textwrap @@ -16,7 +16,7 @@ def test_plugins(dut: Dut) -> None: Successfully registered plugin 'Nihao' Hello plugin performing self-registration... Successfully registered plugin 'Hello' - cpu_start: Starting scheduler + main_task: Calling app_main() List of plugins: - Plugin 'Hello' - Plugin 'Nihao' diff --git a/examples/system/efuse/example_test.py b/examples/system/efuse/example_test.py index f586cf838e..8cb760a4ac 100644 --- a/examples/system/efuse/example_test.py +++ b/examples/system/efuse/example_test.py @@ -286,8 +286,8 @@ def test_examples_efuse_with_virt_secure_boot_v1(env, _): # type: (ttfw_idf.Tin dut.expect('Disable ROM BASIC interpreter fallback...') dut.expect('secure_boot_v1: secure boot is now enabled for bootloader image') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') + dut.expect('main_task: Calling app_main()') dut.expect('Start eFuse example') dut.expect('example: Done') @@ -312,8 +312,8 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (t dut.bootloader_flash() dut.start_app() dut.expect('Loading virtual efuse blocks from real efuses') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') + dut.expect('main_task: Calling app_main()') dut.expect('Start eFuse example') dut.expect('example: Done') @@ -339,8 +339,8 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (t dut.expect('Disable ROM BASIC interpreter fallback...') dut.expect('secure_boot_v1: secure boot is now enabled for bootloader image') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') + dut.expect('main_task: Calling app_main()') dut.expect('Start eFuse example') dut.expect('example: Done') @@ -527,8 +527,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _): # type: (ttfw dut.expect('Disable hardware & software JTAG...') dut.expect('secure_boot_v2: Secure boot permanently enabled') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') + dut.expect('main_task: Calling app_main()') dut.expect('Start eFuse example') dut.expect('example: Done') @@ -554,8 +554,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # dut.bootloader_flash() dut.start_app() dut.expect('Loading virtual efuse blocks from real efuses') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') + dut.expect('main_task: Calling app_main()') dut.expect('Start eFuse example') dut.expect('example: Done') @@ -595,8 +595,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # dut.expect('Disable hardware & software JTAG...') dut.expect('secure_boot_v2: Secure boot permanently enabled') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') + dut.expect('main_task: Calling app_main()') dut.expect('Start eFuse example') dut.expect('example: Done') @@ -665,7 +665,6 @@ def test_examples_efuse_with_virt_sb_v1_and_fe(env, _): # type: (ttfw_idf.TinyF dut.expect('Checking secure boot...') dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..') - dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') diff --git a/examples/system/eventfd/pytest_eventfd.py b/examples/system/eventfd/pytest_eventfd.py index 093879a19f..1e37d20d00 100644 --- a/examples/system/eventfd/pytest_eventfd.py +++ b/examples/system/eventfd/pytest_eventfd.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging @@ -16,7 +16,7 @@ from pytest_embedded import Dut @pytest.mark.generic def test_eventfd(dut: Dut) -> None: - dut.expect_exact('cpu_start: Starting scheduler') + dut.expect_exact('main_task: Calling app_main()') exp_list_5seconds = [ 'eventfd_example: Select timeouted for 1 times', diff --git a/examples/system/select/pytest_select.py b/examples/system/select/pytest_select.py index c09a176db1..5309493a33 100644 --- a/examples/system/select/pytest_select.py +++ b/examples/system/select/pytest_select.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging import os @@ -25,7 +25,7 @@ def get_uart_msgs(i: int) -> List[str]: @pytest.mark.generic def test_examples_select(dut: Dut) -> None: - dut.expect_exact('cpu_start: Starting scheduler', timeout=30) + dut.expect_exact('main_task: Calling app_main()', timeout=30) exp_list = [] for i in range(1, 10): diff --git a/tools/unit-test-app/components/test_utils/test_runner.c b/tools/unit-test-app/components/test_utils/test_runner.c index f9e1422361..b3440708be 100644 --- a/tools/unit-test-app/components/test_utils/test_runner.c +++ b/tools/unit-test-app/components/test_utils/test_runner.c @@ -21,8 +21,10 @@ static void unity_task(void *pvParameters) { - vTaskDelay(2); /* Delay a bit to let the main task be deleted */ - unity_run_menu(); /* Doesn't return */ + // Delay a bit to let the main task and any other startup tasks be deleted + vTaskDelay(pdMS_TO_TICKS(50)); + // Start running unity (prints test menu and doesn't return) + unity_run_menu(); } void test_main(void)