components/esp32: fix and clean up dual core startup

This change removes various delays in PRO and APP CPU startup paths.
Also some unused code and ets_printf statements are cleaned up or removed.
2nd CPU now communicates that it has started through a global variable.
This commit is contained in:
Ivan Grokhotkov 2016-08-24 16:21:28 +08:00
parent 29c2e58c75
commit be112daa71

View File

@ -64,6 +64,8 @@ void uartAttach();
void ets_set_appcpu_boot_addr(uint32_t ent); void ets_set_appcpu_boot_addr(uint32_t ent);
int ets_getAppEntry(); int ets_getAppEntry();
static bool app_cpu_started = false;
void IRAM_ATTR call_user_start_cpu0() { void IRAM_ATTR call_user_start_cpu0() {
//Kill wdt //Kill wdt
REG_CLR_BIT(0x3ff4808c, BIT(10)); //RTCCNTL+8C RTC_WDTCONFIG0 RTC_ REG_CLR_BIT(0x3ff4808c, BIT(10)); //RTCCNTL+8C RTC_WDTCONFIG0 RTC_
@ -114,53 +116,34 @@ void IRAM_ATTR call_user_start_cpu0() {
heap_alloc_caps_init(); heap_alloc_caps_init();
ets_printf("Pro cpu up.\n"); ets_printf("Pro cpu up.\n");
#ifndef CONFIG_FREERTOS_UNICORE #ifndef CONFIG_FREERTOS_UNICORE
ets_printf("Running app cpu, entry point is %p\n", call_user_start_cpu1); ets_printf("Starting app cpu, entry point is %p\n", call_user_start_cpu1);
ets_delay_us(60000);
SET_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN); SET_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN);
CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_C, DPORT_APPCPU_RUNSTALL);
SET_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING); SET_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING);
CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING); CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING);
for (int i=0; i<20; i++) ets_delay_us(40000);
ets_set_appcpu_boot_addr((uint32_t)call_user_start_cpu1); ets_set_appcpu_boot_addr((uint32_t)call_user_start_cpu1);
ets_delay_us(10000); while (!app_cpu_started) {
ets_delay_us(100);
// while (ets_getAppEntry()==(int)call_user_start_cpu1) ; }
//Because of Reasons (tm), the pro cpu cannot use the SPI flash while the app cpu is booting.
// while(((READ_PERI_REG(RTC_STORE7))&BIT(31)) == 0) ; // check APP boot complete flag
ets_delay_us(50000);
ets_delay_us(50000);
ets_printf("\n\nBack to pro cpu.\n");
#else #else
CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN); CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN);
#endif #endif
ets_printf("Pro cpu start user code\n");
user_start_cpu0(); user_start_cpu0();
} }
extern int xPortGetCoreID();
extern int _init_start; extern int _init_start;
/*
We arrive here because the pro CPU pulled us from reset. IRAM is in place, cache is still disabled, we can execute C code.
*/
void IRAM_ATTR call_user_start_cpu1() { void IRAM_ATTR call_user_start_cpu1() {
//We need to do this ASAP because otherwise the structure to catch the SYSCALL instruction, which
//we abuse to do ROM calls, won't work.
asm volatile (\ asm volatile (\
"wsr %0, vecbase\n" \ "wsr %0, vecbase\n" \
::"r"(&_init_start)); ::"r"(&_init_start));
//Enable SPI flash
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, FUNC_SD_DATA3_SPIWP); // swap PIN SDDATA3 from uart1 to spi, because cache need spi
ets_printf("App cpu up\n");
//Make page 0 access raise an exception //Make page 0 access raise an exception
//Also some other unused pages so we can catch weirdness //Also some other unused pages so we can catch weirdness
//ToDo: this but nicer. //ToDo: this but nicer.
@ -192,16 +175,15 @@ void IRAM_ATTR call_user_start_cpu1() {
"isync\n" \ "isync\n" \
:::"a4","a5"); :::"a4","a5");
ets_printf("App cpu up.\n");
app_cpu_started = 1;
user_start_cpu1(); user_start_cpu1();
} }
extern volatile int port_xSchedulerRunning; extern volatile int port_xSchedulerRunning;
extern int xPortStartScheduler(); extern int xPortStartScheduler();
void user_start_cpu1(void) { void user_start_cpu1(void) {
ets_printf("App cpu is running!\n");
//Wait for the freertos initialization is finished on CPU0 //Wait for the freertos initialization is finished on CPU0
while (port_xSchedulerRunning == 0) ; while (port_xSchedulerRunning == 0) ;
ets_printf("Core0 started initializing FreeRTOS. Jumping to scheduler.\n"); ets_printf("Core0 started initializing FreeRTOS. Jumping to scheduler.\n");
@ -221,11 +203,12 @@ static void do_global_ctors(void) {
void user_start_cpu0(void) { void user_start_cpu0(void) {
esp_err_t ret;
ets_setup_syscalls(); ets_setup_syscalls();
do_global_ctors(); do_global_ctors();
// TODO: consider ethernet interface
#if CONFIG_WIFI_ENABLED
#if 1 //workaround #if 1 //workaround
for (uint8_t i = 5; i < 8; i++) { for (uint8_t i = 5; i < 8; i++) {
ets_printf("erase sector %d\n", i); ets_printf("erase sector %d\n", i);
@ -233,8 +216,8 @@ void user_start_cpu0(void) {
} }
#endif #endif
ets_printf("nvs_flash_init\n"); ets_printf("nvs_flash_init\n");
ret = nvs_flash_init(5, 3); esp_err_t ret = nvs_flash_init(5, 3);
if (ESP_OK != ret) { if (ret != ESP_OK) {
ets_printf("nvs_flash_init fail, ret=%d\n", ret); ets_printf("nvs_flash_init fail, ret=%d\n", ret);
} }
@ -242,9 +225,8 @@ void user_start_cpu0(void) {
esp_event_init(NULL); esp_event_init(NULL);
// TODO: consider ethernet interface
#if CONFIG_WIFI_ENABLED
tcpip_adapter_init(); tcpip_adapter_init();
#endif #endif
#if CONFIG_WIFI_ENABLED && CONFIG_WIFI_AUTO_STARTUP #if CONFIG_WIFI_ENABLED && CONFIG_WIFI_AUTO_STARTUP