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
/// Macro for sending a formatted string through an ITM channel #[macro_export] macro_rules! iprint { ($channel:expr, $s:expr) => { $crate::itm::write_str($channel, $s); }; ($channel:expr, $($arg:tt)*) => { $crate::itm::write_fmt($channel, format_args!($($arg)*)); }; } /// Macro for sending a formatted string through an ITM channel, with a newline. #[macro_export] macro_rules! iprintln { ($channel:expr) => { iprint!($channel, "\n"); }; ($channel:expr, $fmt:expr) => { iprint!($channel, concat!($fmt, "\n")); }; ($channel:expr, $fmt:expr, $($arg:tt)*) => { iprint!($channel, concat!($fmt, "\n"), $($arg)*); }; } /// Macro to create a mutable reference to a statically allocated value /// /// This macro returns a value with type `Option<&'static mut $ty>`. `Some($expr)` will be returned /// the first time the macro is executed; further calls will return `None`. To avoid `unwrap`ping a /// `None` variant the caller must ensure that the macro is called from a function that's executed /// at most once in the whole lifetime of the program. /// /// # Example /// /// ``` no_run /// #[macro_use(singleton)] /// extern crate cortex_m; /// /// fn main() { /// // OK if `main` is executed only once /// let x: &'static mut bool = singleton!(: bool = false).unwrap(); /// /// let y = alias(); /// // BAD this second call to `alias` will definitively `panic!` /// let y_alias = alias(); /// } /// /// fn alias() -> &'static mut bool { /// singleton!(: bool = false).unwrap() /// } /// ``` #[macro_export] macro_rules! singleton { (: $ty:ty = $expr:expr) => { $crate::interrupt::free(|_| unsafe { static mut USED: bool = false; static mut VAR: $ty = $expr; if USED { None } else { USED = true; let var: &'static mut _ = &mut VAR; Some(var) } }) } }