Merge pull request #3160 from 1-rafael-1/add-rp-sample-distribute-resources

add assign_resources rp example
This commit is contained in:
James Munns 2024-07-08 21:29:25 +00:00 committed by GitHub
commit 6636a5835b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 86 additions and 0 deletions

View File

@ -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]

View File

@ -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"

View 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;
}
}