-
-
Notifications
You must be signed in to change notification settings - Fork 724
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
HardwareSerial/Uart write and flush lock up when interrupts are disabled #472
Comments
I think the same problem (and probably the same solution) applies to the |
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Feb 12, 2020
On some Arduino cores, printing with IRQs disabled is problematic (see e.g. arduino/ArduinoCore-samd#472). In general, disabling interrupts for shorter amounts of time is a good idea anyway.
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Feb 12, 2020
Serial printing with IRQs disabled is problematic on some Arduino cores, see e.g. arduino/ArduinoCore-samd#472
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Feb 12, 2020
This prevents printing with interrupts disabled, which is problematic on some Arduino cores, see e.g. arduino/ArduinoCore-samd#472
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Feb 12, 2020
On some Arduino cores, printing with IRQs disabled is problematic (see e.g. arduino/ArduinoCore-samd#472). In general, disabling interrupts for shorter amounts of time is a good idea anyway.
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Feb 12, 2020
Serial printing with IRQs disabled is problematic on some Arduino cores, see e.g. arduino/ArduinoCore-samd#472
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Feb 12, 2020
This prevents printing with interrupts disabled, which is problematic on some Arduino cores, see e.g. arduino/ArduinoCore-samd#472
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Apr 15, 2020
On some Arduino cores, printing with IRQs disabled is problematic (see e.g. arduino/ArduinoCore-samd#472). In general, disabling interrupts for shorter amounts of time is a good idea anyway.
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Apr 15, 2020
Serial printing with IRQs disabled is problematic on some Arduino cores, see e.g. arduino/ArduinoCore-samd#472
matthijskooijman
added a commit
to LacunaSpace/basicmac
that referenced
this issue
Apr 15, 2020
This prevents printing with interrupts disabled, which is problematic on some Arduino cores, see e.g. arduino/ArduinoCore-samd#472
This was referenced Sep 22, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In Uart (HardwareSerial), when the
write()
method is called and the buffer is full, it blocks until buffer room becomes available. Whenflush()
is called, it blocks until the buffer is empty (and the last byte is also transmitted).However, when these methods are called with interrupts disabled (or from an ISR with higher priority than the UART interrupt), the ISR that makes room in the buffer will never run, so this waiting blocks indefinitely, locking up the system.
Of course, one can say that serial printing from an ISR or with interrupts disabled is not a good idea, but it often makes sense for debugging (or e.g. for printing an error on a failed assertion).
On AVR, this is fixed by detecting that interrupts are disabled, and if so, manually checking the interrupt flag and run the ISR manually when the interrupt flag is set (code). This makes sure that printing and flushing with interrupts disabled works as expected (there is still the related issue of Uart code that can get interrupted by an ISR that accesses the UART, leading to inconsistent state, but that is a separate issue and far less likely to occur in practice, so not so problematic for debugging).
It would be good to implement the same thing in the SAMD core Uart. One complication is that while on AVR there is a single "interrupts are disabled" flag, on SAMD you would have to check:
VECTACTIVE
, but does have theIPSR
register that provides the needed information).PM
bit in thePRIMASK
register is set (which disables all interrupts)See also http://infocenter.arm.com/help/topic/com.arm.doc.dui0662b/DUI0662B_cortex_m0p_r0p1_dgug.pdf
An implementation could look like (pseudocode):
This might also need to clear the pending bit if that is not automatic. Also, the if might be good to put into a utility function, so it can be used in other places too.
One alternative implementation would be to detect this situation and temporarily raise the Uart interrupt priority until the loop completes. However, this will not work when the
PM
bit is set, when the current interrupt already has priority 0 (or less, for e.g. NMI or hardfault), so this probably is not a viable option.A completely different behaviour would be to detect that the ISR cannot run and drop bytes instead of waiting, but that significantly changes the behaviour of these functions (and this deviates from the AVR behaviour), so I don't think that's a good idea.
I suspect that the USB CDC code suffers from exactly the same problem and should probably be fixed in the same way, but have not tested this.
The text was updated successfully, but these errors were encountered: