// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include "rom/rtc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/xtensa_api.h" #include "soc/uart_reg.h" #include "soc/io_mux_reg.h" #include "soc/dport_reg.h" #include "soc/rtc_cntl_reg.h" #include "soc/timer_group_struct.h" #include "soc/timer_group_reg.h" #include "esp_gdbstub.h" #include "esp_panic.h" /* Panic handlers; these get called when an unhandled exception occurs or the assembly-level task switching / interrupt code runs into an unrecoverable error. The default task stack overflow handler also is in here. */ #if !CONFIG_ESP32_PANIC_SILENT_REBOOT //printf may be broken, so we fix our own printing fns... inline static void panicPutchar(char c) { while (((READ_PERI_REG(UART_STATUS_REG(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ; WRITE_PERI_REG(UART_FIFO_REG(0), c); } inline static void panicPutStr(const char *c) { int x=0; while (c[x]!=0) { panicPutchar(c[x]); x++; } } inline static void panicPutHex(int a) { int x; int c; panicPutchar(' '); for (x=0; x<8; x++) { c=(a>>28)&0xf; if (c<10) panicPutchar('0'+c); else panicPutchar('a'+c-10); a<<=4; } } inline static void panicPutDec(int a) { int n1, n2; n1=a%10; n2=a/10; panicPutchar(' '); if (n2==0) panicPutchar(' '); else panicPutchar(n2+'0'); panicPutchar(n1+'0'); } #else //No printing wanted. Stub out these functions. inline static void panicPutchar(char c) { } inline static void panicPutStr(const char *c) { } inline static void panicPutHex(int a) { } inline static void panicPutDec(int a) { } #endif void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) { panicPutStr("***ERROR*** A stack overflow in task "); panicPutStr((char*)pcTaskName); panicPutStr(" has been detected.\r\n"); } static const char *edesc[]={ "IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError", "Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue", "Privileged", "LoadStoreAlignment", "res", "res", "InstrPDAddrError", "LoadStorePIFDataError", "InstrPIFAddrError", "LoadStorePIFAddrError", "InstTLBMiss", "InstTLBMultiHit", "InstFetchPrivilege", "res", "InstrFetchProhibited", "res", "res", "res", "LoadStoreTLBMiss", "LoadStoreTLBMultihit", "LoadStorePrivilege", "res", "LoadProhibited", "StoreProhibited", "res", "res", "Cp0Dis", "Cp1Dis", "Cp2Dis", "Cp3Dis", "Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis" }; void commonErrorHandler(XtExcFrame *frame); //The fact that we've panic'ed probably means the other CPU is now running wild, possibly //messing up the serial output, so we kill it here. static void haltOtherCore() { if (xPortGetCoreID()==0) { //Kill app cpu CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M); SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<