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();
slemke
February 21, 2025, 10:16pm
3
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
steve9
February 22, 2025, 6:30am
4
You may want to try getResetReason(); from class STM32H747
DR29,
DR30,
DR31,
};
class STM32H747 {
public:
virtual bool begin() = 0;
virtual bool enterLowPower() = 0;
static reset_reason_t getResetReason();
static uint32_t readBackupRegister(RTCBackup register);
static void writeBackupRegister(RTCBackup register, uint32_t data);
protected:
uint8_t readReg(uint8_t subAddress);
void setRegister(uint8_t reg, uint8_t val);
bool useInternalOscillator(bool lowspeed = false);
};
#endif
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.
BOOT_LOG_INF("Start OTA 0x%X 0x%X 0x%X", storage_type, offset, update_size);
return tryOTA(storage_type, offset, update_size);
}
int main(void) {
debug_init();
BOOT_LOG_INF("Starting Arduino bootloader");
int magic = RTCGetBKPRegister(RTC_BKP_DR0);
int reset = ResetReason::get();
RTCSetBKPRegister(RTC_BKP_DR8, reset);
// in case we have been reset let's wait 500 ms to see if user is trying to stay in bootloader
if (reset == RESET_REASON_PIN_RESET) {
// now that we've been reset let's set magic. resetting with this set will
// flag we need to stay in bootloader.
RTCSetBKPRegister(RTC_BKP_DR0, 0xDF59);
HAL_Delay(500);
}
slemke
February 24, 2025, 12:22pm
5
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
steve9
February 24, 2025, 2:20pm
6
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.
slemke
February 24, 2025, 2:48pm
7
Hello,
thanks a lot for your assistance!
I will raise an github issue in the next few days.
Regards,
Sebastian
steve9
February 24, 2025, 3:00pm
8
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.