Hello I’m having trouble implementing an interrupt which will activate System.reset(201).
The motivation is that my device uses multiple threads and ApplicationWatchdog () does not seem to catch delays that happen when not on the main thread.
I have implemented an interrupt which is pet (“reset”) off of the main loop. The functionality works nominally when there is a delay present and the timer is not pet. We used an LED for initial testing and on cue our timer would light the LED when time elapsed.
However, once we added the action of doing System.reset(201), everything locked up and instead of having the Particle Electron connect to cellular with cyan, it stays frozen on white. It looks like the System.reset(201) signal is being pressed very fast. You can see D7 blinking very fast and very faint. I have observed this happening when you press the Reset button at normal speed also, albeit without the fast blinking.
I would like your help understanding why the addition of System.reset(201) has such a dramatic effect on my code causing it to go from running to completely stopped.
@Adam42 The protocol with ISRs is to have a global variable defined as volatile which can be set inside the ISR and then checked in the loop() and acted upon. This is where using a FSM design template works well in that the loop() then has a state RESET_REQUESTED say which can prepare for and then issue a System.reset().
@Adam42, the issue is that System.reset() does a lot of things before actually resetting the device. This is especially important on the Electron. In your situation, an external watchdog that hard resets the Electron may be your best bet.
I see, and understood. We do have a HW WD in place but it prevents us from doing firmware updates that change version 6.4 -> 7.0 for instance. Also we would like another line of defense.
ApplicationWatchdog does not seem to catch delays that happen on seperate threads, We hoped this interrupt version would be a way to fix that, but it also seems to have issues.
How would you recommend initiating system reset in the event of a freeze on a separate thread?
We seem to be having trouble with our threads getting locked up and want a way to reset the system without signaling the operating system. Is there a way to do that?
@peekay123 Good point, we will double down on checking that
The thread is a TCP upload and we sometimes lose connection due to poor signal connection at exactly the wrong time. Its very hard to reproduce in our lab. Our devices in the field are driving across the country and we have to be able to counter a potential freeze on this thread.
I’d still like to have SW WD oversight even if the thread is working nominally, to protect against any unknown-unknowns.
@Adam42, is the thread locking up or FreeRTOS in general? If FreeRTOS is freezing up, the only other mechanism is the STM32 IWDG watchdog which is currently not implemented in the Particle DeviceOS, though it has been requested for a while now as @ScruffR can atest.
The RESET pin needs to be held LOW for some minimum time in order to do a proper reset.
If you directly wire a GPIO to RESET the pin will probably be held LOW for too short of a time.
You can add some external circuitry to prolong the LOW time tho’.
According to the electron datasheet, there is a 10k pull up res on RST and a 100nF cap to GND on RST.
I just soldered an wire between D2 and RST
no problem to reset the electron when system is running.
problem to avoid an endless reset:
#define _PIN_RST_WIRED_ (D2)
SYSTEM_THREAD(ENABLED);
setup(void){
pinMode(_PIN_RST_WIRED_, OUTPUT);
digitalWrite(_PIN_RST_WIRED_, HIGH);
...}
loop(){
...after a while
digitalWrite(_PIN_RST_WIRED_, LOW);
...
}
=> electron resetting forever
What’s happening? I thought all GPIO were inputs by default? Why is the RST pin stil down?
I desoldered one end of the wire to make a “push button contraption”. As soon as the contact between D2 and RST is broken, the system boots perfectly…
In the end, an external watchdog, will probably be better, but if we can have the same result by soldering 1 wire and some code it is definetely worth the investigation
@tdasnoy, I agree with @ScruffR that you will most likely need a one-shot multivibrator (eg 555 timer) to produce a pulse of programmable length on RST when triggered.
I’m not sure if this will work, but I’d try using HAL_Core_System_Reset() instead of System.reset() from an interrupt handler. The HAL_Core version just calls the STM32 library function NVIC_SystemReset(), which is this:
static __INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}