1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
57
62
63
64
65
66
67
70
71
73
74
75
76
77
78
79
81
82
83
84
85
86
87
88
89
94
95
98
99
100
101
102
103
104
105
106
107
108
109
112
113
114
115
118
119
120
123
124
125
126
128
129
130
131
132
133
134
135
136
137
138
139
146
147
148
149
150
157
158
159
160
161
162
168
169
170
171
172
173
174
175
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
206
207
208
209
210
211
/* ... */
#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"14 includes
#if CONFIG_SPIRAM
#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"
#endif
/* ... */
/* ... */
#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
Checks
static void main_task(void* args);
static const char* APP_START_TAG = "app_start";
Declarations
void esp_startup_start_app(void)
{
#if CONFIG_ESP_INT_WDT
esp_int_wdt_init();
esp_int_wdt_cpu_init();/* ... */
#elif 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
esp_crosscore_int_init();
#if CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
void esp_gdbstub_init(void);
esp_gdbstub_init();/* ... */
#endif
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;
/* ... */
void __attribute__((weak)) port_start_app_hook(void);
if (port_start_app_hook != NULL) {
port_start_app_hook();
}{...}
ESP_EARLY_LOGD(APP_START_TAG, "Starting scheduler on CPU0");
vTaskStartScheduler();
}{ ... }
CPU0 App Startup
#if !CONFIG_FREERTOS_UNICORE
void esp_startup_start_app_other_cores(void)
{
if (xPortGetCoreID() >= 2) {
abort();
}{...}
extern volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS];
while (port_xSchedulerRunning[0] == 0) {
;
}{...}
#if CONFIG_APPTRACE_ENABLE
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
esp_int_wdt_cpu_init();/* ... */
#endif
esp_crosscore_int_init();
ESP_EARLY_LOGD(APP_START_TAG, "Starting scheduler on CPU%d", xPortGetCoreID());
xPortStartScheduler();
abort();
}{ ... }
/* ... */#endif
/* ... */
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", (int)xPortGetCoreID());
#if !CONFIG_FREERTOS_UNICORE
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
heap_caps_enable_nonos_stack_heaps();
#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/* ... */
#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
/* ... */
ESP_LOGI(MAIN_TAG, "Calling app_main()");
extern void app_main(void);
app_main();
ESP_LOGI(MAIN_TAG, "Returned from app_main()");
vTaskDelete(NULL);
}{ ... }