Enhancement - automatic safe mode after 10 panics in a short time


#1

I recently had a problem where a deployed Photon got into a repeat panic. I could monitor via the console that it would boot, get up, panic. It repeated this over and over and over.

I would like a setting that I could enable in my code called Auto Safe Mode. When enabled the base OS will keep track of automatic reboots. If it does more than 10 in 10 minutes then the device will go into Safe Mode automatically.

I know this feature would not be good for everyone, but I’d turn it on in every one of my deployed applications. This feature would allow me to remotely recover a device that has gotten itself stuck.

If such a feature exists, please let me know; I was unable to google it.


#2

I think the best thing to do would be to carefully analyze your application to determine the root cause of the panic.

I agree that having an automatic safe mode feature after a defined number of panics would be useful.


#3

I could carefully analyze my application, but the fact is, the code runs fine now. After I did the upgrade in little steps the exact same code that was failing is running without a problem.

While this could be my code triggering something in the later OS, why is it running now?
Jim


#4

A similar feature did exist but caused other issues (e.g. batteries draining) so it was taken out and instead new features were added to allow user code to self-monitor.
You can use a retained panic counter and time tracking variable and in a STARTUP() routine check the reset reason. If you detect a problem call System.enterSafeMode().


#5

You could use a retained variable along with using the reset reason feature to put your code into a safe loop.

While (true) {
Particle.process();
}

I actually had this problem last night and added a manual function which has to be called before the code continues. I’ll be adding this method instead :slight_smile:


#6

Untested as I’m at work but this should do the job.

retained uint32_t lastHardResetTime;
retained int resetCount;

STARTUP(System.enableFeature(FEATURE_RESET_INFO));

void setup() {
    waitFor(Particle.connected, 30000);
    
    while (Time.now() < 1550000000) {
        Particle.process();
    }
    
    if (System.resetReason() == RESET_REASON_PANIC) {
        if ((Time.now() - lastHardResetTime) < 120) {
            resetCount++;
        } else {
            resetCount = 1;
        }
        
        lastHardResetTime = Time.now();

        if (resetCount > 3) {
            System.enterSafeMode();
        }
    }
}

void loop() {
    abort();
}