1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
//! The Fibers module. //! //! **NOTE** This module documentation should be viewed as a continuation of //! [the `drone_core` documentation](drone_core::fib). //! //! # Stackful Fibers //! //! This module implements stackful fibers that are similar to native threads in //! the Rust stdlib. They can run synchronous code inside and yield with a //! blocking call. A stackful fiber can be created with //! [`fib::new_proc`](crate::fib::new_proc), //! [`fib::new_proc_unchecked`](crate::fib::new_proc_unchecked), //! [`fib::new_proc_unprivileged`](crate::fib::new_proc_unprivileged), //! [`fib::new_proc_unprivileged_unchecked`](crate::fib::new_proc_unprivileged_unchecked): //! //! ``` //! use drone_cortex_m::{fib, sv}; //! //! use drone_cortex_m::sv::{SwitchBackService, SwitchContextService}; //! //! // Stackful fibers need a supervisor. //! sv! { //! pub struct Sv; //! static SERVICES; //! //! // These services are required for stackful fibers. //! SwitchContextService; //! SwitchBackService; //! } //! //! # fn main() { //! // This is `impl Fiber<Input = bool, Yield = i32, Return = usize>` //! let a = fib::new_proc::<Sv, bool, i32, usize, _>(0x800, |input, yielder| { //! // do some work and yield //! yielder.proc_yield(1); //! // do some work and yield //! yielder.proc_yield(2); //! // do some work and return //! 3 //! }); //! # } //! ``` //! //! A stackful fiber can be attached to a thread with //! [`token.add_proc(...)`](fib::ThrFiberProc::add_proc), //! [`token.add_proc_unchecked(...)`](fib::ThrFiberProc::add_proc_unchecked), //! [`token.add_proc_unprivileged(...)`](fib::ThrFiberProc::add_proc_unprivileged), //! [`token.add_proc_unprivileged_unchecked(...)`](fib::ThrFiberProc::add_proc_unprivileged_unchecked). //! Note that fibers that are directly attached to threads can't have input, //! yield and return values other than `()`. //! //! ``` //! # #![feature(generators)] //! # use drone_core::token::Token; //! # use drone_cortex_m::{sv, sv::SwitchBackService, sv::SwitchContextService}; //! # static mut THREADS: [Thr; 1] = [Thr::new(0)]; //! # drone_core::thr!(use THREADS; struct Thr {} struct ThrLocal {}); //! # #[derive(Clone, Copy)] struct SysTick; //! # struct Thrs { sys_tick: SysTick } //! # sv!(pub struct Sv; static SERVICES; SwitchContextService; SwitchBackService;); //! # unsafe impl Token for Thrs { //! # unsafe fn take() -> Self { Self { sys_tick: SysTick::take() } } //! # } //! # unsafe impl Token for SysTick { //! # unsafe fn take() -> Self { Self } //! # } //! # unsafe impl drone_core::thr::ThrToken for SysTick { //! # type Thr = Thr; //! # const THR_NUM: usize = 0; //! # } //! # impl drone_cortex_m::thr::ThrSv for SysTick { //! # type Sv = Sv; //! # } //! # fn main() { //! # let thr = unsafe { Thrs::take() }; //! use drone_cortex_m::thr::prelude::*; //! //! // this is `impl Fiber<Input = (), Yield = (), Return = ()>` //! thr.sys_tick.add_proc(0x800, |yielder| { //! // do some work and yield //! yielder.proc_yield(()); //! // do some work and yield //! yielder.proc_yield(()); //! // do some work and return //! }); //! # } //! ``` mod proc; #[doc(no_inline)] pub use drone_core::fib::*; pub use self::proc::{ new_proc, new_proc_unchecked, new_proc_unprivileged, new_proc_unprivileged_unchecked, FiberProc, ThrFiberProc, Yielder, };