mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
Merge pull request #3160 from 1-rafael-1/add-rp-sample-distribute-resources
add assign_resources rp example
This commit is contained in:
commit
6636a5835b
@ -358,3 +358,7 @@ An example showcasing some methods for sharing things between tasks link:https:/
|
||||
But when it comes to "waking" tasks, for example when a data transfer is complete or a button is pressed, it's faster to wake a dedicated task, because that task does not need to check which future is actually ready. `join` and `select` must check ALL of the futures they are managing to see which one (or which ones) are ready to do more work. This is because all Rust executors (like Embassy or Tokio) only have the ability to wake tasks, not specific futures. This means you will use slightly less CPU time juggling futures when using dedicated tasks.
|
||||
|
||||
Practically, there's not a LOT of difference either way - so go with what makes it easier for you and your code first, but there will be some details that are slightly different in each case.
|
||||
|
||||
== splitting peripherals resources between tasks
|
||||
|
||||
There are two ways to split resources between tasks, either manually assigned or by a convenient macro. See link:https://github.com/embassy-rs/embassy/blob/main/examples/rp/src/bin/assign_resources.rs[this example]
|
@ -29,6 +29,9 @@ reqwless = { version = "0.12.0", features = ["defmt",]}
|
||||
serde = { version = "1.0.203", default-features = false, features = ["derive"] }
|
||||
serde-json-core = "0.5.1"
|
||||
|
||||
# for assign resources example
|
||||
assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "94ad10e2729afdf0fd5a77cd12e68409a982f58a" }
|
||||
|
||||
#cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
|
||||
cortex-m = { version = "0.7.6", features = ["inline-asm"] }
|
||||
cortex-m-rt = "0.7.0"
|
||||
|
79
examples/rp/src/bin/assign_resources.rs
Normal file
79
examples/rp/src/bin/assign_resources.rs
Normal file
@ -0,0 +1,79 @@
|
||||
//! This example demonstrates how to assign resources to multiple tasks by splitting up the peripherals.
|
||||
//! It is not about sharing the same resources between tasks, see sharing.rs for that or head to https://embassy.dev/book/#_sharing_peripherals_between_tasks)
|
||||
//! Of course splitting up resources and sharing resources can be combined, yet this example is only about splitting up resources.
|
||||
//!
|
||||
//! There are basically two ways we demonstrate here:
|
||||
//! 1) Assigning resources to a task by passing parts of the peripherals
|
||||
//! 2) Assigning resources to a task by passing a struct with the split up peripherals, using the assign-resources macro
|
||||
//!
|
||||
//! using four LEDs on Pins 10, 11, 20 and 21
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use assign_resources::assign_resources;
|
||||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_rp::gpio::{Level, Output};
|
||||
use embassy_rp::peripherals::{self, PIN_20, PIN_21};
|
||||
use embassy_time::Timer;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
// initialize the peripherals
|
||||
let p = embassy_rp::init(Default::default());
|
||||
|
||||
// 1) Assigning a resource to a task by passing parts of the peripherals.
|
||||
spawner
|
||||
.spawn(double_blinky_manually_assigned(spawner, p.PIN_20, p.PIN_21))
|
||||
.unwrap();
|
||||
|
||||
// 2) Using the assign-resources macro to assign resources to a task.
|
||||
// we perform the split, see further below for the definition of the resources struct
|
||||
let r = split_resources!(p);
|
||||
// and then we can use them
|
||||
spawner.spawn(double_blinky_macro_assigned(spawner, r.leds)).unwrap();
|
||||
}
|
||||
|
||||
// 1) Assigning a resource to a task by passing parts of the peripherals.
|
||||
#[embassy_executor::task]
|
||||
async fn double_blinky_manually_assigned(_spawner: Spawner, pin_20: PIN_20, pin_21: PIN_21) {
|
||||
let mut led_20 = Output::new(pin_20, Level::Low);
|
||||
let mut led_21 = Output::new(pin_21, Level::High);
|
||||
|
||||
loop {
|
||||
info!("toggling leds");
|
||||
led_20.toggle();
|
||||
led_21.toggle();
|
||||
Timer::after_secs(1).await;
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Using the assign-resources macro to assign resources to a task.
|
||||
// first we define the resources we want to assign to the task using the assign_resources! macro
|
||||
// basically this will split up the peripherals struct into smaller structs, that we define here
|
||||
// naming is up to you, make sure your future self understands what you did here
|
||||
assign_resources! {
|
||||
leds: Leds{
|
||||
led_10: PIN_10,
|
||||
led_11: PIN_11,
|
||||
}
|
||||
// add more resources to more structs if needed, for example defining one struct for each task
|
||||
}
|
||||
// this could be done in another file and imported here, but for the sake of simplicity we do it here
|
||||
// see https://github.com/adamgreig/assign-resources for more information
|
||||
|
||||
// 2) Using the split resources in a task
|
||||
#[embassy_executor::task]
|
||||
async fn double_blinky_macro_assigned(_spawner: Spawner, r: Leds) {
|
||||
let mut led_10 = Output::new(r.led_10, Level::Low);
|
||||
let mut led_11 = Output::new(r.led_11, Level::High);
|
||||
|
||||
loop {
|
||||
info!("toggling leds");
|
||||
led_10.toggle();
|
||||
led_11.toggle();
|
||||
Timer::after_secs(1).await;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user