-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Add infinite loop after wdt_enable call #6064
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Currently when using Leonardo and derivatives reseting the watchdog in the main sketch code will interfere with the bootloader reset. This solution was proposed [by pjanco in the arduino.cc](http://forum.arduino.cc/index.php?topic=401628.msg2782592#msg2782592) forums.
This is a situation I didn't consider when working on issue #6033 and PR #6055. My PR is has changes to restore the watchdog timer for a sketch that's using it, if the auto-boot is aborted by bringing the port back up within the watchdog window. It doesn't account for this problem with the sketch resetting the watchdog. Running an infinite loop after enabling the watchdog is not an acceptable fix, though. We're in the middle of an ISR at this point, with interrupts disabled. Looping here would mean the ISR would never exit, so additional interrupt handling to clean up for, or abort, the auto-reset sequence could not occur. I think using an infinite loop to prevent the sketch code from resetting or disabling the watchdog is probably the only acceptable solution, but it would have to be executed in the foreground, not in an ISR. Perhaps the ISR could just set a flag which could be tested in the infinite for loop that calls loop() in file main.cpp. The flag would be set in CDC.cpp after starting the auto-reset watchdog (where the loop is in this PR). The flag would be cleared where the watchdog is stopped and restored if the port comes back up. Declare the flag somewhere: volatile bool _autoBootWatchdogRunning = false; In main.cpp: --- org/main.cpp 2016-02-19 10:57:26.000000000 -0500
+++ new/main.cpp 2017-03-12 17:47:08.483680084 -0400
@@ -43,6 +43,9 @@
setup();
for (;;) {
+#if defined(USBCON)
+ while (_autoBootWatchdogRunning) { }
+#endif
loop();
if (serialEventRun) serialEventRun();
} Note that this fix will not prevent the case where the sketch is resetting the watchdog within an ISR that it has created. I don't think there is an acceptable solution for this case. You would have to disable all interrupts (or shut down their source in some other way), other than those used by USB, during the watchdog timeout window. If the auto-reset was aborted, you would then have to re-enable those interrupts that were previously enabled. This would likely end up being quite messy. |
Will that still allow the USB code to run incase the baud rate is toggled again, cancelling the reset - or is that functionality that no one uses anyways? Is any USB stuff is processed by Basically turning it into:
|
Yeah I think that's an unsolvable edge case. Though most sketches shouldn't be mucking with the WDT. |
@yyyc514, I believe serialEventRun is strictly for the benefit of the serialEvent() function made available to sketches, so it's better not to run it while waiting on the watchdog. Also, I think it's only for physical UARTs not the USB CDC virtual one. |
Ok, great. I just saw that and didn't look at it super closely. |
Closing in in favour of #6055 |
Currently when using Leonardo and derivatives reseting the watchdog in the main sketch code will interfere with the bootloader reset. This solution was proposed by pjanco in the arduino.cc forums.