diff --git a/src/macros.rs b/src/macros.rs
index 465d759e4b027922c042c4f1b9ed5d6167d884b7..bd43b4f100b897c0297f76b9210cb67c82e5766b 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -22,3 +22,44 @@ macro_rules! iprintln {
         iprint!($channel, concat!($fmt, "\n"), $($arg)*);
     };
 }
+
+/// Macro to create an 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
+///
+/// ``` ignore
+/// fn main() {
+///     // OK if `main` is executed only once
+///     let x: &'static mut bool = static_!(: bool = false).unwrap();
+///
+///     let y = alias();
+///     // BAD this second call to `alias` will definitively `panic!`
+///     let y_alias = alias();
+/// }
+///
+/// fn alias() -> &'static mut bool {
+///     static_!(: bool = false).unwrap()
+/// }
+/// ```
+#[macro_export]
+macro_rules! static_ {
+    (: $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)
+            }
+        })
+    }
+}