aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-04-05 23:53:59 +0000
committerGitHub <[email protected]>2022-04-05 23:53:59 +0000
commitc1b382296434e762d16a36d658d2f308358e3f87 (patch)
tree6edd9fd7c2d69a5ad130dc13ae7c0bbed442e640 /examples/nrf/src
parentaee19185b7cf34466f7941784b55e639c925fae4 (diff)
parent27a1b0ea7316be4687e7173a73861d276974d502 (diff)
Merge #695
695: Simplify Channel. r=Dirbaio a=Dirbaio - Allow initializing in a static, without Forever. - Remove ability to close, since in embedded enviromnents channels usually live forever and don't get closed. - Remove MPSC restriction, it's MPMC now. Rename "mpsc" to "channel". - `Sender` and `Receiver` are still available if you want to enforce a piece of code only has send/receive access, but are optional: you can send/receive directly into the Channel if you want. Co-authored-by: Dario Nieuwenhuis <[email protected]>
Diffstat (limited to 'examples/nrf/src')
-rw-r--r--examples/nrf/src/bin/channel.rs45
-rw-r--r--examples/nrf/src/bin/channel_sender_receiver.rs52
-rw-r--r--examples/nrf/src/bin/mpsc.rs60
-rw-r--r--examples/nrf/src/bin/uart_split.rs23
4 files changed, 106 insertions, 74 deletions
diff --git a/examples/nrf/src/bin/channel.rs b/examples/nrf/src/bin/channel.rs
new file mode 100644
index 000000000..476ec09a1
--- /dev/null
+++ b/examples/nrf/src/bin/channel.rs
@@ -0,0 +1,45 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::unwrap;
6use embassy::blocking_mutex::raw::ThreadModeRawMutex;
7use embassy::channel::channel::Channel;
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy_nrf::gpio::{Level, Output, OutputDrive};
11use embassy_nrf::Peripherals;
12
13use defmt_rtt as _; // global logger
14use panic_probe as _;
15
16enum LedState {
17 On,
18 Off,
19}
20
21static CHANNEL: Channel<ThreadModeRawMutex, LedState, 1> = Channel::new();
22
23#[embassy::task]
24async fn my_task() {
25 loop {
26 CHANNEL.send(LedState::On).await;
27 Timer::after(Duration::from_secs(1)).await;
28 CHANNEL.send(LedState::Off).await;
29 Timer::after(Duration::from_secs(1)).await;
30 }
31}
32
33#[embassy::main]
34async fn main(spawner: Spawner, p: Peripherals) {
35 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
36
37 unwrap!(spawner.spawn(my_task()));
38
39 loop {
40 match CHANNEL.recv().await {
41 LedState::On => led.set_high(),
42 LedState::Off => led.set_low(),
43 }
44 }
45}
diff --git a/examples/nrf/src/bin/channel_sender_receiver.rs b/examples/nrf/src/bin/channel_sender_receiver.rs
new file mode 100644
index 000000000..c79f2fd6b
--- /dev/null
+++ b/examples/nrf/src/bin/channel_sender_receiver.rs
@@ -0,0 +1,52 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::unwrap;
6use embassy::blocking_mutex::raw::NoopRawMutex;
7use embassy::channel::channel::{Channel, Receiver, Sender};
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy::util::Forever;
11use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin};
12use embassy_nrf::Peripherals;
13
14use defmt_rtt as _; // global logger
15use panic_probe as _;
16
17enum LedState {
18 On,
19 Off,
20}
21
22static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new();
23
24#[embassy::task]
25async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) {
26 loop {
27 sender.send(LedState::On).await;
28 Timer::after(Duration::from_secs(1)).await;
29 sender.send(LedState::Off).await;
30 Timer::after(Duration::from_secs(1)).await;
31 }
32}
33
34#[embassy::task]
35async fn recv_task(led: AnyPin, receiver: Receiver<'static, NoopRawMutex, LedState, 1>) {
36 let mut led = Output::new(led, Level::Low, OutputDrive::Standard);
37
38 loop {
39 match receiver.recv().await {
40 LedState::On => led.set_high(),
41 LedState::Off => led.set_low(),
42 }
43 }
44}
45
46#[embassy::main]
47async fn main(spawner: Spawner, p: Peripherals) {
48 let channel = CHANNEL.put(Channel::new());
49
50 unwrap!(spawner.spawn(send_task(channel.sender())));
51 unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver())));
52}
diff --git a/examples/nrf/src/bin/mpsc.rs b/examples/nrf/src/bin/mpsc.rs
deleted file mode 100644
index 0cb182755..000000000
--- a/examples/nrf/src/bin/mpsc.rs
+++ /dev/null
@@ -1,60 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::unwrap;
6use embassy::blocking_mutex::raw::NoopRawMutex;
7use embassy::channel::mpsc::{self, Channel, Sender, TryRecvError};
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy::util::Forever;
11use embassy_nrf::gpio::{Level, Output, OutputDrive};
12use embassy_nrf::Peripherals;
13
14use defmt_rtt as _; // global logger
15use panic_probe as _;
16
17enum LedState {
18 On,
19 Off,
20}
21
22static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new();
23
24#[embassy::task(pool_size = 1)]
25async fn my_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) {
26 loop {
27 let _ = sender.send(LedState::On).await;
28 Timer::after(Duration::from_secs(1)).await;
29 let _ = sender.send(LedState::Off).await;
30 Timer::after(Duration::from_secs(1)).await;
31 }
32}
33
34#[embassy::main]
35async fn main(spawner: Spawner, p: Peripherals) {
36 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
37
38 let channel = CHANNEL.put(Channel::new());
39 let (sender, mut receiver) = mpsc::split(channel);
40
41 unwrap!(spawner.spawn(my_task(sender)));
42
43 // We could just loop on `receiver.recv()` for simplicity. The code below
44 // is optimized to drain the queue as fast as possible in the spirit of
45 // handling events as fast as possible. This optimization is benign when in
46 // thread mode, but can be useful when interrupts are sending messages
47 // with the channel having been created via with_critical_sections.
48 loop {
49 let maybe_message = match receiver.try_recv() {
50 m @ Ok(..) => m.ok(),
51 Err(TryRecvError::Empty) => receiver.recv().await,
52 Err(TryRecvError::Closed) => break,
53 };
54 match maybe_message {
55 Some(LedState::On) => led.set_high(),
56 Some(LedState::Off) => led.set_low(),
57 _ => (),
58 }
59 }
60}
diff --git a/examples/nrf/src/bin/uart_split.rs b/examples/nrf/src/bin/uart_split.rs
index 909429b1a..3fde2f0d8 100644
--- a/examples/nrf/src/bin/uart_split.rs
+++ b/examples/nrf/src/bin/uart_split.rs
@@ -3,10 +3,9 @@
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use defmt::*; 5use defmt::*;
6use embassy::blocking_mutex::raw::NoopRawMutex; 6use embassy::blocking_mutex::raw::ThreadModeRawMutex;
7use embassy::channel::mpsc::{self, Channel, Sender}; 7use embassy::channel::channel::Channel;
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::util::Forever;
10use embassy_nrf::peripherals::UARTE0; 9use embassy_nrf::peripherals::UARTE0;
11use embassy_nrf::uarte::UarteRx; 10use embassy_nrf::uarte::UarteRx;
12use embassy_nrf::{interrupt, uarte, Peripherals}; 11use embassy_nrf::{interrupt, uarte, Peripherals};
@@ -14,7 +13,7 @@ use embassy_nrf::{interrupt, uarte, Peripherals};
14use defmt_rtt as _; // global logger 13use defmt_rtt as _; // global logger
15use panic_probe as _; 14use panic_probe as _;
16 15
17static CHANNEL: Forever<Channel<NoopRawMutex, [u8; 8], 1>> = Forever::new(); 16static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
18 17
19#[embassy::main] 18#[embassy::main]
20async fn main(spawner: Spawner, p: Peripherals) { 19async fn main(spawner: Spawner, p: Peripherals) {
@@ -26,14 +25,11 @@ async fn main(spawner: Spawner, p: Peripherals) {
26 let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config); 25 let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
27 let (mut tx, rx) = uart.split(); 26 let (mut tx, rx) = uart.split();
28 27
29 let c = CHANNEL.put(Channel::new());
30 let (s, mut r) = mpsc::split(c);
31
32 info!("uarte initialized!"); 28 info!("uarte initialized!");
33 29
34 // Spawn a task responsible purely for reading 30 // Spawn a task responsible purely for reading
35 31
36 unwrap!(spawner.spawn(reader(rx, s))); 32 unwrap!(spawner.spawn(reader(rx)));
37 33
38 // Message must be in SRAM 34 // Message must be in SRAM
39 { 35 {
@@ -48,19 +44,18 @@ async fn main(spawner: Spawner, p: Peripherals) {
48 // back out the buffer we receive from the read 44 // back out the buffer we receive from the read
49 // task. 45 // task.
50 loop { 46 loop {
51 if let Some(buf) = r.recv().await { 47 let buf = CHANNEL.recv().await;
52 info!("writing..."); 48 info!("writing...");
53 unwrap!(tx.write(&buf).await); 49 unwrap!(tx.write(&buf).await);
54 }
55 } 50 }
56} 51}
57 52
58#[embassy::task] 53#[embassy::task]
59async fn reader(mut rx: UarteRx<'static, UARTE0>, s: Sender<'static, NoopRawMutex, [u8; 8], 1>) { 54async fn reader(mut rx: UarteRx<'static, UARTE0>) {
60 let mut buf = [0; 8]; 55 let mut buf = [0; 8];
61 loop { 56 loop {
62 info!("reading..."); 57 info!("reading...");
63 unwrap!(rx.read(&mut buf).await); 58 unwrap!(rx.read(&mut buf).await);
64 unwrap!(s.send(buf).await); 59 CHANNEL.send(buf).await;
65 } 60 }
66} 61}