executor: return error when creating the spawntoken, not when spawning.

This commit is contained in:
Dario Nieuwenhuis 2025-07-09 01:49:31 +02:00 committed by diondokter
parent 34ff67cdbf
commit 8aec341f28
164 changed files with 337 additions and 389 deletions

View File

@ -80,7 +80,7 @@ async fn main(spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
// Spawned tasks run in the background, concurrently.
spawner.spawn(blink(p.P0_13.into())).unwrap();
spawner.spawn(blink(p.P0_13.into()).unwrap());
let mut button = Input::new(p.P0_11, Pull::Up);
loop {

View File

@ -22,5 +22,5 @@ async fn main(spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
let led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
unwrap!(spawner.spawn(blinker(led, Duration::from_millis(300))));
spawner.spawn(unwrap!(blinker(led, Duration::from_millis(300))));
}

View File

@ -36,8 +36,8 @@ async fn main(spawner: Spawner) {
let dt = 100 * 1_000_000;
let k = 1.003;
unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos(dt))));
unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos(dt))));
spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
}
// A pool size of 2 means you can spawn two instances of this task.
@ -103,8 +103,8 @@ async fn main(spawner: Spawner) {
let dt = 100 * 1_000_000;
let k = 1.003;
unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos((dt as f64 * k) as u64))));
spawner.spawn(unwrap!(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
spawner.spawn(unwrap!(toggle_led(CHANNEL.sender(), Duration::from_nanos((dt as f64 * k) as u64))));
loop {
match CHANNEL.receive().await {

View File

@ -181,7 +181,7 @@ For example: `#[embassy_executor::main(entry = ..., executor = \"some_crate::Exe
let mut executor = #executor::new();
let executor = unsafe { __make_static(&mut executor) };
executor.run(|spawner| {
spawner.must_spawn(__embassy_main(spawner));
spawner.spawn(__embassy_main(spawner).unwrap());
})
},
),
@ -191,7 +191,7 @@ For example: `#[embassy_executor::main(entry = ..., executor = \"some_crate::Exe
let executor = ::std::boxed::Box::leak(::std::boxed::Box::new(#executor::new()));
executor.start(|spawner| {
spawner.must_spawn(__embassy_main(spawner));
spawner.spawn(__embassy_main(spawner).unwrap());
});
Ok(())

View File

@ -234,7 +234,7 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
if !errors.is_empty() {
task_outer_body = quote! {
#![allow(unused_variables, unreachable_code)]
let _x: #embassy_executor::SpawnToken<()> = ::core::todo!();
let _x: ::core::result::Result<#embassy_executor::SpawnToken<()>, #embassy_executor::SpawnError> = ::core::todo!();
_x
};
}
@ -248,7 +248,7 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
#task_inner
#(#task_outer_attrs)*
#visibility #unsafety fn #task_ident #generics (#fargs) -> #embassy_executor::SpawnToken<impl Sized> #where_clause{
#visibility #unsafety fn #task_ident #generics (#fargs) -> ::core::result::Result<#embassy_executor::SpawnToken<impl Sized>, #embassy_executor::SpawnError> #where_clause{
#task_outer_body
}

View File

@ -41,7 +41,7 @@ use self::state::State;
use self::util::{SyncUnsafeCell, UninitCell};
pub use self::waker::task_from_waker;
use super::SpawnToken;
use crate::Metadata;
use crate::{Metadata, SpawnError};
#[no_mangle]
extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static mut TimerQueueItem {
@ -220,11 +220,11 @@ impl<F: Future + 'static> TaskStorage<F> {
///
/// Once the task has finished running, you may spawn it again. It is allowed to spawn it
/// on a different executor.
pub fn spawn(&'static self, future: impl FnOnce() -> F) -> SpawnToken<impl Sized> {
pub fn spawn(&'static self, future: impl FnOnce() -> F) -> Result<SpawnToken<impl Sized>, SpawnError> {
let task = AvailableTask::claim(self);
match task {
Some(task) => task.initialize(future),
None => SpawnToken::new_failed(),
Some(task) => Ok(task.initialize(future)),
None => Err(SpawnError::Busy),
}
}
@ -353,10 +353,10 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
}
}
fn spawn_impl<T>(&'static self, future: impl FnOnce() -> F) -> SpawnToken<T> {
fn spawn_impl<T>(&'static self, future: impl FnOnce() -> F) -> Result<SpawnToken<T>, SpawnError> {
match self.pool.iter().find_map(AvailableTask::claim) {
Some(task) => task.initialize_impl::<T>(future),
None => SpawnToken::new_failed(),
Some(task) => Ok(task.initialize_impl::<T>(future)),
None => Err(SpawnError::Busy),
}
}
@ -367,7 +367,7 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
/// This will loop over the pool and spawn the task in the first storage that
/// is currently free. If none is free, a "poisoned" SpawnToken is returned,
/// which will cause [`Spawner::spawn()`](super::Spawner::spawn) to return the error.
pub fn spawn(&'static self, future: impl FnOnce() -> F) -> SpawnToken<impl Sized> {
pub fn spawn(&'static self, future: impl FnOnce() -> F) -> Result<SpawnToken<impl Sized>, SpawnError> {
self.spawn_impl::<F>(future)
}
@ -380,7 +380,7 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
/// SAFETY: `future` must be a closure of the form `move || my_async_fn(args)`, where `my_async_fn`
/// is an `async fn`, NOT a hand-written `Future`.
#[doc(hidden)]
pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> SpawnToken<impl Sized>
pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> Result<SpawnToken<impl Sized>, SpawnError>
where
FutFn: FnOnce() -> F,
{

View File

@ -23,39 +23,28 @@ use crate::Metadata;
/// Once you've invoked a task function and obtained a SpawnToken, you *must* spawn it.
#[must_use = "Calling a task function does nothing on its own. You must spawn the returned SpawnToken, typically with Spawner::spawn()"]
pub struct SpawnToken<S> {
pub(crate) raw_task: Option<raw::TaskRef>,
pub(crate) raw_task: raw::TaskRef,
phantom: PhantomData<*mut S>,
}
impl<S> SpawnToken<S> {
pub(crate) unsafe fn new(raw_task: raw::TaskRef) -> Self {
Self {
raw_task: Some(raw_task),
raw_task,
phantom: PhantomData,
}
}
/// Return a SpawnToken that represents a failed spawn.
pub fn new_failed() -> Self {
Self {
raw_task: None,
phantom: PhantomData,
}
}
/// Returns the task ID if available, otherwise 0
/// Returns the task ID.
/// This can be used in combination with rtos-trace to match task names with IDs
pub fn id(&self) -> u32 {
match self.raw_task {
None => 0,
Some(t) => t.id(),
}
self.raw_task.id()
}
/// Get the metadata for this task. You can use this to set metadata fields
/// prior to spawning it.
pub fn metadata(&self) -> &Metadata {
self.raw_task.unwrap().metadata()
self.raw_task.metadata()
}
}
@ -164,30 +153,10 @@ impl Spawner {
/// Spawn a task into an executor.
///
/// You obtain the `token` by calling a task function (i.e. one marked with `#[embassy_executor::task]`).
pub fn spawn<S>(&self, token: SpawnToken<S>) -> Result<(), SpawnError> {
pub fn spawn<S>(&self, token: SpawnToken<S>) {
let task = token.raw_task;
mem::forget(token);
match task {
Some(task) => {
unsafe { self.executor.spawn(task) };
Ok(())
}
None => Err(SpawnError::Busy),
}
}
// Used by the `embassy_executor_macros::main!` macro to throw an error when spawn
// fails. This is here to allow conditional use of `defmt::unwrap!`
// without introducing a `defmt` feature in the `embassy_executor_macros` package,
// which would require use of `-Z namespaced-features`.
/// Spawn a task into an executor, panicking on failure.
///
/// # Panics
///
/// Panics if the spawning fails.
pub fn must_spawn<S>(&self, token: SpawnToken<S>) {
unwrap!(self.spawn(token));
unsafe { self.executor.spawn(task) }
}
/// Convert this Spawner to a SendSpawner. This allows you to send the
@ -245,25 +214,9 @@ impl SendSpawner {
/// Spawn a task into an executor.
///
/// You obtain the `token` by calling a task function (i.e. one marked with `#[embassy_executor::task]`).
pub fn spawn<S: Send>(&self, token: SpawnToken<S>) -> Result<(), SpawnError> {
pub fn spawn<S: Send>(&self, token: SpawnToken<S>) {
let header = token.raw_task;
mem::forget(token);
match header {
Some(header) => {
unsafe { self.executor.spawn(header) };
Ok(())
}
None => Err(SpawnError::Busy),
}
}
/// Spawn a task into an executor, panicking on failure.
///
/// # Panics
///
/// Panics if the spawning fails.
pub fn must_spawn<S: Send>(&self, token: SpawnToken<S>) {
unwrap!(self.spawn(token));
unsafe { self.executor.spawn(header) }
}
}

View File

@ -65,7 +65,7 @@ fn executor_task() {
}
let (executor, trace) = setup();
executor.spawner().spawn(task1(trace.clone())).unwrap();
executor.spawner().spawn(task1(trace.clone()).unwrap());
unsafe { executor.poll() };
unsafe { executor.poll() };
@ -93,7 +93,7 @@ fn executor_task_rpit() {
}
let (executor, trace) = setup();
executor.spawner().spawn(task1(trace.clone())).unwrap();
executor.spawner().spawn(task1(trace.clone()).unwrap());
unsafe { executor.poll() };
unsafe { executor.poll() };
@ -120,7 +120,7 @@ fn executor_task_self_wake() {
}
let (executor, trace) = setup();
executor.spawner().spawn(task1(trace.clone())).unwrap();
executor.spawner().spawn(task1(trace.clone()).unwrap());
unsafe { executor.poll() };
unsafe { executor.poll() };
@ -152,7 +152,7 @@ fn executor_task_self_wake_twice() {
}
let (executor, trace) = setup();
executor.spawner().spawn(task1(trace.clone())).unwrap();
executor.spawner().spawn(task1(trace.clone()).unwrap());
unsafe { executor.poll() };
unsafe { executor.poll() };
@ -188,7 +188,7 @@ fn waking_after_completion_does_not_poll() {
let waker = Box::leak(Box::new(AtomicWaker::new()));
let (executor, trace) = setup();
executor.spawner().spawn(task1(trace.clone(), waker)).unwrap();
executor.spawner().spawn(task1(trace.clone(), waker).unwrap());
unsafe { executor.poll() };
waker.wake();
@ -200,7 +200,7 @@ fn waking_after_completion_does_not_poll() {
unsafe { executor.poll() }; // Clears running status
// Can respawn waken-but-dead task
executor.spawner().spawn(task1(trace.clone(), waker)).unwrap();
executor.spawner().spawn(task1(trace.clone(), waker).unwrap());
unsafe { executor.poll() };
@ -250,7 +250,7 @@ fn waking_with_old_waker_after_respawn() {
let waker = Box::leak(Box::new(AtomicWaker::new()));
let (executor, trace) = setup();
executor.spawner().spawn(task1(trace.clone(), waker)).unwrap();
executor.spawner().spawn(task1(trace.clone(), waker).unwrap());
unsafe { executor.poll() };
unsafe { executor.poll() }; // progress to registering the waker
@ -273,8 +273,7 @@ fn waking_with_old_waker_after_respawn() {
let (other_executor, other_trace) = setup();
other_executor
.spawner()
.spawn(task1(other_trace.clone(), waker))
.unwrap();
.spawn(task1(other_trace.clone(), waker).unwrap());
unsafe { other_executor.poll() }; // just run to the yield_now
waker.wake(); // trigger old waker registration
@ -338,22 +337,22 @@ fn task_metadata() {
// check no task name
let (executor, _) = setup();
executor.spawner().spawn(task1(None)).unwrap();
executor.spawner().spawn(task1(None).unwrap());
unsafe { executor.poll() };
// check setting task name
let token = task1(Some("foo"));
let token = task1(Some("foo")).unwrap();
token.metadata().set_name("foo");
executor.spawner().spawn(token).unwrap();
executor.spawner().spawn(token);
unsafe { executor.poll() };
let token = task1(Some("bar"));
let token = task1(Some("bar")).unwrap();
token.metadata().set_name("bar");
executor.spawner().spawn(token).unwrap();
executor.spawner().spawn(token);
unsafe { executor.poll() };
// check name is cleared if the task pool slot is recycled.
let (executor, _) = setup();
executor.spawner().spawn(task1(None)).unwrap();
executor.spawner().spawn(task1(None).unwrap());
unsafe { executor.poll() };
}

View File

@ -15,7 +15,7 @@ fn task() -> impl Future<Output = ()> {
}
fn send_spawn(s: SendSpawner) {
s.spawn(task()).unwrap();
s.spawn(task().unwrap());
}
fn main() {}

View File

@ -1,8 +1,8 @@
error: future cannot be sent between threads safely
--> tests/ui/return_impl_future_nonsend.rs:18:13
|
18 | s.spawn(task()).unwrap();
| ^^^^^^ future created by async block is not `Send`
18 | s.spawn(task().unwrap());
| ^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: within `impl Sized`, the trait `Send` is not implemented for `*mut ()`
note: captured value is not `Send`
@ -13,5 +13,5 @@ note: captured value is not `Send`
note: required by a bound in `SendSpawner::spawn`
--> src/spawner.rs
|
| pub fn spawn<S: Send>(&self, token: SpawnToken<S>) -> Result<(), SpawnError> {
| pub fn spawn<S: Send>(&self, token: SpawnToken<S>) {
| ^^^^ required by this bound in `SendSpawner::spawn`

View File

@ -97,7 +97,7 @@ note: required by a bound in `TaskPool::<F, N>::spawn`
| impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
| ^^^^^^ required by this bound in `TaskPool::<F, N>::spawn`
...
| pub fn spawn(&'static self, future: impl FnOnce() -> F) -> SpawnToken<impl Sized> {
| pub fn spawn(&'static self, future: impl FnOnce() -> F) -> Result<SpawnToken<impl Sized>, SpawnError> {
| ----- required by a bound in this associated function
= note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -10,7 +10,7 @@ async fn task(non_send: *mut ()) {
}
fn send_spawn(s: SendSpawner) {
s.spawn(task(core::ptr::null_mut())).unwrap();
s.spawn(task(core::ptr::null_mut()).unwrap());
}
fn main() {}

View File

@ -12,8 +12,8 @@ error[E0277]: `*mut ()` cannot be sent between threads safely
7 | #[embassy_executor::task]
| ------------------------- within this `impl Sized`
...
13 | s.spawn(task(core::ptr::null_mut())).unwrap();
| ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be sent between threads safely
13 | s.spawn(task(core::ptr::null_mut()).unwrap());
| ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be sent between threads safely
| |
| required by a bound introduced by this call
|
@ -26,8 +26,8 @@ note: required because it's used within this closure
note: required because it appears within the type `impl Sized`
--> src/raw/mod.rs
|
| pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> SpawnToken<impl Sized>
| ^^^^^^^^^^
| pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> Result<SpawnToken<impl Sized>, SpawnError>
| ^^^^^^^^^^
note: required because it appears within the type `impl Sized`
--> tests/ui/spawn_nonsend.rs:7:1
|
@ -36,6 +36,6 @@ note: required because it appears within the type `impl Sized`
note: required by a bound in `SendSpawner::spawn`
--> src/spawner.rs
|
| pub fn spawn<S: Send>(&self, token: SpawnToken<S>) -> Result<(), SpawnError> {
| pub fn spawn<S: Send>(&self, token: SpawnToken<S>) {
| ^^^^ required by this bound in `SendSpawner::spawn`
= note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -464,7 +464,7 @@ impl<'d> Stack<'d> {
/// seed
/// );
/// // Launch network task that runs `runner.run().await`
/// spawner.spawn(net_task(runner)).unwrap();
/// spawner.spawn(net_task(runner).unwrap());
/// // Wait for DHCP config
/// stack.wait_config_up().await;
/// // use the network stack

View File

@ -38,11 +38,11 @@
//!
//! embassy_rp::multicore::spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || {
//! let executor1 = EXECUTOR1.init(Executor::new());
//! executor1.run(|spawner| spawner.spawn(core1_task()).unwrap());
//! executor1.run(|spawner| spawner.spawn(core1_task().unwrap()));
//! });
//!
//! let executor0 = EXECUTOR0.init(Executor::new());
//! executor0.run(|spawner| spawner.spawn(core0_task()).unwrap())
//! executor0.run(|spawner| spawner.spawn(core0_task().unwrap()))
//! }
//! ```

View File

@ -29,7 +29,7 @@
//! #[cortex_m_rt::entry]
//! fn main() -> ! {
//! Executor::take().run(|spawner| {
//! unwrap!(spawner.spawn(async_main(spawner)));
//! spawner.spawn(unwrap!(async_main(spawner)));
//! });
//! }
//!

View File

@ -69,7 +69,7 @@ async fn main(spawner: Spawner) {
Default::default(),
)
.unwrap();
spawner.must_spawn(usart4_task(usart4));
spawner.spawn(usart4_task(usart4).unwrap());
let usart2 = Uart::new_with_rtscts(
p.FLEXCOMM2,
@ -83,5 +83,5 @@ async fn main(spawner: Spawner) {
Default::default(),
)
.unwrap();
spawner.must_spawn(usart2_task(usart2));
spawner.spawn(usart2_task(usart2).unwrap());
}

View File

@ -48,8 +48,8 @@ async fn main(spawner: Spawner) {
let usart4 = Uart::new_blocking(p.FLEXCOMM4, p.PIO0_29, p.PIO0_30, Default::default()).unwrap();
let (_, usart4) = usart4.split();
spawner.must_spawn(usart4_task(usart4));
spawner.spawn(usart4_task(usart4).unwrap());
let usart2 = UartTx::new_blocking(p.FLEXCOMM2, p.PIO0_15, Default::default()).unwrap();
spawner.must_spawn(usart2_task(usart2));
spawner.spawn(usart2_task(usart2).unwrap());
}

View File

@ -63,7 +63,7 @@ async fn main(spawner: Spawner) {
::log::set_max_level(::log::LevelFilter::Trace);
}
spawner.spawn(run1()).unwrap();
spawner.spawn(run2()).unwrap();
spawner.spawn(run3()).unwrap();
spawner.spawn(run1().unwrap());
spawner.spawn(run2().unwrap());
spawner.spawn(run3().unwrap());
}

View File

@ -31,7 +31,7 @@ async fn main(spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
unwrap!(spawner.spawn(my_task()));
spawner.spawn(unwrap!(my_task()));
loop {
match CHANNEL.receive().await {

View File

@ -45,6 +45,6 @@ async fn main(spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
let channel = CHANNEL.init(Channel::new());
unwrap!(spawner.spawn(send_task(channel.sender())));
unwrap!(spawner.spawn(recv_task(p.P0_13.into(), channel.receiver())));
spawner.spawn(unwrap!(send_task(channel.sender())));
spawner.spawn(unwrap!(recv_task(p.P0_13.into(), channel.receiver())));
}

View File

@ -70,7 +70,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
// And now we can use it!

View File

@ -36,7 +36,7 @@ async fn run3() {
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let _p = embassy_nrf::init(Default::default());
unwrap!(spawner.spawn(run1()));
unwrap!(spawner.spawn(run2()));
unwrap!(spawner.spawn(run3()));
spawner.spawn(unwrap!(run1()));
spawner.spawn(unwrap!(run2()));
spawner.spawn(unwrap!(run3()));
}

View File

@ -26,8 +26,8 @@ async fn main(spawner: Spawner) {
let btn3 = Input::new(p.P0_24, Pull::Up);
let btn4 = Input::new(p.P0_25, Pull::Up);
unwrap!(spawner.spawn(button_task(1, btn1)));
unwrap!(spawner.spawn(button_task(2, btn2)));
unwrap!(spawner.spawn(button_task(3, btn3)));
unwrap!(spawner.spawn(button_task(4, btn4)));
spawner.spawn(unwrap!(button_task(1, btn1)));
spawner.spawn(unwrap!(button_task(2, btn2)));
spawner.spawn(unwrap!(button_task(3, btn3)));
spawner.spawn(unwrap!(button_task(4, btn4)));
}

View File

@ -42,7 +42,7 @@ fn main() -> ! {
// `run` calls the closure then runs the executor forever. It never returns.
executor.run(|spawner| {
// Here we get access to a spawner to spawn the initial tasks.
unwrap!(spawner.spawn(run1()));
unwrap!(spawner.spawn(run2()));
spawner.spawn(unwrap!(run1()));
spawner.spawn(unwrap!(run2()));
});
}

View File

@ -130,16 +130,16 @@ fn main() -> ! {
// High-priority executor: EGU1_SWI1, priority level 6
interrupt::EGU1_SWI1.set_priority(Priority::P6);
let spawner = EXECUTOR_HIGH.start(interrupt::EGU1_SWI1);
unwrap!(spawner.spawn(run_high()));
spawner.spawn(unwrap!(run_high()));
// Medium-priority executor: EGU0_SWI0, priority level 7
interrupt::EGU0_SWI0.set_priority(Priority::P7);
let spawner = EXECUTOR_MED.start(interrupt::EGU0_SWI0);
unwrap!(spawner.spawn(run_med()));
spawner.spawn(unwrap!(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV
let executor = EXECUTOR_LOW.init(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
spawner.spawn(unwrap!(run_low()));
});
}

View File

@ -30,7 +30,7 @@ async fn my_task() {
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let _p = embassy_nrf::init(Default::default());
unwrap!(spawner.spawn(my_task()));
spawner.spawn(unwrap!(my_task()));
loop {
Timer::after_millis(300).await;

View File

@ -26,9 +26,9 @@ async fn main(spawner: Spawner) {
// It's good to set up the subscribers before publishing anything.
// A subscriber will only yield messages that have been published after its creation.
spawner.must_spawn(fast_logger(unwrap!(MESSAGE_BUS.subscriber())));
spawner.must_spawn(slow_logger(unwrap!(MESSAGE_BUS.dyn_subscriber())));
spawner.must_spawn(slow_logger_pure(unwrap!(MESSAGE_BUS.dyn_subscriber())));
spawner.spawn(fast_logger(unwrap!(MESSAGE_BUS.subscriber())).unwrap());
spawner.spawn(slow_logger(unwrap!(MESSAGE_BUS.dyn_subscriber())).unwrap());
spawner.spawn(slow_logger_pure(unwrap!(MESSAGE_BUS.dyn_subscriber())).unwrap());
// Get a publisher
let message_publisher = unwrap!(MESSAGE_BUS.publisher());

View File

@ -42,8 +42,8 @@ fn main() -> ! {
let run2_task = unsafe { make_static(&run2_task) };
executor.run(|spawner| {
unwrap!(spawner.spawn(run1_task.spawn(|| run1())));
unwrap!(spawner.spawn(run2_task.spawn(|| run2())));
spawner.spawn(unwrap!(run1_task.spawn(|| run1())));
spawner.spawn(unwrap!(run2_task.spawn(|| run2())));
});
}

View File

@ -14,12 +14,12 @@ mod config {
async fn my_task(spawner: Spawner, n: u32) {
Timer::after_secs(1).await;
info!("Spawning self! {}", n);
unwrap!(spawner.spawn(my_task(spawner, n + 1)));
spawner.spawn(unwrap!(my_task(spawner, n + 1)));
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let _p = embassy_nrf::init(Default::default());
info!("Hello World!");
unwrap!(spawner.spawn(my_task(spawner, 0)));
spawner.spawn(unwrap!(my_task(spawner, 0)));
}

View File

@ -11,12 +11,12 @@ async fn my_task(n: u32) {
Timer::after_secs(1).await;
info!("Spawning self! {}", n);
let spawner = unsafe { Spawner::for_current_executor().await };
unwrap!(spawner.spawn(my_task(n + 1)));
spawner.spawn(unwrap!(my_task(n + 1)));
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let _p = embassy_nrf::init(Default::default());
info!("Hello World!");
unwrap!(spawner.spawn(my_task(0)));
spawner.spawn(unwrap!(my_task(0)));
}

View File

@ -25,6 +25,6 @@ async fn run2() {
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let _p = embassy_nrf::init(Default::default());
unwrap!(spawner.spawn(run1()));
unwrap!(spawner.spawn(run2()));
spawner.spawn(unwrap!(run1()));
spawner.spawn(unwrap!(run2()));
}

View File

@ -30,7 +30,7 @@ async fn main(spawner: Spawner) {
// Spawn a task responsible purely for reading
unwrap!(spawner.spawn(reader(rx)));
spawner.spawn(unwrap!(reader(rx)));
// Message must be in SRAM
{

View File

@ -86,11 +86,11 @@ async fn main(spawner: Spawner) {
// Build the builder.
let usb = builder.build();
unwrap!(spawner.spawn(usb_task(usb)));
spawner.spawn(unwrap!(usb_task(usb)));
static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new();
let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr);
unwrap!(spawner.spawn(usb_ncm_task(runner)));
spawner.spawn(unwrap!(usb_ncm_task(runner)));
let config = embassy_net::Config::dhcpv4(Default::default());
// let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
@ -109,7 +109,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
// And now we can use it!

View File

@ -76,8 +76,8 @@ async fn main(spawner: Spawner) {
// Build the builder.
let usb = builder.build();
unwrap!(spawner.spawn(usb_task(usb)));
unwrap!(spawner.spawn(echo_task(class)));
spawner.spawn(unwrap!(usb_task(usb)));
spawner.spawn(unwrap!(echo_task(class)));
}
struct Disconnected {}

View File

@ -70,7 +70,7 @@ async fn main(spawner: Spawner) {
)
.await;
unwrap!(spawner.spawn(wifi_task(runner)));
spawner.spawn(unwrap!(wifi_task(runner)));
unwrap!(control.init().await);
unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await);
@ -92,7 +92,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
// And now we can use it!

View File

@ -112,7 +112,7 @@ async fn main(spawner: Spawner) {
info!("Hello World!");
unwrap!(spawner.spawn(blink_task(p.P0_02.into())));
spawner.spawn(unwrap!(blink_task(p.P0_02.into())));
let ipc_mem = unsafe {
let ipc_start = &__start_ipc as *const u8 as *mut MaybeUninit<u8>;
@ -138,8 +138,8 @@ async fn main(spawner: Spawner) {
static TRACE: StaticCell<TraceBuffer> = StaticCell::new();
let (device, control, runner, tracer) =
embassy_net_nrf91::new_with_trace(STATE.init(State::new()), ipc_mem, TRACE.init(TraceBuffer::new())).await;
unwrap!(spawner.spawn(modem_task(runner)));
unwrap!(spawner.spawn(trace_task(uart, tracer)));
spawner.spawn(unwrap!(modem_task(runner)));
spawner.spawn(unwrap!(trace_task(uart, tracer)));
let config = embassy_net::Config::default();
@ -150,12 +150,12 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::<2>::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
static CONTROL: StaticCell<context::Control<'static>> = StaticCell::new();
let control = CONTROL.init(context::Control::new(control, 0).await);
unwrap!(spawner.spawn(control_task(
spawner.spawn(unwrap!(control_task(
control,
context::Config {
apn: b"iot.nat.es",

View File

@ -26,15 +26,13 @@ async fn main(spawner: Spawner) {
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();
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();
spawner.spawn(double_blinky_macro_assigned(spawner, r.leds).unwrap());
}
// 1) Assigning a resource to a task by passing parts of the peripherals.

View File

@ -27,8 +27,8 @@ async fn main(spawner: Spawner) {
let dt = 100 * 1_000_000;
let k = 1.003;
unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
unwrap!(spawner.spawn(toggle_led(
spawner.spawn(unwrap!(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
spawner.spawn(unwrap!(toggle_led(
CHANNEL.sender(),
Duration::from_nanos((dt as f64 * k) as u64)
)));

View File

@ -30,8 +30,8 @@ async fn main(spawner: Spawner) {
let dt = 100 * 1_000_000;
let k = 1.003;
unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos(dt))));
unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos(dt))));
spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
}
#[embassy_executor::task(pool_size = 2)]

View File

@ -61,7 +61,7 @@ async fn main(spawner: Spawner) {
)
.await
.unwrap();
unwrap!(spawner.spawn(ethernet_task(runner)));
spawner.spawn(unwrap!(ethernet_task(runner)));
// Generate random seed
let seed = rng.next_u64();
@ -76,7 +76,7 @@ async fn main(spawner: Spawner) {
);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
info!("Waiting for DHCP...");
let cfg = wait_for_config(stack).await;

View File

@ -63,7 +63,7 @@ async fn main(spawner: Spawner) {
)
.await
.unwrap();
unwrap!(spawner.spawn(ethernet_task(runner)));
spawner.spawn(unwrap!(ethernet_task(runner)));
// Generate random seed
let seed = rng.next_u64();
@ -78,7 +78,7 @@ async fn main(spawner: Spawner) {
);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
info!("Waiting for DHCP...");
let cfg = wait_for_config(stack).await;

View File

@ -64,7 +64,7 @@ async fn main(spawner: Spawner) {
)
.await
.unwrap();
unwrap!(spawner.spawn(ethernet_task(runner)));
spawner.spawn(unwrap!(ethernet_task(runner)));
// Generate random seed
let seed = rng.next_u64();
@ -79,7 +79,7 @@ async fn main(spawner: Spawner) {
);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
info!("Waiting for DHCP...");
let cfg = wait_for_config(stack).await;
@ -87,8 +87,8 @@ async fn main(spawner: Spawner) {
info!("IP address: {:?}", local_addr);
// Create two sockets listening to the same port, to handle simultaneous connections
unwrap!(spawner.spawn(listen_task(stack, 0, 1234)));
unwrap!(spawner.spawn(listen_task(stack, 1, 1234)));
spawner.spawn(unwrap!(listen_task(stack, 0, 1234)));
spawner.spawn(unwrap!(listen_task(stack, 1, 1234)));
}
#[embassy_executor::task(pool_size = 2)]

View File

@ -67,7 +67,7 @@ async fn main(spawner: Spawner) {
)
.await
.unwrap();
unwrap!(spawner.spawn(ethernet_task(runner)));
spawner.spawn(unwrap!(ethernet_task(runner)));
// Generate random seed
let seed = rng.next_u64();
@ -82,7 +82,7 @@ async fn main(spawner: Spawner) {
);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
info!("Waiting for DHCP...");
let cfg = wait_for_config(stack).await;

View File

@ -66,7 +66,7 @@ async fn main(spawner: Spawner) {
)
.await
.unwrap();
unwrap!(spawner.spawn(ethernet_task(runner)));
spawner.spawn(unwrap!(ethernet_task(runner)));
// Generate random seed
let seed = rng.next_u64();
@ -81,7 +81,7 @@ async fn main(spawner: Spawner) {
);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
info!("Waiting for DHCP...");
let cfg = wait_for_config(stack).await;

View File

@ -64,7 +64,7 @@ async fn main(spawner: Spawner) {
)
.await
.unwrap();
unwrap!(spawner.spawn(ethernet_task(runner)));
spawner.spawn(unwrap!(ethernet_task(runner)));
// Generate random seed
let seed = rng.next_u64();
@ -79,7 +79,7 @@ async fn main(spawner: Spawner) {
);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
info!("Waiting for DHCP...");
let cfg = wait_for_config(stack).await;

View File

@ -105,7 +105,7 @@ async fn main(spawner: Spawner) {
config.addr = DEV_ADDR as u16;
let device = i2c_slave::I2cSlave::new(p.I2C1, d_scl, d_sda, Irqs, config);
unwrap!(spawner.spawn(device_task(device)));
spawner.spawn(unwrap!(device_task(device)));
let c_sda = p.PIN_0;
let c_scl = p.PIN_1;
@ -113,5 +113,5 @@ async fn main(spawner: Spawner) {
config.frequency = 1_000_000;
let controller = i2c::I2c::new_async(p.I2C0, c_scl, c_sda, Irqs, config);
unwrap!(spawner.spawn(controller_task(controller)));
spawner.spawn(unwrap!(controller_task(controller)));
}

View File

@ -51,7 +51,7 @@ async fn main(spawner: Spawner) {
// No Mutex needed when sharing within the same executor/prio level
static AVG: StaticCell<Cell<u32>> = StaticCell::new();
let avg = AVG.init(Default::default());
spawner.must_spawn(processing(avg));
spawner.spawn(processing(avg).unwrap());
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {

View File

@ -35,12 +35,12 @@ fn main() -> ! {
unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
move || {
let executor1 = EXECUTOR1.init(Executor::new());
executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led))));
executor1.run(|spawner| spawner.spawn(unwrap!(core1_task(led))));
},
);
let executor0 = EXECUTOR0.init(Executor::new());
executor0.run(|spawner| unwrap!(spawner.spawn(core0_task())));
executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
}
#[embassy_executor::task]

View File

@ -130,16 +130,16 @@ fn main() -> ! {
// High-priority executor: SWI_IRQ_1, priority level 2
interrupt::SWI_IRQ_1.set_priority(Priority::P2);
let spawner = EXECUTOR_HIGH.start(interrupt::SWI_IRQ_1);
unwrap!(spawner.spawn(run_high()));
spawner.spawn(unwrap!(run_high()));
// Medium-priority executor: SWI_IRQ_0, priority level 3
interrupt::SWI_IRQ_0.set_priority(Priority::P3);
let spawner = EXECUTOR_MED.start(interrupt::SWI_IRQ_0);
unwrap!(spawner.spawn(run_med()));
spawner.spawn(unwrap!(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV
let executor = EXECUTOR_LOW.init(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
spawner.spawn(unwrap!(run_low()));
});
}

View File

@ -129,13 +129,13 @@ async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let r = split_resources! {p};
spawner.spawn(orchestrate(spawner)).unwrap();
spawner.spawn(random_60s(spawner)).unwrap();
spawner.spawn(random_90s(spawner)).unwrap();
spawner.spawn(orchestrate(spawner).unwrap());
spawner.spawn(random_60s(spawner).unwrap());
spawner.spawn(random_90s(spawner).unwrap());
// `random_30s` is not spawned here, butin the orchestrate task depending on state
spawner.spawn(usb_power(spawner, r.vbus)).unwrap();
spawner.spawn(vsys_voltage(spawner, r.vsys)).unwrap();
spawner.spawn(consumer(spawner)).unwrap();
spawner.spawn(usb_power(spawner, r.vbus).unwrap());
spawner.spawn(vsys_voltage(spawner, r.vsys).unwrap());
spawner.spawn(consumer(spawner).unwrap());
}
/// Main task that processes all events and updates system state.
@ -198,7 +198,7 @@ async fn orchestrate(spawner: Spawner) {
drop(state);
if respawn_first_random_seed_task {
info!("(Re)-Starting the first random signal task");
spawner.spawn(random_30s(spawner)).unwrap();
spawner.spawn(random_30s(spawner).unwrap());
}
}
_ => {}

View File

@ -125,7 +125,7 @@ async fn main(spawner: Spawner) {
setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0);
setup_pio_task_sm1(&mut common, &mut sm1);
setup_pio_task_sm2(&mut common, &mut sm2);
spawner.spawn(pio_task_sm0(sm0)).unwrap();
spawner.spawn(pio_task_sm1(sm1)).unwrap();
spawner.spawn(pio_task_sm2(irq3, sm2)).unwrap();
spawner.spawn(pio_task_sm0(sm0).unwrap());
spawner.spawn(pio_task_sm1(sm1).unwrap());
spawner.spawn(pio_task_sm2(irq3, sm2).unwrap());
}

View File

@ -50,6 +50,6 @@ async fn main(spawner: Spawner) {
let encoder0 = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5, &prg);
let encoder1 = PioEncoder::new(&mut common, sm1, p.PIN_6, p.PIN_7, &prg);
spawner.must_spawn(encoder_0(encoder0));
spawner.must_spawn(encoder_1(encoder1));
spawner.spawn(encoder_0(encoder0).unwrap());
spawner.spawn(encoder_1(encoder1).unwrap());
}

View File

@ -18,8 +18,8 @@ use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25)).unwrap();
spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4)).unwrap();
spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25).unwrap());
spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4).unwrap());
}
/// Demonstrate PWM by modifying & applying the config

View File

@ -35,8 +35,8 @@ async fn main(spawner: Spawner) {
static I2C_BUS: StaticCell<I2c1Bus> = StaticCell::new();
let i2c_bus = I2C_BUS.init(Mutex::new(i2c));
spawner.must_spawn(i2c_task_a(i2c_bus));
spawner.must_spawn(i2c_task_b(i2c_bus));
spawner.spawn(i2c_task_a(i2c_bus).unwrap());
spawner.spawn(i2c_task_b(i2c_bus).unwrap());
// Shared SPI bus
let spi_cfg = spi::Config::default();
@ -48,8 +48,8 @@ async fn main(spawner: Spawner) {
let cs_a = Output::new(p.PIN_0, Level::High);
let cs_b = Output::new(p.PIN_1, Level::High);
spawner.must_spawn(spi_task_a(spi_bus, cs_a));
spawner.must_spawn(spi_task_b(spi_bus, cs_b));
spawner.spawn(spi_task_a(spi_bus, cs_a).unwrap());
spawner.spawn(spi_task_b(spi_bus, cs_b).unwrap());
}
#[embassy_executor::task]

View File

@ -68,7 +68,7 @@ fn main() -> ! {
// High-priority executor: runs in interrupt mode
interrupt::SWI_IRQ_0.set_priority(Priority::P3);
let spawner = EXECUTOR_HI.start(interrupt::SWI_IRQ_0);
spawner.must_spawn(task_a(uart));
spawner.spawn(task_a(uart).unwrap());
// Low priority executor: runs in thread mode
let executor = EXECUTOR_LOW.init(Executor::new());
@ -83,8 +83,8 @@ fn main() -> ! {
static REF_CELL: ConstStaticCell<RefCell<MyType>> = ConstStaticCell::new(RefCell::new(MyType { inner: 0 }));
let ref_cell = REF_CELL.take();
spawner.must_spawn(task_b(uart, cell, ref_cell));
spawner.must_spawn(task_c(cell, ref_cell));
spawner.spawn(task_b(uart, cell, ref_cell).unwrap());
spawner.spawn(task_c(cell, ref_cell).unwrap());
});
}

View File

@ -33,7 +33,7 @@ async fn main(spawner: Spawner) {
let uart = BufferedUart::new(uart, tx_pin, rx_pin, Irqs, tx_buf, rx_buf, Config::default());
let (mut tx, rx) = uart.split();
unwrap!(spawner.spawn(reader(rx)));
spawner.spawn(unwrap!(reader(rx)));
info!("Writing...");
loop {

View File

@ -27,7 +27,7 @@ async fn main(spawner: Spawner) {
let mut uart_tx = UartTx::new(p.UART0, p.PIN_0, p.DMA_CH0, Config::default());
let uart_rx = UartRx::new(p.UART1, p.PIN_5, Irqs, p.DMA_CH1, Config::default());
unwrap!(spawner.spawn(reader(uart_rx)));
spawner.spawn(unwrap!(reader(uart_rx)));
info!("Writing...");
loop {

View File

@ -84,11 +84,11 @@ async fn main(spawner: Spawner) {
// Build the builder.
let usb = builder.build();
unwrap!(spawner.spawn(usb_task(usb)));
spawner.spawn(unwrap!(usb_task(usb)));
static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new();
let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr);
unwrap!(spawner.spawn(usb_ncm_task(runner)));
spawner.spawn(unwrap!(usb_ncm_task(runner)));
let config = embassy_net::Config::dhcpv4(Default::default());
//let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
@ -104,7 +104,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
// And now we can use it!

View File

@ -25,7 +25,7 @@ async fn logger_task(driver: Driver<'static, USB>) {
async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let driver = Driver::new(p.USB, Irqs);
spawner.spawn(logger_task(driver)).unwrap();
spawner.spawn(logger_task(driver).unwrap());
let mut counter = 0;
loop {

View File

@ -69,7 +69,7 @@ async fn main(spawner: Spawner) {
let usb = builder.build();
// Run the USB device.
unwrap!(spawner.spawn(usb_task(usb)));
spawner.spawn(unwrap!(usb_task(usb)));
// Do stuff with the class!
loop {

View File

@ -53,7 +53,7 @@ async fn logger_task(driver: Driver<'static, USB>) {
async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let driver = Driver::new(p.USB, Irqs);
spawner.spawn(logger_task(driver)).unwrap();
spawner.spawn(logger_task(driver).unwrap());
let mut counter = 0;
loop {

View File

@ -70,7 +70,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control
@ -91,7 +91,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (stack, runner) = embassy_net::new(net_device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
//control.start_ap_open("cyw43", 5).await;
control.start_ap_wpa2("cyw43", "password", 5).await;

View File

@ -55,7 +55,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control

View File

@ -59,7 +59,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control

View File

@ -74,7 +74,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control
@ -95,7 +95,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
let (stack, runner) = embassy_net::new(net_device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
while let Err(err) = control
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))

View File

@ -76,7 +76,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control
@ -98,7 +98,7 @@ async fn main(spawner: Spawner) {
static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new();
let (stack, runner) = embassy_net::new(net_device, config, RESOURCES.init(StackResources::new()), seed);
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
while let Err(err) = control
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))

View File

@ -52,8 +52,8 @@ async fn main(spawner: Spawner) {
let channel = CHANNEL.init(Channel::new(buf));
let (sender, receiver) = channel.split();
spawner.must_spawn(consumer(receiver));
spawner.must_spawn(producer(sender, adc_parts));
spawner.spawn(consumer(receiver).unwrap());
spawner.spawn(producer(sender, adc_parts).unwrap());
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {

View File

@ -26,15 +26,13 @@ async fn main(spawner: Spawner) {
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();
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();
spawner.spawn(double_blinky_macro_assigned(spawner, r.leds).unwrap());
}
// 1) Assigning a resource to a task by passing parts of the peripherals.

View File

@ -27,8 +27,8 @@ async fn main(spawner: Spawner) {
let dt = 100 * 1_000_000;
let k = 1.003;
unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
unwrap!(spawner.spawn(toggle_led(
spawner.spawn(unwrap!(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
spawner.spawn(unwrap!(toggle_led(
CHANNEL.sender(),
Duration::from_nanos((dt as f64 * k) as u64)
)));

View File

@ -30,8 +30,8 @@ async fn main(spawner: Spawner) {
let dt = 100 * 1_000_000;
let k = 1.003;
unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos(dt))));
unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos(dt))));
spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
}
#[embassy_executor::task(pool_size = 2)]

View File

@ -71,7 +71,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control

View File

@ -68,7 +68,7 @@ async fn main(spawner: Spawner) {
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
unwrap!(spawner.spawn(cyw43_task(runner)));
spawner.spawn(unwrap!(cyw43_task(runner)));
control.init(clm).await;
control

View File

@ -105,7 +105,7 @@ async fn main(spawner: Spawner) {
config.addr = DEV_ADDR as u16;
let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config);
unwrap!(spawner.spawn(device_task(device)));
spawner.spawn(unwrap!(device_task(device)));
let c_sda = p.PIN_1;
let c_scl = p.PIN_0;
@ -113,5 +113,5 @@ async fn main(spawner: Spawner) {
config.frequency = 1_000_000;
let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config);
unwrap!(spawner.spawn(controller_task(controller)));
spawner.spawn(unwrap!(controller_task(controller)));
}

View File

@ -51,7 +51,7 @@ async fn main(spawner: Spawner) {
// No Mutex needed when sharing within the same executor/prio level
static AVG: StaticCell<Cell<u32>> = StaticCell::new();
let avg = AVG.init(Default::default());
spawner.must_spawn(processing(avg));
spawner.spawn(processing(avg).unwrap());
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {

View File

@ -35,12 +35,12 @@ fn main() -> ! {
unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
move || {
let executor1 = EXECUTOR1.init(Executor::new());
executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led))));
executor1.run(|spawner| spawner.spawn(unwrap!(core1_task(led))));
},
);
let executor0 = EXECUTOR0.init(Executor::new());
executor0.run(|spawner| unwrap!(spawner.spawn(core0_task())));
executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
}
#[embassy_executor::task]

View File

@ -130,16 +130,16 @@ fn main() -> ! {
// High-priority executor: SWI_IRQ_1, priority level 2
interrupt::SWI_IRQ_1.set_priority(Priority::P2);
let spawner = EXECUTOR_HIGH.start(interrupt::SWI_IRQ_1);
unwrap!(spawner.spawn(run_high()));
spawner.spawn(unwrap!(run_high()));
// Medium-priority executor: SWI_IRQ_0, priority level 3
interrupt::SWI_IRQ_0.set_priority(Priority::P3);
let spawner = EXECUTOR_MED.start(interrupt::SWI_IRQ_0);
unwrap!(spawner.spawn(run_med()));
spawner.spawn(unwrap!(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV
let executor = EXECUTOR_LOW.init(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
spawner.spawn(unwrap!(run_low()));
});
}

View File

@ -125,7 +125,7 @@ async fn main(spawner: Spawner) {
setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0);
setup_pio_task_sm1(&mut common, &mut sm1);
setup_pio_task_sm2(&mut common, &mut sm2);
spawner.spawn(pio_task_sm0(sm0)).unwrap();
spawner.spawn(pio_task_sm1(sm1)).unwrap();
spawner.spawn(pio_task_sm2(irq3, sm2)).unwrap();
spawner.spawn(pio_task_sm0(sm0).unwrap());
spawner.spawn(pio_task_sm1(sm1).unwrap());
spawner.spawn(pio_task_sm2(irq3, sm2).unwrap());
}

View File

@ -50,6 +50,6 @@ async fn main(spawner: Spawner) {
let encoder0 = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5, &prg);
let encoder1 = PioEncoder::new(&mut common, sm1, p.PIN_6, p.PIN_7, &prg);
spawner.must_spawn(encoder_0(encoder0));
spawner.must_spawn(encoder_1(encoder1));
spawner.spawn(encoder_0(encoder0).unwrap());
spawner.spawn(encoder_1(encoder1).unwrap());
}

View File

@ -18,8 +18,8 @@ use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25)).unwrap();
spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4)).unwrap();
spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25).unwrap());
spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4).unwrap());
}
/// Demonstrate PWM by modifying & applying the config

View File

@ -35,8 +35,8 @@ async fn main(spawner: Spawner) {
static I2C_BUS: StaticCell<I2c1Bus> = StaticCell::new();
let i2c_bus = I2C_BUS.init(Mutex::new(i2c));
spawner.must_spawn(i2c_task_a(i2c_bus));
spawner.must_spawn(i2c_task_b(i2c_bus));
spawner.spawn(i2c_task_a(i2c_bus).unwrap());
spawner.spawn(i2c_task_b(i2c_bus).unwrap());
// Shared SPI bus
let spi_cfg = spi::Config::default();
@ -48,8 +48,8 @@ async fn main(spawner: Spawner) {
let cs_a = Output::new(p.PIN_0, Level::High);
let cs_b = Output::new(p.PIN_1, Level::High);
spawner.must_spawn(spi_task_a(spi_bus, cs_a));
spawner.must_spawn(spi_task_b(spi_bus, cs_b));
spawner.spawn(spi_task_a(spi_bus, cs_a).unwrap());
spawner.spawn(spi_task_b(spi_bus, cs_b).unwrap());
}
#[embassy_executor::task]

View File

@ -68,7 +68,7 @@ fn main() -> ! {
// High-priority executor: runs in interrupt mode
interrupt::SWI_IRQ_0.set_priority(Priority::P3);
let spawner = EXECUTOR_HI.start(interrupt::SWI_IRQ_0);
spawner.must_spawn(task_a(uart));
spawner.spawn(task_a(uart).unwrap());
// Low priority executor: runs in thread mode
let executor = EXECUTOR_LOW.init(Executor::new());
@ -83,8 +83,8 @@ fn main() -> ! {
static REF_CELL: ConstStaticCell<RefCell<MyType>> = ConstStaticCell::new(RefCell::new(MyType { inner: 0 }));
let ref_cell = REF_CELL.take();
spawner.must_spawn(task_b(uart, cell, ref_cell));
spawner.must_spawn(task_c(cell, ref_cell));
spawner.spawn(task_b(uart, cell, ref_cell).unwrap());
spawner.spawn(task_c(cell, ref_cell).unwrap());
});
}

View File

@ -33,7 +33,7 @@ async fn main(spawner: Spawner) {
let uart = BufferedUart::new(uart, tx_pin, rx_pin, Irqs, tx_buf, rx_buf, Config::default());
let (mut tx, rx) = uart.split();
unwrap!(spawner.spawn(reader(rx)));
spawner.spawn(unwrap!(reader(rx)));
info!("Writing...");
loop {

View File

@ -27,7 +27,7 @@ async fn main(spawner: Spawner) {
let mut uart_tx = UartTx::new(p.UART0, p.PIN_0, p.DMA_CH0, Config::default());
let uart_rx = UartRx::new(p.UART1, p.PIN_5, Irqs, p.DMA_CH1, Config::default());
unwrap!(spawner.spawn(reader(uart_rx)));
spawner.spawn(unwrap!(reader(uart_rx)));
info!("Writing...");
loop {

View File

@ -52,8 +52,8 @@ async fn main(spawner: Spawner) {
let channel = CHANNEL.init(Channel::new(buf));
let (sender, receiver) = channel.split();
spawner.must_spawn(consumer(receiver));
spawner.must_spawn(producer(sender, adc_parts));
spawner.spawn(consumer(receiver).unwrap());
spawner.spawn(producer(sender, adc_parts).unwrap());
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {

View File

@ -56,7 +56,7 @@ async fn main_task(spawner: Spawner) {
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
// Launch network task
spawner.spawn(net_task(runner)).unwrap();
spawner.spawn(net_task(runner).unwrap());
// Then we can use it!
let mut rx_buffer = [0; 4096];
@ -95,6 +95,6 @@ fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(main_task(spawner)).unwrap();
spawner.spawn(main_task(spawner).unwrap());
});
}

View File

@ -53,7 +53,7 @@ async fn main_task(spawner: Spawner) {
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
// Launch network task
spawner.spawn(net_task(runner)).unwrap();
spawner.spawn(net_task(runner).unwrap());
let host = "example.com";
info!("querying host {:?}...", host);
@ -78,6 +78,6 @@ fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(main_task(spawner)).unwrap();
spawner.spawn(main_task(spawner).unwrap());
});
}

View File

@ -102,8 +102,8 @@ async fn main_task(spawner: Spawner) {
);
// Launch network task
spawner.spawn(net_task(net_runner)).unwrap();
spawner.spawn(ppp_task(stack, runner, port)).unwrap();
spawner.spawn(net_task(net_runner).unwrap());
spawner.spawn(ppp_task(stack, runner, port).unwrap());
// Then we can use it!
let mut rx_buffer = [0; 4096];
@ -160,6 +160,6 @@ fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(main_task(spawner)).unwrap();
spawner.spawn(main_task(spawner).unwrap());
});
}

View File

@ -52,7 +52,7 @@ async fn main_task(spawner: Spawner) {
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
// Launch network task
spawner.spawn(net_task(runner)).unwrap();
spawner.spawn(net_task(runner).unwrap());
// Then we can use it!
let mut rx_meta = [PacketMetadata::EMPTY; 16];
@ -86,6 +86,6 @@ fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(main_task(spawner)).unwrap();
spawner.spawn(main_task(spawner).unwrap());
});
}

View File

@ -50,6 +50,6 @@ fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(run()).unwrap();
spawner.spawn(run().unwrap());
});
}

View File

@ -54,7 +54,7 @@ async fn main_task(spawner: Spawner) {
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
// Launch network task
spawner.spawn(net_task(runner)).unwrap();
spawner.spawn(net_task(runner).unwrap());
// Then we can use it!
let mut rx_buffer = [0; 4096];
@ -101,6 +101,6 @@ fn main() {
let executor = EXECUTOR.init(Executor::new());
executor.run(|spawner| {
spawner.spawn(main_task(spawner)).unwrap();
spawner.spawn(main_task(spawner).unwrap());
});
}

View File

@ -17,5 +17,5 @@ async fn main(spawner: Spawner) {
.format_timestamp_nanos()
.init();
spawner.spawn(run()).unwrap();
spawner.spawn(run().unwrap());
}

View File

@ -46,7 +46,7 @@ async fn main(spawner: Spawner) {
BLINK_MS.store(del_var, Ordering::Relaxed);
// Spawn LED blinking task
spawner.spawn(led_task(p.PA5.into())).unwrap();
spawner.spawn(led_task(p.PA5.into()).unwrap());
loop {
// Check if button got pressed

View File

@ -134,16 +134,16 @@ fn main() -> ! {
// High-priority executor: USART1, priority level 6
interrupt::USART1.set_priority(Priority::P6);
let spawner = EXECUTOR_HIGH.start(interrupt::USART1);
unwrap!(spawner.spawn(run_high()));
spawner.spawn(unwrap!(run_high()));
// Medium-priority executor: USART2, priority level 7
interrupt::USART2.set_priority(Priority::P7);
let spawner = EXECUTOR_MED.start(interrupt::USART2);
unwrap!(spawner.spawn(run_med()));
spawner.spawn(unwrap!(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV
let executor = EXECUTOR_LOW.init(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
spawner.spawn(unwrap!(run_low()));
});
}

View File

@ -37,7 +37,7 @@ async fn main(spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
unwrap!(spawner.spawn(blinky(p.PC13)));
spawner.spawn(unwrap!(blinky(p.PC13)));
let ch3 = CapturePin::new(p.PA2, Pull::None);
let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default());

View File

@ -36,7 +36,7 @@ async fn main(spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
unwrap!(spawner.spawn(blinky(p.PC13)));
spawner.spawn(unwrap!(blinky(p.PC13)));
let mut pwm_input = PwmInput::new_ch1(p.TIM2, p.PA0, Pull::None, khz(10));
pwm_input.enable();

View File

@ -113,8 +113,8 @@ async fn main(spawner: Spawner) {
];
let leds = Leds::new(leds);
spawner.spawn(button_waiter(button)).unwrap();
spawner.spawn(led_blinker(leds)).unwrap();
spawner.spawn(button_waiter(button).unwrap());
spawner.spawn(led_blinker(leds).unwrap());
}
#[embassy_executor::task]

View File

@ -135,16 +135,16 @@ fn main() -> ! {
// High-priority executor: UART4, priority level 6
interrupt::UART4.set_priority(Priority::P6);
let spawner = EXECUTOR_HIGH.start(interrupt::UART4);
unwrap!(spawner.spawn(run_high()));
spawner.spawn(unwrap!(run_high()));
// Medium-priority executor: UART5, priority level 7
interrupt::UART5.set_priority(Priority::P7);
let spawner = EXECUTOR_MED.start(interrupt::UART5);
unwrap!(spawner.spawn(run_med()));
spawner.spawn(unwrap!(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV
let executor = EXECUTOR_LOW.init(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
spawner.spawn(unwrap!(run_low()));
});
}

View File

@ -11,7 +11,7 @@ use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
spawner.must_spawn(adc_task(p));
spawner.spawn(adc_task(p).unwrap());
}
#[embassy_executor::task]

View File

@ -91,7 +91,7 @@ async fn main(spawner: Spawner) -> ! {
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
// Launch network task
unwrap!(spawner.spawn(net_task(runner)));
spawner.spawn(unwrap!(net_task(runner)));
// Ensure DHCP configuration is up before trying connect
stack.wait_config_up().await;

Some files were not shown because too many files have changed in this diff Show More