aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordatdenkikniet <jcdra1@gmail.com>2023-04-22 19:54:42 +0200
committerdatdenkikniet <jcdra1@gmail.com>2023-05-11 19:20:58 +0200
commited465b0c3b8b4c588f5cc7945af79a504f928cc8 (patch)
treeab1611238b3aa65436f07d07a275f09719e895b3
parentd22faec870b57274b1b2a74c1fe947e969c13379 (diff)
Fix #699
-rw-r--r--book/en/src/by-example/channel.md10
-rw-r--r--rtic/examples/async-channel-try.rs13
2 files changed, 17 insertions, 6 deletions
diff --git a/book/en/src/by-example/channel.md b/book/en/src/by-example/channel.md
index c020870..50c3278 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 54a51d9..2e2af52 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();
+ }
}