forked from espressif/esp-idf
Merge branch 'refactor/freertos_startup_and_common_functions' into 'master'
FreeRTOS: Refactor app startup and port common functions See merge request espressif/esp-idf!21240
This commit is contained in:
@@ -51,7 +51,9 @@ if(${target} STREQUAL "linux")
|
|||||||
"${kernel_dir}/portable/${arch}/utils/wait_for_event.c")
|
"${kernel_dir}/portable/${arch}/utils/wait_for_event.c")
|
||||||
else()
|
else()
|
||||||
list(APPEND srcs
|
list(APPEND srcs
|
||||||
|
"app_startup.c"
|
||||||
"FreeRTOS-openocd.c"
|
"FreeRTOS-openocd.c"
|
||||||
|
"port_common.c"
|
||||||
"${kernel_dir}/portable/${arch}/portasm.S")
|
"${kernel_dir}/portable/${arch}/portasm.S")
|
||||||
|
|
||||||
list(APPEND private_include_dirs
|
list(APPEND private_include_dirs
|
||||||
@@ -62,7 +64,6 @@ else()
|
|||||||
list(APPEND include_dirs "${kernel_dir}/portable/${arch}/include/freertos") # Xtensa headers via #include "xx.h"
|
list(APPEND include_dirs "${kernel_dir}/portable/${arch}/include/freertos") # Xtensa headers via #include "xx.h"
|
||||||
else()
|
else()
|
||||||
list(APPEND srcs
|
list(APPEND srcs
|
||||||
"${kernel_dir}/portable/port_common.c"
|
|
||||||
"${kernel_dir}/portable/port_systick.c"
|
"${kernel_dir}/portable/port_systick.c"
|
||||||
"esp_additions/freertos_v8_compat.c")
|
"esp_additions/freertos_v8_compat.c")
|
||||||
|
|
||||||
@@ -130,13 +131,14 @@ else()
|
|||||||
# FreeRTOS headers have a dependency on app_trace when SystemView tracing is enabled
|
# FreeRTOS headers have a dependency on app_trace when SystemView tracing is enabled
|
||||||
idf_component_optional_requires(PUBLIC app_trace)
|
idf_component_optional_requires(PUBLIC app_trace)
|
||||||
elseif(CONFIG_APPTRACE_ENABLE)
|
elseif(CONFIG_APPTRACE_ENABLE)
|
||||||
# [refactor-todo]: port.c has a dependency on esp_apptrace_init, for running it on APP CPU.
|
# [refactor-todo]: app_startup.c esp_startup_start_app_other_cores() has a dependency on esp_apptrace_init()
|
||||||
# this should be resolved when link-time registration of startup functions is added.
|
# (called on CPU1). This should be resolved when link-time registration of startup functions is added.
|
||||||
idf_component_optional_requires(PRIVATE app_trace)
|
idf_component_optional_requires(PRIVATE app_trace)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME)
|
if(CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME)
|
||||||
# [refactor-todo]: port.c esp_startup_start_app_common() calls esp_gdbstub_init()
|
# [refactor-todo]: app_startup.c esp_startup_start_app_other_cores() calls esp_gdbstub_init() (called on CPU0).
|
||||||
|
# This should be resolved when link-time registration of startup functions is added.
|
||||||
idf_component_optional_requires(PRIVATE esp_gdbstub)
|
idf_component_optional_requires(PRIVATE esp_gdbstub)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -35,24 +35,17 @@
|
|||||||
#include "hal/systimer_hal.h"
|
#include "hal/systimer_hal.h"
|
||||||
#include "hal/systimer_ll.h"
|
#include "hal/systimer_ll.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM_TRACE
|
#ifdef CONFIG_PM_TRACE
|
||||||
#include "esp_private/pm_trace.h"
|
#include "esp_private/pm_trace.h"
|
||||||
#endif //CONFIG_PM_TRACE
|
#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");
|
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
|
||||||
|
|
||||||
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------------------------------------------------ */
|
* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
|
BaseType_t uxSchedulerRunning = 0; // Duplicate of xSchedulerRunning, accessible to port files
|
||||||
|
|
||||||
BaseType_t uxSchedulerRunning = 0;
|
|
||||||
volatile UBaseType_t uxInterruptNesting = 0;
|
volatile UBaseType_t uxInterruptNesting = 0;
|
||||||
portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED;
|
portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
portMUX_TYPE port_xISRLock = portMUX_INITIALIZER_UNLOCKED;
|
portMUX_TYPE port_xISRLock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
@@ -226,83 +219,7 @@ IRAM_ATTR void SysTickIsrHandler(void *arg)
|
|||||||
|
|
||||||
#endif // CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
#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 -------------------------------------------------
|
/* ---------------------------------------------- Port Implementations -------------------------------------------------
|
||||||
* Implementations of Porting Interface functions
|
* Implementations of Porting Interface functions
|
||||||
@@ -468,72 +385,6 @@ void vPortFreeStack( void *pv )
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
|
||||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
|
||||||
StackType_t **ppxIdleTaskStackBuffer,
|
|
||||||
uint32_t *pulIdleTaskStackSize )
|
|
||||||
{
|
|
||||||
StackType_t *pxStackBufferTemp;
|
|
||||||
StaticTask_t *pxTCBBufferTemp;
|
|
||||||
|
|
||||||
/* 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 = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE);
|
|
||||||
}
|
|
||||||
#else /* portSTACK_GROWTH */
|
|
||||||
{
|
|
||||||
//Allocate TCB and stack buffer in internal memory
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE);
|
|
||||||
pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
}
|
|
||||||
#endif /* portSTACK_GROWTH */
|
|
||||||
|
|
||||||
assert(pxStackBufferTemp != NULL);
|
|
||||||
assert(pxTCBBufferTemp != NULL);
|
|
||||||
// Write back pointers
|
|
||||||
*ppxIdleTaskStackBuffer = pxStackBufferTemp;
|
|
||||||
*ppxIdleTaskTCBBuffer = pxTCBBufferTemp;
|
|
||||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH);
|
|
||||||
}
|
|
||||||
#else /* portSTACK_GROWTH */
|
|
||||||
{
|
|
||||||
//Allocate TCB and stack buffer in internal memory
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH);
|
|
||||||
pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
}
|
|
||||||
#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 )
|
|
||||||
|
|
||||||
// ------------------------ Stack --------------------------
|
// ------------------------ Stack --------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -32,18 +32,6 @@
|
|||||||
#include "esp_freertos_hooks.h"
|
#include "esp_freertos_hooks.h"
|
||||||
#include "esp_intr_alloc.h"
|
#include "esp_intr_alloc.h"
|
||||||
#include "esp_memory_utils.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
|
#ifdef CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||||
#include "soc/periph_defs.h"
|
#include "soc/periph_defs.h"
|
||||||
#include "soc/system_reg.h"
|
#include "soc/system_reg.h"
|
||||||
@@ -56,7 +44,7 @@ _Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16")
|
|||||||
/*
|
/*
|
||||||
OS state variables
|
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
|
unsigned int port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit
|
||||||
//FreeRTOS SMP Locks
|
//FreeRTOS SMP Locks
|
||||||
portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED;
|
portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
@@ -305,121 +293,6 @@ IRAM_ATTR void SysTickIsrHandler(void *arg)
|
|||||||
|
|
||||||
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
#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 -------------------------------------------------
|
/* ---------------------------------------------- Port Implementations -------------------------------------------------
|
||||||
@@ -533,72 +406,6 @@ void vPortFreeStack( void *pv )
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
|
||||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
|
||||||
StackType_t **ppxIdleTaskStackBuffer,
|
|
||||||
uint32_t *pulIdleTaskStackSize )
|
|
||||||
{
|
|
||||||
StackType_t *pxStackBufferTemp;
|
|
||||||
StaticTask_t *pxTCBBufferTemp;
|
|
||||||
|
|
||||||
/* 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 = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE);
|
|
||||||
}
|
|
||||||
#else /* portSTACK_GROWTH */
|
|
||||||
{
|
|
||||||
//Allocate TCB and stack buffer in internal memory
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configMINIMAL_STACK_SIZE);
|
|
||||||
pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
}
|
|
||||||
#endif /* portSTACK_GROWTH */
|
|
||||||
|
|
||||||
assert(pxStackBufferTemp != NULL);
|
|
||||||
assert(pxTCBBufferTemp != NULL);
|
|
||||||
// Write back pointers
|
|
||||||
*ppxIdleTaskStackBuffer = pxStackBufferTemp;
|
|
||||||
*ppxIdleTaskTCBBuffer = pxTCBBufferTemp;
|
|
||||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH);
|
|
||||||
}
|
|
||||||
#else /* portSTACK_GROWTH */
|
|
||||||
{
|
|
||||||
//Allocate TCB and stack buffer in internal memory
|
|
||||||
pxStackBufferTemp = pvPortMalloc(configTIMER_TASK_STACK_DEPTH);
|
|
||||||
pxTCBBufferTemp = pvPortMalloc(sizeof(StaticTask_t));
|
|
||||||
}
|
|
||||||
#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 )
|
|
||||||
|
|
||||||
// ------------------------ Stack --------------------------
|
// ------------------------ Stack --------------------------
|
||||||
|
|
||||||
// User exception dispatcher when exiting
|
// User exception dispatcher when exiting
|
||||||
|
@@ -95,6 +95,7 @@ void vApplicationTickHook( void )
|
|||||||
|
|
||||||
void vPortYieldOtherCore( BaseType_t coreid ) { } // trying to skip for now
|
void vPortYieldOtherCore( BaseType_t coreid ) { } // trying to skip for now
|
||||||
|
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
|
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
|
||||||
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
||||||
* used by the Idle task. */
|
* used by the Idle task. */
|
||||||
@@ -120,8 +121,10 @@ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
|
|||||||
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||||
}
|
}
|
||||||
|
#endif // configSUPPORT_STATIC_ALLOCATION == 1
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||||
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||||
* to provide the memory that is used by the Timer service task. */
|
* to provide the memory that is used by the Timer service task. */
|
||||||
@@ -146,6 +149,7 @@ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
|
|||||||
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||||
}
|
}
|
||||||
|
#endif // configSUPPORT_STATIC_ALLOCATION == 1
|
||||||
|
|
||||||
void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
|
void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
|
||||||
{
|
{
|
||||||
|
@@ -1,230 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#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 <ARCH>/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(configMINIMAL_STACK_SIZE);
|
|
||||||
}
|
|
||||||
#else /* portSTACK_GROWTH */
|
|
||||||
{
|
|
||||||
//Allocate TCB and stack buffer in internal memory
|
|
||||||
pxStackBufferTemp = pvPortMallocStackMem(configMINIMAL_STACK_SIZE);
|
|
||||||
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
|
|
||||||
}
|
|
||||||
#endif /* portSTACK_GROWTH */
|
|
||||||
|
|
||||||
assert(pxTCBBufferTemp != NULL);
|
|
||||||
assert(pxStackBufferTemp != NULL);
|
|
||||||
//Write back pointers
|
|
||||||
*ppxIdleTaskTCBBuffer = pxTCBBufferTemp;
|
|
||||||
*ppxIdleTaskStackBuffer = pxStackBufferTemp;
|
|
||||||
*pulIdleTaskStackSize = configMINIMAL_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;
|
|
||||||
}
|
|
@@ -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.
|
* @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
|
* @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 uxCriticalNesting = 0;
|
||||||
static UBaseType_t uxSavedInterruptState = 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;
|
UBaseType_t uxInterruptNesting = 0;
|
||||||
BaseType_t xPortSwitchFlag = 0;
|
BaseType_t xPortSwitchFlag = 0;
|
||||||
__attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
|
__attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
|
||||||
@@ -473,16 +471,3 @@ void vPortSetStackWatchpoint(void *pxStackStart)
|
|||||||
/* ---------------------------------------------- Misc Implementations -------------------------------------------------
|
/* ---------------------------------------------- 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();
|
|
||||||
}
|
|
||||||
|
@@ -69,15 +69,11 @@
|
|||||||
#include "esp_private/esp_int_wdt.h"
|
#include "esp_private/esp_int_wdt.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_log.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 "FreeRTOS.h" /* This pulls in portmacro.h */
|
||||||
#include "task.h" /* Required for TaskHandle_t, tskNO_AFFINITY, and vTaskStartScheduler */
|
#include "task.h" /* Required for TaskHandle_t, tskNO_AFFINITY, and vTaskStartScheduler */
|
||||||
#include "port_systick.h"
|
#include "port_systick.h"
|
||||||
#include "esp_cpu.h"
|
#include "esp_cpu.h"
|
||||||
#include "esp_memory_utils.h"
|
#include "esp_memory_utils.h"
|
||||||
#include "esp_chip_info.h"
|
|
||||||
|
|
||||||
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
|
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
|
||||||
|
|
||||||
@@ -88,8 +84,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 */
|
volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Indicates whether scheduler is running on a per-core basis
|
||||||
extern volatile int port_xSchedulerRunning[portNUM_PROCESSORS];
|
|
||||||
unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit
|
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_uxCriticalNesting[portNUM_PROCESSORS] = {0};
|
||||||
BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0};
|
BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0};
|
||||||
@@ -618,53 +613,3 @@ void vPortReleaseTaskMPUSettings( xMPU_SETTINGS *xMPUSettings )
|
|||||||
_xt_coproc_release( xMPUSettings->coproc_area );
|
_xt_coproc_release( xMPUSettings->coproc_area );
|
||||||
}
|
}
|
||||||
#endif /* portUSING_MPU_WRAPPERS */
|
#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();
|
|
||||||
}
|
|
||||||
|
207
components/freertos/app_startup.c
Normal file
207
components/freertos/app_startup.c
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#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
|
||||||
|
|
||||||
|
ESP_LOGI(MAIN_TAG, "Calling app_main()");
|
||||||
|
extern void app_main(void);
|
||||||
|
app_main();
|
||||||
|
ESP_LOGI(MAIN_TAG, "Returned from app_main()");
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
@@ -130,14 +130,12 @@ entries:
|
|||||||
queue: uxQueueGetQueueNumber (default)
|
queue: uxQueueGetQueueNumber (default)
|
||||||
queue: vQueueSetQueueNumber (default)
|
queue: vQueueSetQueueNumber (default)
|
||||||
queue: ucQueueGetQueueType (default)
|
queue: ucQueueGetQueueType (default)
|
||||||
# port.c Functions
|
# app_startup.c
|
||||||
port: esp_startup_start_app (default)
|
app_startup: esp_startup_start_app (default)
|
||||||
if ESP_SYSTEM_SINGLE_CORE_MODE = n:
|
if CONFIG_FREERTOS_UNICORE = n:
|
||||||
port: esp_startup_start_app_other_cores (default)
|
app_startup: esp_startup_start_app_other_cores (default)
|
||||||
|
app_startup: other_cpu_startup_idle_hook_cb (default)
|
||||||
|
app_startup: main_task (default)
|
||||||
# port_common.c Functions
|
# port_common.c Functions
|
||||||
port_common:main_task (default)
|
|
||||||
port_common:esp_startup_start_app_common (default)
|
|
||||||
port_common:vApplicationGetIdleTaskMemory (default)
|
port_common:vApplicationGetIdleTaskMemory (default)
|
||||||
port_common:vApplicationGetTimerTaskMemory (default)
|
port_common:vApplicationGetTimerTaskMemory (default)
|
||||||
if FREERTOS_UNICORE = n:
|
|
||||||
port_common:other_cpu_startup_idle_hook_cb (default)
|
|
||||||
|
@@ -144,10 +144,12 @@ entries:
|
|||||||
# port
|
# port
|
||||||
port: pxPortInitialiseStack (default)
|
port: pxPortInitialiseStack (default)
|
||||||
port: xPortStartScheduler (default)
|
port: xPortStartScheduler (default)
|
||||||
port: main_task (default)
|
# app_startup.c
|
||||||
port: esp_startup_start_app (default)
|
app_startup: esp_startup_start_app (default)
|
||||||
if ESP_SYSTEM_SINGLE_CORE_MODE = n:
|
if CONFIG_FREERTOS_UNICORE = n:
|
||||||
port:esp_startup_start_app_other_cores (default)
|
app_startup: esp_startup_start_app_other_cores (default)
|
||||||
|
app_startup: other_cpu_startup_idle_hook_cb (default)
|
||||||
|
app_startup: main_task (default)
|
||||||
# timers.c
|
# timers.c
|
||||||
timers: xTimerCreateTimerTask (default)
|
timers: xTimerCreateTimerTask (default)
|
||||||
timers: xTimerCreate (default)
|
timers: xTimerCreate (default)
|
||||||
|
130
components/freertos/port_common.c
Normal file
130
components/freertos/port_common.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#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(configMINIMAL_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(configMINIMAL_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;
|
||||||
|
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
@@ -21,8 +21,10 @@
|
|||||||
|
|
||||||
static void unity_task(void *pvParameters)
|
static void unity_task(void *pvParameters)
|
||||||
{
|
{
|
||||||
vTaskDelay(2); /* Delay a bit to let the main task be deleted */
|
// Delay a bit to let the main task and any other startup tasks be deleted
|
||||||
unity_run_menu(); /* Doesn't return */
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
// Start running unity (prints test menu and doesn't return)
|
||||||
|
unity_run_menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
|
Reference in New Issue
Block a user