Clarify whether non-blocking or stateless is the more important aspect of nb
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Documentation
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- rust
- Domain
- embedded-iot
Research direction
Start by reading the linked comment on pull request #12 and compare the two embedded_hal::serial::Write implementations shown for the nRF51. Determine whether nb::Result prioritizes non-blocking behavior or avoiding program-held state, then document the agreed semantics and examples once the design question is resolved.
Written by the indexing model from the issue text.
Description
In reference to @japaric's comment here.
In my mind operations that return nb::Result signal that they can't be started and completed right
now via WouldBlock but once you get an Ok you know that the operation started and completed in one step, without blocking. This also means that operations that return nb::Result carry no program
state -- there may be some state in the hardware registers or in the kernel but it's not on the
program stack / heap.
Unfortunately this is not always possible, as an example consider the embedded_hal::serial::Write implementation from the nrf51_hal crate:
pub struct Tx<UART> {
_uart: PhantomData<UART>,
}
impl hal::serial::Write<u8> for Tx<UART0> {
type Error = !;
fn flush(&mut self) -> nb::Result<(), !> {
Ok(())
}
fn write(&mut self, byte: u8) -> nb::Result<(), !> {
/* Write one 8bit value */
unsafe { (*UART0::ptr()).txd.write(|w| w.bits(u32::from(byte))) }
/* Wait until written ... */
while unsafe { (*UART0::ptr()).events_txdrdy.read().bits() } == 0 {}
/* ... and clear read bit, there's no other way this will work */
unsafe { (*UART0::ptr()).events_txdrdy.write(|w| w.bits(0)) };
Ok(())
}
}
This is currently a blocking implementation. To convert it to a non-blocking implementation we need to introduce some state of whether we're currently transmitting a byte (as far as I can tell, there is no way to derive this from the microcontroller registers):
pub struct Tx<UART> {
_uart: PhantomData<UART>,
busy: bool,
}
impl hal::serial::Write<u8> for Tx<UART0> {
type Error = !;
fn flush(&mut self) -> nb::Result<(), !> {
let uart = unsafe { &*UART0::ptr() };
if self.busy {
if uart.events_txdrdy.read().bits() == 1 {
uart.events_txdrdy.reset();
self.busy = false;
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
} else {
Ok(())
}
}
fn write(&mut self, byte: u8) -> nb::Result<(), !> {
let uart = unsafe { &*UART0::ptr() };
self.flush()?;
uart.txd.write(|w| unsafe { w.bits(u32::from(byte)) });
self.busy = true;
Ok(())
}
}
In my mind the whole purpose of nb is to support implementing non-blocking IO primitives suitable for integrating into something like a futures event loop (although, I'm still trying to work out how to support interrupt-driven task notifications without having to have event loop specific implementations anyway...). If implementations are going to be forced to block to not have a tiny bit of important state, that undermines the entire utility of this crate.
Once this is clarified I will try and open a PR documenting this along with other stuff mentioned in that comment.
cc @therealprof (in case you have some other ideas about non-blocking uart support on the nrf51)
- Dominant language
- Rust
- Stars
- 109
- Forks
- 18
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rust-embedded/nb
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
rust-embedded/nb#37 · 2 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 25/100
rust-embedded/nb#17 · 1 comment ·
-
discussion
Difficulty 5/5 Over a week Newbie friendliness 25/100
rust-embedded/nb#16 · 2 comments · 1 reaction ·
-
discussion
Difficulty 5/5 Over a week Newbie friendliness 25/100
rust-embedded/nb#15 · 1 comment · 1 reaction ·
-
discussion
Difficulty 5/5 Over a week Newbie friendliness 20/100
rust-embedded/nb#14 · 8 comments · 4 reactions ·
All issues in rust-embedded/nb
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100