diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-04-05 23:53:59 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-04-05 23:53:59 +0000 |
| commit | c1b382296434e762d16a36d658d2f308358e3f87 (patch) | |
| tree | 6edd9fd7c2d69a5ad130dc13ae7c0bbed442e640 /examples | |
| parent | aee19185b7cf34466f7941784b55e639c925fae4 (diff) | |
| parent | 27a1b0ea7316be4687e7173a73861d276974d502 (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')
| -rw-r--r-- | examples/nrf/src/bin/channel.rs | 45 | ||||
| -rw-r--r-- | examples/nrf/src/bin/channel_sender_receiver.rs | 52 | ||||
| -rw-r--r-- | examples/nrf/src/bin/mpsc.rs | 60 | ||||
| -rw-r--r-- | examples/nrf/src/bin/uart_split.rs | 23 | ||||
| -rw-r--r-- | examples/stm32f3/src/bin/button_events.rs | 59 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/usart_split.rs | 26 |
6 files changed, 139 insertions, 126 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 | |||
| 5 | use defmt::unwrap; | ||
| 6 | use embassy::blocking_mutex::raw::ThreadModeRawMutex; | ||
| 7 | use embassy::channel::channel::Channel; | ||
| 8 | use embassy::executor::Spawner; | ||
| 9 | use embassy::time::{Duration, Timer}; | ||
| 10 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 11 | use embassy_nrf::Peripherals; | ||
| 12 | |||
| 13 | use defmt_rtt as _; // global logger | ||
| 14 | use panic_probe as _; | ||
| 15 | |||
| 16 | enum LedState { | ||
| 17 | On, | ||
| 18 | Off, | ||
| 19 | } | ||
| 20 | |||
| 21 | static CHANNEL: Channel<ThreadModeRawMutex, LedState, 1> = Channel::new(); | ||
| 22 | |||
| 23 | #[embassy::task] | ||
| 24 | async 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] | ||
| 34 | async 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 | |||
| 5 | use defmt::unwrap; | ||
| 6 | use embassy::blocking_mutex::raw::NoopRawMutex; | ||
| 7 | use embassy::channel::channel::{Channel, Receiver, Sender}; | ||
| 8 | use embassy::executor::Spawner; | ||
| 9 | use embassy::time::{Duration, Timer}; | ||
| 10 | use embassy::util::Forever; | ||
| 11 | use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; | ||
| 12 | use embassy_nrf::Peripherals; | ||
| 13 | |||
| 14 | use defmt_rtt as _; // global logger | ||
| 15 | use panic_probe as _; | ||
| 16 | |||
| 17 | enum LedState { | ||
| 18 | On, | ||
| 19 | Off, | ||
| 20 | } | ||
| 21 | |||
| 22 | static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new(); | ||
| 23 | |||
| 24 | #[embassy::task] | ||
| 25 | async 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] | ||
| 35 | async 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] | ||
| 47 | async 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 | |||
| 5 | use defmt::unwrap; | ||
| 6 | use embassy::blocking_mutex::raw::NoopRawMutex; | ||
| 7 | use embassy::channel::mpsc::{self, Channel, Sender, TryRecvError}; | ||
| 8 | use embassy::executor::Spawner; | ||
| 9 | use embassy::time::{Duration, Timer}; | ||
| 10 | use embassy::util::Forever; | ||
| 11 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 12 | use embassy_nrf::Peripherals; | ||
| 13 | |||
| 14 | use defmt_rtt as _; // global logger | ||
| 15 | use panic_probe as _; | ||
| 16 | |||
| 17 | enum LedState { | ||
| 18 | On, | ||
| 19 | Off, | ||
| 20 | } | ||
| 21 | |||
| 22 | static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new(); | ||
| 23 | |||
| 24 | #[embassy::task(pool_size = 1)] | ||
| 25 | async 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] | ||
| 35 | async 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 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy::blocking_mutex::raw::NoopRawMutex; | 6 | use embassy::blocking_mutex::raw::ThreadModeRawMutex; |
| 7 | use embassy::channel::mpsc::{self, Channel, Sender}; | 7 | use embassy::channel::channel::Channel; |
| 8 | use embassy::executor::Spawner; | 8 | use embassy::executor::Spawner; |
| 9 | use embassy::util::Forever; | ||
| 10 | use embassy_nrf::peripherals::UARTE0; | 9 | use embassy_nrf::peripherals::UARTE0; |
| 11 | use embassy_nrf::uarte::UarteRx; | 10 | use embassy_nrf::uarte::UarteRx; |
| 12 | use embassy_nrf::{interrupt, uarte, Peripherals}; | 11 | use embassy_nrf::{interrupt, uarte, Peripherals}; |
| @@ -14,7 +13,7 @@ use embassy_nrf::{interrupt, uarte, Peripherals}; | |||
| 14 | use defmt_rtt as _; // global logger | 13 | use defmt_rtt as _; // global logger |
| 15 | use panic_probe as _; | 14 | use panic_probe as _; |
| 16 | 15 | ||
| 17 | static CHANNEL: Forever<Channel<NoopRawMutex, [u8; 8], 1>> = Forever::new(); | 16 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); |
| 18 | 17 | ||
| 19 | #[embassy::main] | 18 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner, p: Peripherals) { | 19 | async 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] |
| 59 | async fn reader(mut rx: UarteRx<'static, UARTE0>, s: Sender<'static, NoopRawMutex, [u8; 8], 1>) { | 54 | async 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 | } |
diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index 99aab3027..06e8eec1f 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs | |||
| @@ -11,11 +11,10 @@ | |||
| 11 | #![feature(type_alias_impl_trait)] | 11 | #![feature(type_alias_impl_trait)] |
| 12 | 12 | ||
| 13 | use defmt::*; | 13 | use defmt::*; |
| 14 | use embassy::blocking_mutex::raw::NoopRawMutex; | 14 | use embassy::blocking_mutex::raw::ThreadModeRawMutex; |
| 15 | use embassy::channel::mpsc::{self, Channel, Receiver, Sender}; | 15 | use embassy::channel::channel::Channel; |
| 16 | use embassy::executor::Spawner; | 16 | use embassy::executor::Spawner; |
| 17 | use embassy::time::{with_timeout, Duration, Timer}; | 17 | use embassy::time::{with_timeout, Duration, Timer}; |
| 18 | use embassy::util::Forever; | ||
| 19 | use embassy_stm32::exti::ExtiInput; | 18 | use embassy_stm32::exti::ExtiInput; |
| 20 | use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; | 19 | use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; |
| 21 | use embassy_stm32::peripherals::PA0; | 20 | use embassy_stm32::peripherals::PA0; |
| @@ -51,14 +50,15 @@ impl<'a> Leds<'a> { | |||
| 51 | } | 50 | } |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | async fn show(&mut self, queue: &mut Receiver<'static, NoopRawMutex, ButtonEvent, 4>) { | 53 | async fn show(&mut self) { |
| 55 | self.leds[self.current_led].set_high(); | 54 | self.leds[self.current_led].set_high(); |
| 56 | if let Ok(new_message) = with_timeout(Duration::from_millis(500), queue.recv()).await { | 55 | if let Ok(new_message) = with_timeout(Duration::from_millis(500), CHANNEL.recv()).await { |
| 57 | self.leds[self.current_led].set_low(); | 56 | self.leds[self.current_led].set_low(); |
| 58 | self.process_event(new_message).await; | 57 | self.process_event(new_message).await; |
| 59 | } else { | 58 | } else { |
| 60 | self.leds[self.current_led].set_low(); | 59 | self.leds[self.current_led].set_low(); |
| 61 | if let Ok(new_message) = with_timeout(Duration::from_millis(200), queue.recv()).await { | 60 | if let Ok(new_message) = with_timeout(Duration::from_millis(200), CHANNEL.recv()).await |
| 61 | { | ||
| 62 | self.process_event(new_message).await; | 62 | self.process_event(new_message).await; |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| @@ -77,15 +77,18 @@ impl<'a> Leds<'a> { | |||
| 77 | } | 77 | } |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | async fn process_event(&mut self, event: Option<ButtonEvent>) { | 80 | async fn process_event(&mut self, event: ButtonEvent) { |
| 81 | match event { | 81 | match event { |
| 82 | Some(ButtonEvent::SingleClick) => self.move_next(), | 82 | ButtonEvent::SingleClick => { |
| 83 | Some(ButtonEvent::DoubleClick) => { | 83 | self.move_next(); |
| 84 | } | ||
| 85 | ButtonEvent::DoubleClick => { | ||
| 84 | self.change_direction(); | 86 | self.change_direction(); |
| 85 | self.move_next() | 87 | self.move_next(); |
| 88 | } | ||
| 89 | ButtonEvent::Hold => { | ||
| 90 | self.flash().await; | ||
| 86 | } | 91 | } |
| 87 | Some(ButtonEvent::Hold) => self.flash().await, | ||
| 88 | _ => {} | ||
| 89 | } | 92 | } |
| 90 | } | 93 | } |
| 91 | } | 94 | } |
| @@ -97,7 +100,7 @@ enum ButtonEvent { | |||
| 97 | Hold, | 100 | Hold, |
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | static BUTTON_EVENTS_QUEUE: Forever<Channel<NoopRawMutex, ButtonEvent, 4>> = Forever::new(); | 103 | static CHANNEL: Channel<ThreadModeRawMutex, ButtonEvent, 4> = Channel::new(); |
| 101 | 104 | ||
| 102 | #[embassy::main] | 105 | #[embassy::main] |
| 103 | async fn main(spawner: Spawner, p: Peripherals) { | 106 | async fn main(spawner: Spawner, p: Peripherals) { |
| @@ -116,27 +119,19 @@ async fn main(spawner: Spawner, p: Peripherals) { | |||
| 116 | ]; | 119 | ]; |
| 117 | let leds = Leds::new(leds); | 120 | let leds = Leds::new(leds); |
| 118 | 121 | ||
| 119 | let buttons_queue = BUTTON_EVENTS_QUEUE.put(Channel::new()); | 122 | spawner.spawn(button_waiter(button)).unwrap(); |
| 120 | let (sender, receiver) = mpsc::split(buttons_queue); | 123 | spawner.spawn(led_blinker(leds)).unwrap(); |
| 121 | spawner.spawn(button_waiter(button, sender)).unwrap(); | ||
| 122 | spawner.spawn(led_blinker(leds, receiver)).unwrap(); | ||
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | #[embassy::task] | 126 | #[embassy::task] |
| 126 | async fn led_blinker( | 127 | async fn led_blinker(mut leds: Leds<'static>) { |
| 127 | mut leds: Leds<'static>, | ||
| 128 | mut queue: Receiver<'static, NoopRawMutex, ButtonEvent, 4>, | ||
| 129 | ) { | ||
| 130 | loop { | 128 | loop { |
| 131 | leds.show(&mut queue).await; | 129 | leds.show().await; |
| 132 | } | 130 | } |
| 133 | } | 131 | } |
| 134 | 132 | ||
| 135 | #[embassy::task] | 133 | #[embassy::task] |
| 136 | async fn button_waiter( | 134 | async fn button_waiter(mut button: ExtiInput<'static, PA0>) { |
| 137 | mut button: ExtiInput<'static, PA0>, | ||
| 138 | queue: Sender<'static, NoopRawMutex, ButtonEvent, 4>, | ||
| 139 | ) { | ||
| 140 | const DOUBLE_CLICK_DELAY: u64 = 250; | 135 | const DOUBLE_CLICK_DELAY: u64 = 250; |
| 141 | const HOLD_DELAY: u64 = 1000; | 136 | const HOLD_DELAY: u64 = 1000; |
| 142 | 137 | ||
| @@ -150,9 +145,7 @@ async fn button_waiter( | |||
| 150 | .is_err() | 145 | .is_err() |
| 151 | { | 146 | { |
| 152 | info!("Hold"); | 147 | info!("Hold"); |
| 153 | if queue.send(ButtonEvent::Hold).await.is_err() { | 148 | CHANNEL.send(ButtonEvent::Hold).await; |
| 154 | break; | ||
| 155 | } | ||
| 156 | button.wait_for_falling_edge().await; | 149 | button.wait_for_falling_edge().await; |
| 157 | } else if with_timeout( | 150 | } else if with_timeout( |
| 158 | Duration::from_millis(DOUBLE_CLICK_DELAY), | 151 | Duration::from_millis(DOUBLE_CLICK_DELAY), |
| @@ -161,15 +154,11 @@ async fn button_waiter( | |||
| 161 | .await | 154 | .await |
| 162 | .is_err() | 155 | .is_err() |
| 163 | { | 156 | { |
| 164 | if queue.send(ButtonEvent::SingleClick).await.is_err() { | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | info!("Single click"); | 157 | info!("Single click"); |
| 158 | CHANNEL.send(ButtonEvent::SingleClick).await; | ||
| 168 | } else { | 159 | } else { |
| 169 | info!("Double click"); | 160 | info!("Double click"); |
| 170 | if queue.send(ButtonEvent::DoubleClick).await.is_err() { | 161 | CHANNEL.send(ButtonEvent::DoubleClick).await; |
| 171 | break; | ||
| 172 | } | ||
| 173 | button.wait_for_falling_edge().await; | 162 | button.wait_for_falling_edge().await; |
| 174 | } | 163 | } |
| 175 | button.wait_for_rising_edge().await; | 164 | button.wait_for_rising_edge().await; |
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs index ee1763aa4..40a7c3e44 100644 --- a/examples/stm32h7/src/bin/usart_split.rs +++ b/examples/stm32h7/src/bin/usart_split.rs | |||
| @@ -4,10 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use defmt_rtt as _; // global logger | 6 | use defmt_rtt as _; // global logger |
| 7 | use embassy::blocking_mutex::raw::NoopRawMutex; | 7 | use embassy::blocking_mutex::raw::ThreadModeRawMutex; |
| 8 | use embassy::channel::mpsc::{self, Channel, Sender}; | 8 | use embassy::channel::channel::Channel; |
| 9 | use embassy::executor::Spawner; | 9 | use embassy::executor::Spawner; |
| 10 | use embassy::util::Forever; | ||
| 11 | use embassy_stm32::dma::NoDma; | 10 | use embassy_stm32::dma::NoDma; |
| 12 | use embassy_stm32::{ | 11 | use embassy_stm32::{ |
| 13 | peripherals::{DMA1_CH1, UART7}, | 12 | peripherals::{DMA1_CH1, UART7}, |
| @@ -28,7 +27,7 @@ async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { | |||
| 28 | } | 27 | } |
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | static CHANNEL: Forever<Channel<NoopRawMutex, [u8; 8], 1>> = Forever::new(); | 30 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); |
| 32 | 31 | ||
| 33 | #[embassy::main] | 32 | #[embassy::main] |
| 34 | async fn main(spawner: Spawner, p: Peripherals) -> ! { | 33 | async fn main(spawner: Spawner, p: Peripherals) -> ! { |
| @@ -40,28 +39,21 @@ async fn main(spawner: Spawner, p: Peripherals) -> ! { | |||
| 40 | 39 | ||
| 41 | let (mut tx, rx) = usart.split(); | 40 | let (mut tx, rx) = usart.split(); |
| 42 | 41 | ||
| 43 | let c = CHANNEL.put(Channel::new()); | 42 | unwrap!(spawner.spawn(reader(rx))); |
| 44 | let (s, mut r) = mpsc::split(c); | ||
| 45 | |||
| 46 | unwrap!(spawner.spawn(reader(rx, s))); | ||
| 47 | 43 | ||
| 48 | loop { | 44 | loop { |
| 49 | if let Some(buf) = r.recv().await { | 45 | let buf = CHANNEL.recv().await; |
| 50 | info!("writing..."); | 46 | info!("writing..."); |
| 51 | unwrap!(tx.write(&buf).await); | 47 | unwrap!(tx.write(&buf).await); |
| 52 | } | ||
| 53 | } | 48 | } |
| 54 | } | 49 | } |
| 55 | 50 | ||
| 56 | #[embassy::task] | 51 | #[embassy::task] |
| 57 | async fn reader( | 52 | async fn reader(mut rx: UartRx<'static, UART7, DMA1_CH1>) { |
| 58 | mut rx: UartRx<'static, UART7, DMA1_CH1>, | ||
| 59 | s: Sender<'static, NoopRawMutex, [u8; 8], 1>, | ||
| 60 | ) { | ||
| 61 | let mut buf = [0; 8]; | 53 | let mut buf = [0; 8]; |
| 62 | loop { | 54 | loop { |
| 63 | info!("reading..."); | 55 | info!("reading..."); |
| 64 | unwrap!(rx.read(&mut buf).await); | 56 | unwrap!(rx.read(&mut buf).await); |
| 65 | unwrap!(s.send(buf).await); | 57 | CHANNEL.send(buf).await; |
| 66 | } | 58 | } |
| 67 | } | 59 | } |
