aboutsummaryrefslogtreecommitdiff
path: root/book/src/by-example/app.md
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-11-03 16:31:11 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-11-03 16:31:11 +0000
commit777765e522949ebf84d05d4db075132172d81494 (patch)
tree41bc00739da8f832eb5ba68ef99ec8b9d06111a4 /book/src/by-example/app.md
parent653338e7997a0cdc5deaed98b1bb5f60006717ed (diff)
parent3a867e70c3b1afc4943ec597e4f188432fba5a8b (diff)
Merge #97
97: v0.4.0 r=japaric a=japaric closes #32 closes #33 Co-authored-by: Jorge Aparicio <jorge@japaric.io>
Diffstat (limited to 'book/src/by-example/app.md')
-rw-r--r--book/src/by-example/app.md105
1 files changed, 105 insertions, 0 deletions
diff --git a/book/src/by-example/app.md b/book/src/by-example/app.md
new file mode 100644
index 0000000..ae0f4b8
--- /dev/null
+++ b/book/src/by-example/app.md
@@ -0,0 +1,105 @@
+# The `app` attribute
+
+This is the smallest possible RTFM application:
+
+``` rust
+{{#include ../../../examples/smallest.rs}}
+```
+
+All RTFM applications use the [`app`] attribute (`#[app(..)]`). This attribute
+must be applied to a `const` item that contains items. The `app` attribute has
+a mandatory `device` argument that takes a *path* as a value. This path must
+point to a *device* crate generated using [`svd2rust`] **v0.14.x**. The `app`
+attribute will expand into a suitable entry point so it's not required to use
+the [`cortex_m_rt::entry`] attribute.
+
+[`app`]: ../../api/cortex_m_rtfm_macros/attr.app.html
+[`svd2rust`]: https://crates.io/crates/svd2rust
+[`cortex_m_rt::entry`]: ../../api/cortex_m_rt_macros/attr.entry.html
+
+> **ASIDE**: Some of you may be wondering why we are using a `const` item as a
+> module and not a proper `mod` item. The reason is that using attributes on
+> modules requires a feature gate, which requires a nightly toolchain. To make
+> RTFM work on stable we use the `const` item instead. When more parts of macros
+> 1.2 are stabilized we'll move from a `const` item to a `mod` item and
+> eventually to a crate level attribute (`#![app]`).
+
+## `init`
+
+Within the pseudo-module the `app` attribute expects to find an initialization
+function marked with the `init` attribute. This function must have signature
+`[unsafe] fn()`.
+
+This initialization function will be the first part of the application to run.
+The `init` function will run *with interrupts disabled* and has exclusive access
+to Cortex-M and device specific peripherals through the `core` and `device`
+variables, which are injected in the scope of `init` by the `app` attribute. Not
+all Cortex-M peripherals are available in `core` because the RTFM runtime takes
+ownership of some of them -- for more details see the [`rtfm::Peripherals`]
+struct.
+
+`static mut` variables declared at the beginning of `init` will be transformed
+into `&'static mut` references that are safe to access.
+
+[`rtfm::Peripherals`]: ../../api/rtfm/struct.Peripherals.html
+
+The example below shows the types of the `core` and `device` variables and
+showcases safe access to a `static mut` variable.
+
+``` rust
+{{#include ../../../examples/init.rs}}
+```
+
+Running the example will print `init` to the console and then exit the QEMU
+process.
+
+``` console
+$ cargo run --example init
+{{#include ../../../ci/expected/init.run}}```
+
+## `idle`
+
+A function marked with the `idle` attribute can optionally appear in the
+pseudo-module. This function is used as the special *idle task* and must have
+signature `[unsafe] fn() - > !`.
+
+When present, the runtime will execute the `idle` task after `init`. Unlike
+`init`, `idle` will run *with interrupts enabled* and it's not allowed to return
+so it runs forever.
+
+When no `idle` function is declared, the runtime sets the [SLEEPONEXIT] bit and
+then sends the microcontroller to sleep after running `init`.
+
+[SLEEPONEXIT]: https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
+
+Like in `init`, `static mut` variables will be transformed into `&'static mut`
+references that are safe to access.
+
+The example below shows that `idle` runs after `init`.
+
+``` rust
+{{#include ../../../examples/idle.rs}}
+```
+
+``` console
+$ cargo run --example idle
+{{#include ../../../ci/expected/idle.run}}```
+
+## `interrupt` / `exception`
+
+Just like you would do with the `cortex-m-rt` crate you can use the `interrupt`
+and `exception` attributes within the `app` pseudo-module to declare interrupt
+and exception handlers. In RTFM, we refer to interrupt and exception handlers as
+*hardware* tasks.
+
+``` rust
+{{#include ../../../examples/interrupt.rs}}
+```
+
+``` console
+$ cargo run --example interrupt
+{{#include ../../../ci/expected/interrupt.run}}```
+
+So far all the RTFM applications we have seen look no different that the
+applications one can write using only the `cortex-m-rt` crate. In the next
+section we start introducing features unique to RTFM.