Skip to content

Conversation

Kezii
Copy link
Contributor

@Kezii Kezii commented Oct 9, 2025

fixes #4750

probably not the optimal solution? let me know what to do instead

@i509VCB
Copy link
Member

i509VCB commented Oct 9, 2025

In an ideal world the reader would be told that an overrun happened, rather than an error message. read would return an error at the point where an overrun happened.

Edit: An example of this is what is done in the mspm0 HAL:

if (data.0 >> 8) != 0 {
// Cortex-M0 does not support atomic fetch_or, must do 2 operations.
critical_section::with(|_cs| {
let mut value = state.rx_error.load(Ordering::Relaxed);
value |= (data.0 >> 8) as u8;
state.rx_error.store(value, Ordering::Relaxed);
});
error = true;
// only fill the buffer with valid characters. the current character is fine
// if the error is an overrun, but if we add it to the buffer we'll report
// the overrun one character too late. drop it instead and pretend we were
// a bit slower at draining the rx fifo than we actually were.
// this is consistent with blocking uart error reporting.
break;
}

@Kezii Kezii changed the title remove panic on uarte overrun [WIP] remove panic on uarte overrun Oct 9, 2025
@Kezii Kezii changed the title [WIP] remove panic on uarte overrun remove panic on uarte overrun Oct 10, 2025
@Kezii
Copy link
Contributor Author

Kezii commented Oct 10, 2025

Hello,
Thank you for your comment, I tested this patch, based on your suggestion, to work correctly. this is ready for review

@Kezii Kezii force-pushed the main branch 3 times, most recently from 8761bb4 to 8299b4e Compare October 10, 2025 01:45
@Kezii Kezii changed the title remove panic on uarte overrun remove panic on uarte overrun, return error on read instead Oct 10, 2025
@Kezii Kezii changed the title remove panic on uarte overrun, return error on read instead [embassy nrf] remove panic on uarte overrun, return error on read instead Oct 10, 2025
Comment on lines 770 to 771
if s.rx_overrun.load(Ordering::Relaxed) {
s.rx_overrun.store(false, Ordering::Relaxed);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can convert these load + store into a swap:

if s.rx_overrun.swap(false, ...) {
}

https://doc.rust-lang.org/std/sync/atomic/struct.AtomicU32.html#method.swap

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you, done


if errs.overrun() {
panic!("BufferedUarte overrun");
s.rx_overrun.store(true, Ordering::Relaxed);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be Ordering::Acquire since the write is in an interrupt and the read is not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apparently that breaks the build

error: atomic stores cannot have Acquire or AcqRel ordering
--> src/buffered_uarte.rs:93:46
|
93 | s.rx_overrun.store(true, Ordering::Acquire);
| ^^^^^^^^^^^^^^^^^
|
= help: consider using ordering modes Release, SeqCst or Relaxed
= note: #[deny(invalid_atomic_ordering)] on by default

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should I use Release for the store and AcqRel for the swap?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, my bad. This one should be Release.

compiler_fence(Ordering::SeqCst);
//trace!("poll_read");

if s.rx_overrun.swap(false, Ordering::Relaxed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be Ordering::AcqRel?

/// we are ready to read if there is data in the buffer
fn read_ready(&self) -> Result<bool, Error> {
let state = self.buffered_state;
if state.rx_overrun.swap(false, Ordering::Relaxed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also Ordering::AcqRel?

@Kezii Kezii force-pushed the main branch 2 times, most recently from 690eaaf to 7b47da5 Compare October 14, 2025 15:15
@Kezii
Copy link
Contributor Author

Kezii commented Oct 14, 2025

I used Release for the interrupt handler, and Acquire for the user code

In my understanding, there's no need for AcqRel since we are not polling on the false value ?

@lulf
Copy link
Member

lulf commented Oct 14, 2025

I used Release for the interrupt handler, and Acquire for the user code

In my understanding, there's no need for AcqRel since we are not polling on the false value ?

Hmm, yeah. You're right

@lulf lulf added this pull request to the merge queue Oct 14, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Oct 14, 2025
@lulf lulf added this pull request to the merge queue Oct 14, 2025
Merged via the queue into embassy-rs:main with commit 751ed8f Oct 14, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[embassy-nrf] Remove "BufferedUarte overrun" panic

3 participants