aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/late-resources.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/examples/late-resources.rs b/examples/late-resources.rs
new file mode 100644
index 00000000..933a252b
--- /dev/null
+++ b/examples/late-resources.rs
@@ -0,0 +1,64 @@
+//! Demonstrates initialization of resources in `init`.
+
+#![deny(unsafe_code)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate cortex_m_rtfm as rtfm;
+extern crate stm32f103xx;
+
+use rtfm::{app, Threshold};
+
+app! {
+ device: stm32f103xx,
+
+ resources: {
+ // Usually, resources are initialized with a constant initializer:
+ static ON: bool = false;
+
+ // However, there are cases where this is not possible or not desired. For example, there
+ // may not be a sensible value to use, or the type may not be constructible in a constant
+ // (like `Vec`).
+ // While it is possible to use an `Option` in some cases, that requires you to properly
+ // initialize it and `.unwrap()` it at every use. It also consumes more memory.
+ //
+ // To solve this, it is possible to defer initialization of resources to `init` by omitting
+ // the initializer. Doing that will require `init` to return the values of all "late"
+ // resources.
+ static IP_ADDRESS: u32;
+ },
+
+ tasks: {
+ SYS_TICK: {
+ path: sys_tick,
+ resources: [IP_ADDRESS, ON],
+ },
+ }
+}
+
+// The signature of `init` is now required to have a specific return type.
+fn init(_p: init::Peripherals, _r: init::Resources) -> init::LateResourceValues {
+ // `init::Resources` does not contain `IP_ADDRESS`, since it is not yet initialized.
+ //_r.IP_ADDRESS; // doesn't compile
+
+ // ...obtain value for IP_ADDRESS from EEPROM/DHCP...
+ let ip_address = 0x7f000001;
+
+ init::LateResourceValues {
+ // This struct will contain fields for all resources with omitted initializers.
+ IP_ADDRESS: ip_address,
+ }
+}
+
+fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
+ // Other tasks can access late resources like any other, since they are guaranteed to be
+ // initialized when tasks are run.
+
+ r.IP_ADDRESS;
+}
+
+fn idle() -> ! {
+ loop {
+ rtfm::wfi();
+ }
+}