Implementing Failsafe Mechanism for Firmware Updates on ESP32
Hey guys i am building a custom ESP32-based project (using the ESP32 DevKitC v4 board, with ESP-IDF version 4.4) and want to implement a failsafe mechanism for firmware updates. I've connected GPIO0 to ground via a switch, intending to enter flash mode when the button is pressed and
ESP.restart()
is called. However, ESP.restart()
only restarts the app, ignoring the GPIO0 state.
During the restart process, I've captured the following logs and debug messages:
"Restarting..."
"CPU reset..."
"Boot mode: 3 (FLASH BOOT)"
"Flash booting @ 0x1000"
Despite these logs indicating a flash boot, the board doesn't enter flash mode. I've tried using ESP.restart()
with the button pressed, but it doesn't work as expected.
Can I force a full boot process, potentially using a direct jump to the hardware reset vector, to enter flash mode when the button is pressed and ESP.restart()
is called? Any insights or solutions would be greatly appreciatedSolution:Jump to solution
Use the ESP32's RTC_CNTL_SW_SYS_RST register to perform a hardware reset @Daniel kalu , it will check the state of GPIO0 and enter flash mode if it's grounded.
4 Replies
Solution
Use the ESP32's RTC_CNTL_SW_SYS_RST register to perform a hardware reset @Daniel kalu , it will check the state of GPIO0 and enter flash mode if it's grounded.
See this #include "esp_system.h"
#include "esp_attr.h"
void restart_to_flash_mode() {
// Check if GPIO0 is grounded (button pressed)
if (gpio_get_level(GPIO_NUM_0) == 0) {
// Perform hardware reset instead of software reset
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
} else {
ESP.restart(); // Perform normal software reset if GPIO0 is not grounded
}
}
Using the
RTC_CNTL_SW_SYS_RST
register works perfectly for forcing a hardware reset and entering flash mode when GPIO0 is grounded. The restart_to_flash_mode()
function is exactly what I needed.
Thank you for your solution 🙏Happy to help @Daniel kalu