diff options
| author | Jorge Aparicio <jorge@japaric.io> | 2019-02-11 21:40:53 +0100 |
|---|---|---|
| committer | Jorge Aparicio <jorge@japaric.io> | 2019-02-11 21:40:53 +0100 |
| commit | 0007a35a274ab2d07eb937e41971ea5e2c1cb5ff (patch) | |
| tree | 98361d6d3dfced4b068771c31163b324573294b7 /book/en/src/by-example/app.md | |
| parent | 68a937a72a3a6d261076803d38b7d9b2cb9e3067 (diff) | |
change layout of books
Diffstat (limited to 'book/en/src/by-example/app.md')
| -rw-r--r-- | book/en/src/by-example/app.md | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/book/en/src/by-example/app.md b/book/en/src/by-example/app.md new file mode 100644 index 0000000..996b8c1 --- /dev/null +++ b/book/en/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 *peripheral access crate* (PAC) 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. |
