Last Reset Reason is always UNKNOWN

It is possible to read the last reset reason with the following code, but it always returns RESET_REASON_UNKNOWN. Does Arduino Opta not support this function? How do I know if it is supported?

#include <drivers/ResetReason.h>
mbed::ResetReason::get();

Provide context.

Hello,

same problem here also on an OPTA.

Here is an example sketch:

#include <Watchdog.h>
#include <mbed.h>
#include <ResetReason.h>

mbed::Watchdog& watchdog = mbed::Watchdog::get_instance();

void setup() {

  // get ResetReason
  const reset_reason_t reason = mbed::ResetReason::get();

  Serial.begin(115200);         // Open serial communications
  Serial.setTimeout(1000);    // Timeout for .readstring()
  while (!Serial) { };   // wait for port to open - needed for native USB port only

  String clearText = "";
  char buf[9];

  switch (reason) {  
    case RESET_REASON_POWER_ON:       { clearText = "PowerOn"; break; }
    case RESET_REASON_PIN_RESET:      { clearText = "Pin reset"; break; }
    case RESET_REASON_BROWN_OUT:      { clearText = "Voltage dropped below the low voltage detect"; break; }
    case RESET_REASON_SOFTWARE:       { clearText = "Software reset"; break; }
    case RESET_REASON_WATCHDOG:       { clearText = "Watchdog"; break; }
    case RESET_REASON_LOCKUP:         { clearText = "Lockup - unrecoverable exception"; break; }
    case RESET_REASON_WAKE_LOW_POWER: { clearText = "wake up from deep sleep"; break; }
    case RESET_REASON_ACCESS_ERROR:   { clearText = "Umbrella value that encompasses any boot related reset"; break; }
    case RESET_REASON_BOOT_ERROR:     { clearText = "Boot error"; break; }
    case RESET_REASON_MULTIPLE:       { clearText = "Multiple"; break; }
    case RESET_REASON_PLATFORM:       { clearText = "Platform specific"; break; }
    case RESET_REASON_UNKNOWN:        { clearText = "unknown"; break; }
    default:                          { clearText = "undefined"; break; }
  }    

  Serial.print("> last reboot reason: ");
  Serial.print(clearText);
  sprintf(buf, " (0x%02x)", reason); 
  Serial.println(buf);

  // Trigger a Watchdog Reset for testing....
  watchdog.start(5000);  
  
  while (true) {
    // do NOT kick watchdog regularly within provided timeout
    // watchdog.kick();
  }  

}

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

}

Output:

> last reboot reason: unknown (0x0b)

Expected:

> last reboot reason: Watchdog

You may want to try getResetReason(); from class STM32H747

Update: STM32H747::getResetReason(); works on the GIGA

An alternative way, without including the library, is to read the register directly:

extern RTC_HandleTypeDef RTCHandle;
...
reason = RTCHandle.Instance->BKP8R;

N.B. works on GIGA, should work on OPTA

FYI, the reason ResetReason::get() is returning UNKNOWN when called from the application is that a call to get() clears the reason, and a call to get() is made by the mcuboot loader. The loader does this so that it can detect a double-tap of the reset pin and keep you in bootloader mode. As the reason has been cleared from mbed RSR register, the loader saves the reason in a backup register that can be queried by the app.

Hello,

thanks for your reply. I have tested both:

Both without success - I get always "RESET_REASON_POWER_ON" = 0x00.

Do you have any idea here?

Thanks,
Sebastian

Hi Sebastian, that is most unexpected. I suggest raising a git issue or an Arduino support case to seek guidance - I'm out of ideas.

Hello,

thanks a lot for your assistance!
I will raise an github issue in the next few days.

Regards,
Sebastian

FYI, this is the issue raised against mcuboot-arduino-stm32h7 Don't clear Reset Source Register on boot · Issue #14 · arduino/mcuboot-arduino-stm32h7 · GitHub that resulted in this commit Store reset reason in RTC backup register 8 · arduino/mcuboot-arduino-stm32h7@fc72657 · GitHub
I can only think either it isn't included in your version of this bootloader, or the opta is running some other loader, or something in the platform setup is resetting the registers.