You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have noticed that after splitting the BufferedUart and dropping the tx, the uart stops reading. I have quickly traced the problem in the Drop implementation of both BufferedUartRx and BufferedUartTx.
let state = T::buffered_state();unsafe{ state.tx_buf.deinit()}// RX is inactive if the the buffer is not available.// We can now unregister the interrupt handlerif state.rx_buf.is_empty(){T::Interrupt::disable();}
Interrupts get disabled when either the rx or tx are dropped. This happens because rx_buf.is_empty() does not actually check if the buffer is not available but if it is empty. It might be empty at a certain time but that does not mean it is not available.
let state = T::buffered_state();unsafe{ state.tx_buf.deinit()}// RX is inactive if the buffer is not available.// We can now unregister the interrupt handlerif state.rx_buf.len() == 0{T::Interrupt::disable();}
This is a relatively easy fix but we quickly arrive at another issue. The interrupt does not actually check if the buffer is initialized or not. And because the drop function deinitializes the buffer we get a panic:
0.119691 ERROR panicked at library/core/src/panicking.rs:220:5:
unsafe precondition(s) violated: slice::from_raw_parts_mut requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
This comes from the ring buffer because after the buffer is uninitialized the pointer to the data becomes null. After adding the same checks as in the drop method in the interrupt handler we get rid of all the bugs and everything works as expected.
I suggest we change the RingBuffer struct by adding some methods for checking if it is initialized or not. Fun fact: clippy actually suggests to replace state.rx_buf.len() == 0 with s.tx_buf.is_empty() which is wrong. Maybe doing some renaming of those methods is also important.
In addition, maybe we can also do a rewrite of the RingBuffer as it is quite unsafe at the moment.
I would like to create a pull request to fix this bug by adding the necessary checks and maybe renaming some of the methods inside the RingBuffer. Is this ok with you?
The text was updated successfully, but these errors were encountered:
I have noticed that after splitting the
BufferedUart
and dropping the tx, the uart stops reading. I have quickly traced the problem in theDrop
implementation of bothBufferedUartRx
andBufferedUartTx
.Interrupts get disabled when either the rx or tx are dropped. This happens because
rx_buf.is_empty()
does not actually check if the buffer is not available but if it is empty. It might be empty at a certain time but that does not mean it is not available.This is a relatively easy fix but we quickly arrive at another issue. The interrupt does not actually check if the buffer is initialized or not. And because the drop function deinitializes the buffer we get a panic:
This comes from the ring buffer because after the buffer is uninitialized the pointer to the data becomes null. After adding the same checks as in the drop method in the interrupt handler we get rid of all the bugs and everything works as expected.
I suggest we change the RingBuffer struct by adding some methods for checking if it is initialized or not. Fun fact: clippy actually suggests to replace
state.rx_buf.len() == 0
withs.tx_buf.is_empty()
which is wrong. Maybe doing some renaming of those methods is also important.In addition, maybe we can also do a rewrite of the RingBuffer as it is quite unsafe at the moment.
I would like to create a pull request to fix this bug by adding the necessary checks and maybe renaming some of the methods inside the
RingBuffer
. Is this ok with you?The text was updated successfully, but these errors were encountered: