Saltar a contenido

70. ESPERSSIF ESP32

70.1 WATCH DOG

Usando Arduino Platform Documentación oficial,

Por ejemplo:

#include <esp_task_wdt.h>
//3 seconds WDT
#define WDT_TIMEOUT 3
void setup() {
  Serial.begin(115200);
  Serial.println("Configuring WDT...");
  esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
  esp_task_wdt_add(NULL); //add current thread to WDT watch
}
int i = 0;
int last = millis();
void loop() {
  // resetting WDT every 2s, 5 times only
  if (millis() - last >= 2000 && i < 5) {
      Serial.println("Resetting WDT...");
      esp_task_wdt_reset();
      last = millis();
      i++;
      if (i == 5) {
        Serial.println("Stopping WDT reset. CPU should reboot in 3s");
      }
  }
}
Que se resume:
1. incluimos esp_task_wdt.h 2. En el setup esp_task_wdt_init(WDT_TIMEOUT, true) con true implica reboot al cumplir WDT_TIMEOUT 3. esp_task_wdt_add(NULL) añade el wdt a la tarea actual. y en general esp_err_tesp_task_wdt_add(TaskHandle_t handle) Añade a la tarea con handle 4. Resetear el watchdog en el código antes del timeout: esp_task_wdt_reset()

70.2 REBOOT

Ejemplo:

#include <rom/rtc.h>

void print_reset_reason(RESET_REASON reason)
{
  switch ( reason)
  {
    case 1 : Serial.println ("POWERON_RESET");break;          /**<1, Vbat power on reset*/
    case 3 : Serial.println ("SW_RESET");break;               /**<3, Software reset digital core*/
    case 4 : Serial.println ("OWDT_RESET");break;             /**<4, Legacy watch dog reset digital core*/
    case 5 : Serial.println ("DEEPSLEEP_RESET");break;        /**<5, Deep Sleep reset digital core*/
    case 6 : Serial.println ("SDIO_RESET");break;             /**<6, Reset by SLC module, reset digital core*/
    case 7 : Serial.println ("TG0WDT_SYS_RESET");break;       /**<7, Timer Group0 Watch dog reset digital core*/
    case 8 : Serial.println ("TG1WDT_SYS_RESET");break;       /**<8, Timer Group1 Watch dog reset digital core*/
    case 9 : Serial.println ("RTCWDT_SYS_RESET");break;       /**<9, RTC Watch dog Reset digital core*/
    case 10 : Serial.println ("INTRUSION_RESET");break;       /**<10, Instrusion tested to reset CPU*/
    case 11 : Serial.println ("TGWDT_CPU_RESET");break;       /**<11, Time Group reset CPU*/
    case 12 : Serial.println ("SW_CPU_RESET");break;          /**<12, Software reset CPU*/
    case 13 : Serial.println ("RTCWDT_CPU_RESET");break;      /**<13, RTC Watch dog Reset CPU*/
    case 14 : Serial.println ("EXT_CPU_RESET");break;         /**<14, for APP CPU, reseted by PRO CPU*/
    case 15 : Serial.println ("RTCWDT_BROWN_OUT_RESET");break;/**<15, Reset when the vdd voltage is not stable*/
    case 16 : Serial.println ("RTCWDT_RTC_RESET");break;      /**<16, RTC Watch dog reset digital core and rtc module*/
    default : Serial.println ("NO_MEAN");
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(2000);

  Serial.println("CPU0 reset reason: ");
  print_reset_reason(rtc_get_reset_reason(0));

  Serial.println("CPU1 reset reason: ");
  print_reset_reason(rtc_get_reset_reason(1));

}

void loop() {
  // put your main code here, to run repeatedly:

}
O lo mismo con otra implemenetación
String razon_reset[] ={"None","POWERON_RESET", "dos","SW_RESET","OWDT_RESET","DEEPSLEEP_RESET",
                      "SDIO_RESET","TG0WDT_SYS_RESET","TG1WDT_SYS_RESET","RTCWDT_SYS_RESET","INTRUSION_RESET",
                      "TGWDT_CPU_RESET","SW_CPU_RESET","RTCWDT_CPU_RESET","EXT_CPU_RESET","RTCWDT_BROWN_OUT_RESET",
                      "RTCWDT_RTC_RESET"};

//======================================================================
//======================================================================

String ultimo_reboot(){
  RESET_REASON reason;
  String str0, str1;
  reason= rtc_get_reset_reason(0);
  if (reason <17)
     str0 = "<p>CPU 0 :" + razon_reset[reason] + "</p>";
  else
      str0 = "Desconocido";

  reason= rtc_get_reset_reason(0);
  if (reason <17)
     str1 = "<p>CPU 1 :" + razon_reset[reason] +"</p>";
  else
      str1 = "Desconocido";
   return str0+str1;
}

70.3 ERROR FATAL

Documentación oficial.
Para el IDE de Arduino con Platformio, seguir esta guia

Situaciones que llevan a un error fatal: * Excepciones de CPU: * Instrucciónilegarl * Error de alineamiento de Load/Store * Load/Store no permitido * Salvaguardas a nivel sistema * Interrupción watchdog * Task watchdog * Error de acceso a cache * Evento detección "Brownout" * Chequeo de protección de Stack * Chequeo de integridad de HEAP * Comportamiento indefinido

70.3.1 Panic Handler

El panic handler empieza volcando la causa del error a consola, por ejemplo:

Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
Se puede configurar como continua el Panic Handler: * Impimir registro y reboot (CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT) — default option. * Impimir registros y parar (CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT) * Reboot silencioso (CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT) -- continuar --

70.3.2 Depurado de COREDUMP

Documentación oficial.
El volcado coredump se produce por fallos hardware o software. Después del fallo, elprocesador entra en estado de panico vuelca cierta información y pasa a estado halt o reinicia.
La información se puede volcar a memoria FLASH o al puerto serie.
Esta información tiene que ser analiza en el PC, incluye el estado de las tareas, stack etc.
ESP-IDF proporciona el script espcoredump.py para analizar este volcado y proporciona dos comandos: * info_corefile que imprime los registors, callstack, tareas del sistema,y memoria. * dbg_corefile Crea un fichero ELF que se puede usar con GDB

70.3.3 Configuración usando IDF IDE

Ejecutamos idf.py menuconfig * Destino del volcado: * Flash * UART * NINGUNO (deshabilitado)

Formato del coredump:
* ELF * BINARIO

Otra utilidad en java para decodificar el coredump