]> granicus.if.org Git - esp-idf/blob - components/esp32/cpu_start.c
esp_flash: fix coredump for legacy spi flash API
[esp-idf] / components / esp32 / cpu_start.c
1 // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stdint.h>
16 #include <string.h>
17
18 #include "esp_attr.h"
19 #include "esp_err.h"
20
21 #include "esp32/rom/ets_sys.h"
22 #include "esp32/rom/uart.h"
23 #include "esp32/rom/rtc.h"
24 #include "esp32/rom/cache.h"
25
26 #include "soc/cpu.h"
27 #include "soc/rtc.h"
28 #include "soc/dport_reg.h"
29 #include "soc/gpio_periph.h"
30 #include "soc/timer_periph.h"
31 #include "soc/rtc_wdt.h"
32 #include "soc/efuse_periph.h"
33
34 #include "driver/rtc_io.h"
35
36 #include "freertos/FreeRTOS.h"
37 #include "freertos/task.h"
38 #include "freertos/semphr.h"
39 #include "freertos/queue.h"
40 #include "freertos/portmacro.h"
41
42 #include "esp_heap_caps_init.h"
43 #include "sdkconfig.h"
44 #include "esp_system.h"
45 #include "esp_spi_flash.h"
46 #include "esp_flash_internal.h"
47 #include "nvs_flash.h"
48 #include "esp_event.h"
49 #include "esp_spi_flash.h"
50 #include "esp_private/crosscore_int.h"
51 #include "esp_log.h"
52 #include "esp_vfs_dev.h"
53 #include "esp_newlib.h"
54 #include "esp32/brownout.h"
55 #include "esp_int_wdt.h"
56 #include "esp_task.h"
57 #include "esp_task_wdt.h"
58 #include "esp_phy_init.h"
59 #include "esp32/cache_err_int.h"
60 #include "esp_coexist_internal.h"
61 #include "esp_core_dump.h"
62 #include "esp_app_trace.h"
63 #include "esp_private/dbg_stubs.h"
64 #include "esp_flash_encrypt.h"
65 #include "esp32/spiram.h"
66 #include "esp_clk_internal.h"
67 #include "esp_timer.h"
68 #include "esp_pm.h"
69 #include "esp_private/pm_impl.h"
70 #include "trax.h"
71 #include "esp_ota_ops.h"
72 #include "esp_efuse.h"
73 #include "bootloader_flash_config.h"
74
75 #define STRINGIFY(s) STRINGIFY2(s)
76 #define STRINGIFY2(s) #s
77
78 void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))) __attribute__((noreturn));
79 void start_cpu0_default(void) IRAM_ATTR __attribute__((noreturn));
80 #if !CONFIG_FREERTOS_UNICORE
81 static void IRAM_ATTR call_start_cpu1(void) __attribute__((noreturn));
82 void start_cpu1(void) __attribute__((weak, alias("start_cpu1_default"))) __attribute__((noreturn));
83 void start_cpu1_default(void) IRAM_ATTR __attribute__((noreturn));
84 static bool app_cpu_started = false;
85 #endif //!CONFIG_FREERTOS_UNICORE
86
87 static void do_global_ctors(void);
88 static void main_task(void* args);
89 extern void app_main(void);
90 extern esp_err_t esp_pthread_init(void);
91
92 extern int _bss_start;
93 extern int _bss_end;
94 extern int _rtc_bss_start;
95 extern int _rtc_bss_end;
96 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
97 extern int _ext_ram_bss_start;
98 extern int _ext_ram_bss_end;
99 #endif
100 extern int _init_start;
101 extern void (*__init_array_start)(void);
102 extern void (*__init_array_end)(void);
103 extern volatile int port_xSchedulerRunning[2];
104
105 static const char* TAG = "cpu_start";
106
107 struct object { long placeholder[ 10 ]; };
108 void __register_frame_info (const void *begin, struct object *ob);
109 extern char __eh_frame[];
110
111 //If CONFIG_SPIRAM_IGNORE_NOTFOUND is set and external RAM is not found or errors out on testing, this is set to false.
112 static bool s_spiram_okay=true;
113
114 /*
115  * We arrive here after the bootloader finished loading the program from flash. The hardware is mostly uninitialized,
116  * and the app CPU is in reset. We do have a stack, so we can do the initialization in C.
117  */
118
119 void IRAM_ATTR call_start_cpu0(void)
120 {
121 #if CONFIG_FREERTOS_UNICORE
122     RESET_REASON rst_reas[1];
123 #else
124     RESET_REASON rst_reas[2];
125 #endif
126     cpu_configure_region_protection();
127     cpu_init_memctl();
128
129     //Move exception vectors to IRAM
130     asm volatile (\
131                   "wsr    %0, vecbase\n" \
132                   ::"r"(&_init_start));
133
134     rst_reas[0] = rtc_get_reset_reason(0);
135
136 #if !CONFIG_FREERTOS_UNICORE
137     rst_reas[1] = rtc_get_reset_reason(1);
138 #endif
139
140     // from panic handler we can be reset by RWDT or TG0WDT
141     if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET
142 #if !CONFIG_FREERTOS_UNICORE
143         || rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET
144 #endif
145     ) {
146 #ifndef CONFIG_BOOTLOADER_WDT_ENABLE
147         rtc_wdt_disable();
148 #endif
149     }
150
151     //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
152     memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
153
154     /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */
155     if (rst_reas[0] != DEEPSLEEP_RESET) {
156         memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start));
157     }
158
159 #if CONFIG_SPIRAM_BOOT_INIT
160     esp_spiram_init_cache();
161     if (esp_spiram_init() != ESP_OK) {
162 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
163         ESP_EARLY_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
164         abort();
165 #endif
166
167 #if CONFIG_SPIRAM_IGNORE_NOTFOUND
168         ESP_EARLY_LOGI(TAG, "Failed to init external RAM; continuing without it.");
169         s_spiram_okay = false;
170 #else
171         ESP_EARLY_LOGE(TAG, "Failed to init external RAM!");
172         abort();
173 #endif
174     }
175 #endif
176
177     ESP_EARLY_LOGI(TAG, "Pro cpu up.");
178     if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) {
179         const esp_app_desc_t *app_desc = esp_ota_get_app_description();
180         ESP_EARLY_LOGI(TAG, "Application information:");
181 #ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
182         ESP_EARLY_LOGI(TAG, "Project name:     %s", app_desc->project_name);
183 #endif
184 #ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
185         ESP_EARLY_LOGI(TAG, "App version:      %s", app_desc->version);
186 #endif
187 #ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
188         ESP_EARLY_LOGI(TAG, "Secure version:   %d", app_desc->secure_version);
189 #endif
190 #ifdef CONFIG_APP_COMPILE_TIME_DATE
191         ESP_EARLY_LOGI(TAG, "Compile time:     %s %s", app_desc->date, app_desc->time);
192 #endif
193         char buf[17];
194         esp_ota_get_app_elf_sha256(buf, sizeof(buf));
195         ESP_EARLY_LOGI(TAG, "ELF file SHA256:  %s...", buf);
196         ESP_EARLY_LOGI(TAG, "ESP-IDF:          %s", app_desc->idf_ver);
197     }
198
199 #if !CONFIG_FREERTOS_UNICORE
200     if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_DIS_APP_CPU)) {
201         ESP_EARLY_LOGE(TAG, "Running on single core chip, but application is built with dual core support.");
202         ESP_EARLY_LOGE(TAG, "Please enable CONFIG_FREERTOS_UNICORE option in menuconfig.");
203         abort();
204     }
205     ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1);
206
207 #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
208     esp_flash_encryption_init_checks();
209 #endif
210
211     //Flush and enable icache for APP CPU
212     Cache_Flush(1);
213     Cache_Read_Enable(1);
214     esp_cpu_unstall(1);
215     // Enable clock and reset APP CPU. Note that OpenOCD may have already
216     // enabled clock and taken APP CPU out of reset. In this case don't reset
217     // APP CPU again, as that will clear the breakpoints which may have already
218     // been set.
219     if (!DPORT_GET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN)) {
220         DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
221         DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
222         DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
223         DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
224     }
225     ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1);
226
227     while (!app_cpu_started) {
228         ets_delay_us(100);
229     }
230 #else
231     ESP_EARLY_LOGI(TAG, "Single core mode");
232     DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
233 #endif
234
235
236 #if CONFIG_SPIRAM_MEMTEST
237     if (s_spiram_okay) {
238         bool ext_ram_ok=esp_spiram_test();
239         if (!ext_ram_ok) {
240             ESP_EARLY_LOGE(TAG, "External RAM failed memory test!");
241             abort();
242         }
243     }
244 #endif
245 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
246     memset(&_ext_ram_bss_start, 0, (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start));
247 #endif
248     /* Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted.
249        If the heap allocator is initialized first, it will put free memory linked list items into
250        memory also used by the ROM. Starting the app cpu will let its ROM initialize that memory,
251        corrupting those linked lists. Initializing the allocator *after* the app cpu has booted
252        works around this problem.
253        With SPI RAM enabled, there's a second reason: half of the SPI RAM will be managed by the
254        app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may
255        fail initializing it properly. */
256     heap_caps_init();
257
258     ESP_EARLY_LOGI(TAG, "Pro cpu start user code");
259     start_cpu0();
260 }
261
262 #if !CONFIG_FREERTOS_UNICORE
263
264 static void wdt_reset_cpu1_info_enable(void)
265 {
266     DPORT_REG_SET_BIT(DPORT_APP_CPU_RECORD_CTRL_REG, DPORT_APP_CPU_PDEBUG_ENABLE | DPORT_APP_CPU_RECORD_ENABLE);
267     DPORT_REG_CLR_BIT(DPORT_APP_CPU_RECORD_CTRL_REG, DPORT_APP_CPU_RECORD_ENABLE);
268 }
269
270 void IRAM_ATTR call_start_cpu1(void)
271 {
272     asm volatile (\
273                   "wsr    %0, vecbase\n" \
274                   ::"r"(&_init_start));
275
276     ets_set_appcpu_boot_addr(0);
277     cpu_configure_region_protection();
278     cpu_init_memctl();
279
280 #if CONFIG_ESP_CONSOLE_UART_NONE
281     ets_install_putc1(NULL);
282     ets_install_putc2(NULL);
283 #else // CONFIG_ESP_CONSOLE_UART_NONE
284     uartAttach();
285     ets_install_uart_printf();
286     uart_tx_switch(CONFIG_ESP_CONSOLE_UART_NUM);
287 #endif
288
289     wdt_reset_cpu1_info_enable();
290     ESP_EARLY_LOGI(TAG, "App cpu up.");
291     app_cpu_started = 1;
292     start_cpu1();
293 }
294 #endif //!CONFIG_FREERTOS_UNICORE
295
296 static void intr_matrix_clear(void)
297 {
298     //Clear all the interrupt matrix register
299     for (int i = ETS_WIFI_MAC_INTR_SOURCE; i <= ETS_CACHE_IA_INTR_SOURCE; i++) {
300         intr_matrix_set(0, i, ETS_INVALID_INUM);
301 #if !CONFIG_FREERTOS_UNICORE
302         intr_matrix_set(1, i, ETS_INVALID_INUM);
303 #endif
304     }
305 }
306
307 void start_cpu0_default(void)
308 {
309     esp_err_t err;
310     esp_setup_syscall_table();
311
312     if (s_spiram_okay) {
313 #if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
314         esp_err_t r=esp_spiram_add_to_heapalloc();
315         if (r != ESP_OK) {
316             ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!");
317             abort();
318         }
319 #if CONFIG_SPIRAM_USE_MALLOC
320         heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
321 #endif
322 #endif
323     }
324
325 //Enable trace memory and immediately start trace.
326 #if CONFIG_ESP32_TRAX
327 #if CONFIG_ESP32_TRAX_TWOBANKS
328     trax_enable(TRAX_ENA_PRO_APP);
329 #else
330     trax_enable(TRAX_ENA_PRO);
331 #endif
332     trax_start_trace(TRAX_DOWNCOUNT_WORDS);
333 #endif
334     esp_clk_init();
335     esp_perip_clk_init();
336     intr_matrix_clear();
337
338 #ifndef CONFIG_ESP_CONSOLE_UART_NONE
339 #ifdef CONFIG_PM_ENABLE
340     const int uart_clk_freq = REF_CLK_FREQ;
341     /* When DFS is enabled, use REFTICK as UART clock source */
342     CLEAR_PERI_REG_MASK(UART_CONF0_REG(CONFIG_ESP_CONSOLE_UART_NUM), UART_TICK_REF_ALWAYS_ON);
343 #else
344     const int uart_clk_freq = APB_CLK_FREQ;
345 #endif // CONFIG_PM_DFS_ENABLE
346     uart_div_modify(CONFIG_ESP_CONSOLE_UART_NUM, (uart_clk_freq << 4) / CONFIG_ESP_CONSOLE_UART_BAUDRATE);
347 #endif // CONFIG_ESP_CONSOLE_UART_NONE
348
349 #if CONFIG_ESP32_BROWNOUT_DET
350     esp_brownout_init();
351 #endif
352 #if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE
353     esp_efuse_disable_basic_rom_console();
354 #endif
355     rtc_gpio_force_hold_dis_all();
356     esp_vfs_dev_uart_register();
357     esp_reent_init(_GLOBAL_REENT);
358 #ifndef CONFIG_ESP_CONSOLE_UART_NONE
359     const char* default_uart_dev = "/dev/uart/" STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM);
360     _GLOBAL_REENT->_stdin  = fopen(default_uart_dev, "r");
361     _GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w");
362     _GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w");
363 #else
364     _GLOBAL_REENT->_stdin  = (FILE*) &__sf_fake_stdin;
365     _GLOBAL_REENT->_stdout = (FILE*) &__sf_fake_stdout;
366     _GLOBAL_REENT->_stderr = (FILE*) &__sf_fake_stderr;
367 #endif
368     esp_timer_init();
369     esp_set_time_from_rtc();
370 #if CONFIG_ESP32_APPTRACE_ENABLE
371     err = esp_apptrace_init();
372     assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!");
373 #endif
374 #if CONFIG_SYSVIEW_ENABLE
375     SEGGER_SYSVIEW_Conf();
376 #endif
377 #if CONFIG_ESP32_DEBUG_STUBS_ENABLE
378     esp_dbg_stubs_init();
379 #endif
380     err = esp_pthread_init();
381     assert(err == ESP_OK && "Failed to init pthread module!");
382
383     do_global_ctors();
384 #if CONFIG_ESP_INT_WDT
385     esp_int_wdt_init();
386     //Initialize the interrupt watch dog for CPU0.
387     esp_int_wdt_cpu_init();
388 #endif
389     esp_cache_err_int_init();
390     esp_crosscore_int_init();
391 #ifndef CONFIG_FREERTOS_UNICORE
392     esp_dport_access_int_init();
393 #endif
394     spi_flash_init();
395     /* init default OS-aware flash access critical section */
396     spi_flash_guard_set(&g_flash_guard_default_ops);
397
398     esp_flash_app_init();
399     esp_err_t flash_ret = esp_flash_init_default_chip();
400     assert(flash_ret == ESP_OK);
401
402     uint8_t revision = esp_efuse_get_chip_ver();
403     ESP_LOGI(TAG, "Chip Revision: %d", revision);
404     if (revision > CONFIG_ESP32_REV_MIN) {
405         ESP_LOGW(TAG, "Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.");
406     } else if(revision != CONFIG_ESP32_REV_MIN) {
407         ESP_LOGE(TAG, "ESP-IDF can't support this chip revision. Modify minimum supported revision in menuconfig");
408         abort();
409     }
410
411 #ifdef CONFIG_PM_ENABLE
412     esp_pm_impl_init();
413 #ifdef CONFIG_PM_DFS_INIT_AUTO
414     int xtal_freq = (int) rtc_clk_xtal_freq_get();
415     esp_pm_config_esp32_t cfg = {
416         .max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ,
417         .min_freq_mhz = xtal_freq,
418     };
419     esp_pm_configure(&cfg);
420 #endif //CONFIG_PM_DFS_INIT_AUTO
421 #endif //CONFIG_PM_ENABLE
422
423 #if CONFIG_ESP32_ENABLE_COREDUMP
424     esp_core_dump_init();
425     size_t core_data_sz = 0;
426     size_t core_data_addr = 0;
427     if (esp_core_dump_image_get(&core_data_addr, &core_data_sz) == ESP_OK && core_data_sz > 0) {
428         ESP_LOGI(TAG, "Found core dump %d bytes in flash @ 0x%x", core_data_sz, core_data_addr);
429     }
430 #endif
431
432 #if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
433     esp_coex_adapter_register(&g_coex_adapter_funcs);
434 #endif
435
436     bootloader_flash_update_id();
437 #if !CONFIG_SPIRAM_BOOT_INIT
438     // Read the application binary image header. This will also decrypt the header if the image is encrypted.
439     esp_image_header_t fhdr = {0};
440     // This assumes that DROM is the first segment in the application binary, i.e. that we can read
441     // the binary header through cache by accessing SOC_DROM_LOW address.
442     memcpy(&fhdr, (void*) SOC_DROM_LOW, sizeof(fhdr));
443     // If psram is uninitialized, we need to improve some flash configuration.
444     bootloader_flash_clock_config(&fhdr);
445     bootloader_flash_gpio_config(&fhdr);
446     bootloader_flash_dummy_config(&fhdr);
447     bootloader_flash_cs_timing_config();
448 #endif
449
450     portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
451                                                 ESP_TASK_MAIN_STACK, NULL,
452                                                 ESP_TASK_MAIN_PRIO, NULL, 0);
453     assert(res == pdTRUE);
454     ESP_LOGI(TAG, "Starting scheduler on PRO CPU.");
455     vTaskStartScheduler();
456     abort(); /* Only get to here if not enough free heap to start scheduler */
457 }
458
459 #if !CONFIG_FREERTOS_UNICORE
460 void start_cpu1_default(void)
461 {
462     // Wait for FreeRTOS initialization to finish on PRO CPU
463     while (port_xSchedulerRunning[0] == 0) {
464         ;
465     }
466 #if CONFIG_ESP32_TRAX_TWOBANKS
467     trax_start_trace(TRAX_DOWNCOUNT_WORDS);
468 #endif
469 #if CONFIG_ESP32_APPTRACE_ENABLE
470     esp_err_t err = esp_apptrace_init();
471     assert(err == ESP_OK && "Failed to init apptrace module on APP CPU!");
472 #endif
473 #if CONFIG_ESP_INT_WDT
474     //Initialize the interrupt watch dog for CPU1.
475     esp_int_wdt_cpu_init();
476 #endif
477     //Take care putting stuff here: if asked, FreeRTOS will happily tell you the scheduler
478     //has started, but it isn't active *on this CPU* yet.
479     esp_cache_err_int_init();
480     esp_crosscore_int_init();
481     esp_dport_access_int_init();
482
483     ESP_EARLY_LOGI(TAG, "Starting scheduler on APP CPU.");
484     xPortStartScheduler();
485     abort(); /* Only get to here if FreeRTOS somehow very broken */
486 }
487 #endif //!CONFIG_FREERTOS_UNICORE
488
489 #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
490 size_t __cxx_eh_arena_size_get(void)
491 {
492     return CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE;
493 }
494 #endif
495
496 static void do_global_ctors(void)
497 {
498 #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
499     static struct object ob;
500     __register_frame_info( __eh_frame, &ob );
501 #endif
502
503     void (**p)(void);
504     for (p = &__init_array_end - 1; p >= &__init_array_start; --p) {
505         (*p)();
506     }
507 }
508
509 static void main_task(void* args)
510 {
511 #if !CONFIG_FREERTOS_UNICORE
512     // Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack
513     while (port_xSchedulerRunning[1] == 0) {
514         ;
515     }
516 #endif
517     //Enable allocation in region where the startup stacks were located.
518     heap_caps_enable_nonos_stack_heaps();
519
520     // Now we have startup stack RAM available for heap, enable any DMA pool memory
521 #if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
522     esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
523     if (r != ESP_OK) {
524         ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r);
525         abort();
526     }
527 #endif
528
529     //Initialize task wdt if configured to do so
530 #ifdef CONFIG_ESP_TASK_WDT_PANIC
531     ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, true));
532 #elif CONFIG_ESP_TASK_WDT
533     ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false));
534 #endif
535
536     //Add IDLE 0 to task wdt
537 #ifdef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
538     TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
539     if(idle_0 != NULL){
540         ESP_ERROR_CHECK(esp_task_wdt_add(idle_0));
541     }
542 #endif
543     //Add IDLE 1 to task wdt
544 #ifdef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
545     TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
546     if(idle_1 != NULL){
547         ESP_ERROR_CHECK(esp_task_wdt_add(idle_1));
548     }
549 #endif
550
551     // Now that the application is about to start, disable boot watchdog
552 #ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE
553     rtc_wdt_disable();
554 #endif
555 #ifdef CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
556     const esp_partition_t *efuse_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM, NULL);
557     if (efuse_partition) {
558         esp_efuse_init(efuse_partition->address, efuse_partition->size);
559     }
560 #endif
561     app_main();
562     vTaskDelete(NULL);
563 }
564