Arduino-esp32: How can I read the reset reason

Created on 16 Jun 2017  路  14Comments  路  Source: espressif/arduino-esp32

Hello,
I need to read the reset reason.

I found a reference in tools/sdk/include/esp32/rom/rtc.h:
RESET_REASON rtc_get_reset_reason(int cpu_no);

How can I use it in the Arduino IDE?

for reference

Most helpful comment

It's not the beautiful code in the world, but there it is:

#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:

}

You also need to be aware of why some reasons occur: https://github.com/espressif/esp-idf/issues/494

All 14 comments

Hi,
ESP8266-approach didn't work there, I tested it before.

I double-check your solution:

  1. I tested die CallSDKFunction:
    Compiler reported: "...fatal error: user_interface.h: No such file or directory"
  2. Look at Library:
    cd /Documents/Arduino/hardware/espressif/esp32
    sudo find . -print | grep -i 'user_interface' -> There is no file!

It's not the beautiful code in the world, but there it is:

#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:

}

You also need to be aware of why some reasons occur: https://github.com/espressif/esp-idf/issues/494

Super solution! Thank you!

My short use case was:
~~~~

include

int get_reset_reason(int icore) {
return (int) rtc_get_reset_reason( (RESET_REASON) icore);
}

void setup () {
if ( get_reset_reason(0) == 12) { // = SW_CPU_RESET
// do something
}
}
~~~~

It was part of a workaround to change baudrate on the fly, please look at Issue #441

or more simple:

#include <rom/rtc.h>

void setup () {
   if ( (int)rtc_get_reset_reason(0) == 12)  { // =  SW_CPU_RESET
        // do something
   }
}

or a little bit more simple and with using the constant:
~~~~

include

void setup () {
if ( rtc_get_reset_reason(0) == SW_CPU_RESET ) {
// do something
}
}
~~~~

Thanks, this was a great and small solution.

Do you have another great idea for changing the baudrate of one uart on the fly:

  • ESP started with baudrate 38400
  • On the fly then baudrate changed to 115200. That means without any restart.

Please look at #441

@copercini thanks for the sketch. Quick question: if esp32 crashed due to some reason and reboots. How do I know the reason or stack trace on reboot?

@arvindr21 you can get the stack trace printed in the serial and decode with https://github.com/me-no-dev/EspExceptionDecoder ;D

This is when I have access to the serial monitor. Let's say the device is running remotely and crashed. On boot I would like to check the boot reason & if possible stack trace and relay it back to my servers to improve the firmware. Doable?

In my projects, it makes some checks in the boot, like: sd card is mounted, RFID RC522 is started correctly, last reboot reason, ipv4, ipv6 and send it via MQTT if got a connection or creates a webserver and print it in a "debug page" if offline.

Anyway, IDF has a option to store the crash log in the flash memory, take a look here: https://esp-idf.readthedocs.io/en/v2.0/core_dump.html

Thanks @copercini I am planning to something similar. Send it to an end point on boot, so I know what is happening on the remote device. Will check out the in-memory crash log. Thanks.

Hi Guys,
where should I find #include ?

error: rom/rtc.h: No such file or directory

Thank you

Hi majid1350,
you found it here:
$ls $IDF_PATH/components/esp_rom/include/esp32/rom/rtc.h

Was this page helpful?
0 / 5 - 0 ratings

Related issues

merlinschumacher picture merlinschumacher  路  4Comments

0x1abin picture 0x1abin  路  3Comments

maxpromer picture maxpromer  路  3Comments

lonerzzz picture lonerzzz  路  3Comments

OAXP picture OAXP  路  4Comments