diff --git a/book/en/src/by-example/channel.md b/book/en/src/by-example/channel.md index c020870aac..50c3278ea4 100644 --- a/book/en/src/by-example/channel.md +++ b/book/en/src/by-example/channel.md @@ -1,6 +1,6 @@ # Communication over channels. -Channels can be used to communicate data between running *software* tasks. The channel is essentially a wait queue, allowing tasks with multiple producers and a single receiver. A channel is constructed in the `init` task and backed by statically allocated memory. Send and receive endpoints are distributed to *software* tasks: +Channels can be used to communicate data between running tasks. The channel is essentially a wait queue, allowing tasks with multiple producers and a single receiver. A channel is constructed in the `init` task and backed by statically allocated memory. Send and receive endpoints are distributed to *software* tasks: ``` rust ... @@ -16,6 +16,8 @@ const CAPACITY: usize = 5; In this case the channel holds data of `u32` type with a capacity of 5 elements. +Channels can also be used from *hardware* tasks, but only in a non-`async` manner using the [Try API](#try-api). + ## Sending data The `send` method post a message on the channel as shown below: @@ -107,11 +109,11 @@ $ cargo run --target thumbv7m-none-eabi --example async-channel-no-receiver --fe {{#include ../../../../rtic/ci/expected/async-channel-no-receiver.run}} ``` - - ## Try API -In cases you wish the sender to proceed even in case the channel is full. To that end, a `try_send` API is provided. +Using the Try API, you can send or receive data from or to a channel without requiring that the operation succeeds, and in non-`async` contexts. + +This API is exposed through `Receiver::try_recv` and `Sender::try_send`. ``` rust {{#include ../../../../rtic/examples/async-channel-try.rs}} diff --git a/rtic/examples/async-channel-try.rs b/rtic/examples/async-channel-try.rs index 54a51d9e84..2e2af52e5d 100644 --- a/rtic/examples/async-channel-try.rs +++ b/rtic/examples/async-channel-try.rs @@ -18,7 +18,9 @@ mod app { struct Shared {} #[local] - struct Local {} + struct Local { + sender: Sender<'static, u32, CAPACITY>, + } const CAPACITY: usize = 1; #[init] @@ -28,7 +30,7 @@ mod app { receiver::spawn(r).unwrap(); sender1::spawn(s.clone()).unwrap(); - (Shared {}, Local {}) + (Shared {}, Local { sender: s.clone() }) } #[task] @@ -45,4 +47,11 @@ mod app { hprintln!("Sender 1 try sending: 2 {:?}", sender.try_send(2)); debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator } + + // This interrupt is never triggered, but is used to demonstrate that + // one can (try to) send data into a channel from a hardware task. + #[task(binds = GPIOA, local = [sender])] + fn hw_task(cx: hw_task::Context) { + cx.local.sender.try_send(3).ok(); + } }