aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorhuntc <[email protected]>2021-06-06 18:36:16 +1000
committerhuntc <[email protected]>2021-07-15 12:31:52 +1000
commit1b9d5e50710cefde4bd1e234695783d62e824c68 (patch)
tree616e232e76ee7d5500390a102cbd656dcf08197c /examples
parent8a172ac12325ddc382e5ac0ffa637120a166d057 (diff)
Multi Producer Single Consumer channel
An MPSC inspired by Tokio and Crossbeam. The MPSC is designed to support both single and multi core processors, with only single core implemented at this time. The allocation of the channel’s buffer is inspired by the const generic parameters that Heapless provides.
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf/src/bin/mpsc.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/examples/nrf/src/bin/mpsc.rs b/examples/nrf/src/bin/mpsc.rs
new file mode 100644
index 000000000..6a0f8f471
--- /dev/null
+++ b/examples/nrf/src/bin/mpsc.rs
@@ -0,0 +1,64 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use defmt::panic;
12use embassy::executor::Spawner;
13use embassy::time::{Duration, Timer};
14use embassy::util::mpsc::TryRecvError;
15use embassy::util::{mpsc, Forever};
16use embassy_nrf::gpio::{Level, Output, OutputDrive};
17use embassy_nrf::Peripherals;
18use embedded_hal::digital::v2::OutputPin;
19use mpsc::{Channel, Sender, WithThreadModeOnly};
20
21enum LedState {
22 On,
23 Off,
24}
25
26static CHANNEL: Forever<Channel<WithThreadModeOnly, LedState, 1>> = Forever::new();
27
28#[embassy::task(pool_size = 1)]
29async fn my_task(sender: Sender<'static, WithThreadModeOnly, LedState, 1>) {
30 loop {
31 let _ = sender.send(LedState::On).await;
32 Timer::after(Duration::from_secs(1)).await;
33 let _ = sender.send(LedState::Off).await;
34 Timer::after(Duration::from_secs(1)).await;
35 }
36}
37
38#[embassy::main]
39async fn main(spawner: Spawner, p: Peripherals) {
40 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
41
42 let channel = CHANNEL.put(Channel::with_thread_mode_only());
43 let (sender, mut receiver) = mpsc::split(channel);
44
45 spawner.spawn(my_task(sender)).unwrap();
46
47 // We could just loop on `receiver.recv()` for simplicity. The code below
48 // is optimized to drain the queue as fast as possible in the spirit of
49 // handling events as fast as possible. This optimization is benign when in
50 // thread mode, but can be useful when interrupts are sending messages
51 // with the channel having been created via with_critical_sections.
52 loop {
53 let maybe_message = match receiver.try_recv() {
54 m @ Ok(..) => m.ok(),
55 Err(TryRecvError::Empty) => receiver.recv().await,
56 Err(TryRecvError::Closed) => break,
57 };
58 match maybe_message {
59 Some(LedState::On) => led.set_high().unwrap(),
60 Some(LedState::Off) => led.set_low().unwrap(),
61 _ => (),
62 }
63 }
64}