async-stm32f1xx 0.2.1

Abstractions for asynchronous programming on the STM32F1xx family of microcontrollers.
Documentation
//! Sharing state between tasks using [`Cell`] and [`RefCell`].
//!
//! # Expected output
//!
//! ```
//! Task `b` will set cell now.
//! Task `b` will set ref_cell now.
//! Task `b` will yield now.
//! Task `a`: cell = Cell { value: 42 }
//! Task `a`: ref_cell = RefCell { value: Some(42) }
//! Task `a` will yield now.
//! Task `b` will not yield again.
//! ```

#![no_main]
#![no_std]

use async_embedded::task;
use core::cell::{Cell, RefCell};
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
use panic_semihosting as _; // panic handler
use stm32f1xx_hal as _; // memory layout

#[entry]
fn main() -> ! {
    static mut CELL: Cell<u32> = Cell::new(0);
    static mut REF_CELL: RefCell<Option<u32>> = RefCell::new(None);

    // only references with `'static` lifetimes can be sent to `spawn`-ed tasks
    // NOTE we coerce these to a shared (`&-`) reference to avoid the `move` blocks taking ownership
    // of the owning static (`&'static mut`) reference
    let cell: &'static Cell<_> = CELL;
    let ref_cell: &'static RefCell<_> = REF_CELL;

    let a = async move {
        hprintln!("Task `a`: cell = {:?}", cell).ok();
        hprintln!("Task `a`: ref_cell = {:?}", ref_cell).ok();

        loop {
            hprintln!("Task `a` will yield now.").ok();
            task::r#yield().await;
        }
    };
    task::spawn(a);

    let b = async {
        hprintln!("Task `b` will set cell now.").ok();
        cell.set(42);

        hprintln!("Task `b` will set ref_cell now.").ok();
        *ref_cell.borrow_mut() = Some(42);

        hprintln!("Task `b` will yield now.").ok();
        task::r#yield().await;

        hprintln!("Task `b` will not yield again.").ok();
        loop {}
    };
    task::block_on(b)
}