aboutsummaryrefslogtreecommitdiff
path: root/book/en/src
diff options
context:
space:
mode:
Diffstat (limited to 'book/en/src')
-rw-r--r--book/en/src/SUMMARY.md6
-rw-r--r--book/en/src/by-example.md8
-rw-r--r--book/en/src/by-example/app.md13
-rw-r--r--book/en/src/by-example/new.md18
-rw-r--r--book/en/src/by-example/resources.md6
-rw-r--r--book/en/src/by-example/tips.md1
-rw-r--r--book/en/src/migration.md333
-rw-r--r--book/en/src/migration/migration_rtic.md (renamed from book/en/src/migration_rtic.md)4
-rw-r--r--book/en/src/migration/migration_v4.md233
-rw-r--r--book/en/src/migration/migration_v5.md96
10 files changed, 374 insertions, 344 deletions
diff --git a/book/en/src/SUMMARY.md b/book/en/src/SUMMARY.md
index a573cbb5..e1a4a330 100644
--- a/book/en/src/SUMMARY.md
+++ b/book/en/src/SUMMARY.md
@@ -10,8 +10,10 @@
- [Types, Send and Sync](./by-example/types-send-sync.md)
- [Starting a new project](./by-example/new.md)
- [Tips & tricks](./by-example/tips.md)
-- [Migrating from v0.4.x to v0.5.0](./migration.md)
-- [Migrating from RTFM to RTIC](./migration_rtic.md)
+- [Migration Guides](./migration.md)
+ - [v0.5.x to v0.6.x](./migration/migration_v5.md)
+ - [v0.4.x to v0.5.x](./migration/migration_v4.md)
+ - [RTFM to RTIC](./migration/migration_rtic.md)
- [Under the hood](./internals.md)
- [Interrupt configuration](./internals/interrupt-configuration.md)
- [Non-reentrancy](./internals/non-reentrancy.md)
diff --git a/book/en/src/by-example.md b/book/en/src/by-example.md
index 38985da1..e4441fd9 100644
--- a/book/en/src/by-example.md
+++ b/book/en/src/by-example.md
@@ -14,3 +14,11 @@ program. Check [the embedded Rust book] for instructions on how to set up an
embedded development environment that includes QEMU.
[the embedded Rust book]: https://rust-embedded.github.io/book/intro/install.html
+
+## Real World Examples
+
+The following are examples of RTFM being used in real world projects.
+
+### RTFM V0.4.2
+
+- [etrombly/sandbox](https://github.com/etrombly/sandbox/tree/41d423bcdd0d8e42fd46b79771400a8ca349af55). A hardware zen garden that draws patterns in sand. Patterns are sent over serial using G-code.
diff --git a/book/en/src/by-example/app.md b/book/en/src/by-example/app.md
index ab6f4524..c4f18c7a 100644
--- a/book/en/src/by-example/app.md
+++ b/book/en/src/by-example/app.md
@@ -7,11 +7,14 @@ This is the smallest possible RTIC application:
```
All RTIC applications use the [`app`] attribute (`#[app(..)]`). This attribute
-must be applied to a `mod`-item. 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** or newer. The `app` attribute will expand into a suitable entry
-point so it's not required to use the [`cortex_m_rt::entry`] attribute.
+must be applied to a `mod`-item. The `app` attribute has a mandatory `device`
+argument that takes a *path* as a value. This must be a full path pointing to a
+*peripheral access crate* (PAC) generated using [`svd2rust`] **v0.14.x** or
+newer. More details can be found in the [Starting a new project](./new.md)
+section.
+
+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_rtic_macros/attr.app.html
[`svd2rust`]: https://crates.io/crates/svd2rust
diff --git a/book/en/src/by-example/new.md b/book/en/src/by-example/new.md
index 866a9fa5..82681bf4 100644
--- a/book/en/src/by-example/new.md
+++ b/book/en/src/by-example/new.md
@@ -52,7 +52,23 @@ $ curl \
> src/main.rs
```
-That example depends on the `panic-semihosting` crate:
+The `init` example uses the `lm3s6965` device. Remember to adjust the `device`
+argument in the app macro attribute to match the path of your PAC crate, if
+different, and add peripherals or other arguments if needed. Although aliases
+can be used, this needs to be a full path (from the crate root). For many
+devices, it is common for the HAL implementation crate (aliased as `hal`) or
+Board Support crate to re-export the PAC as `pac`, leading to a pattern similar
+to the below:
+
+```rust
+use abcd123_hal as hal;
+//...
+
+#[rtic::app(device = crate::hal::pac, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
+mod app { /*...*/ }
+```
+
+The `init` example also depends on the `panic-semihosting` crate:
``` console
$ cargo add panic-semihosting
diff --git a/book/en/src/by-example/resources.md b/book/en/src/by-example/resources.md
index d082dfc1..9d90fbe3 100644
--- a/book/en/src/by-example/resources.md
+++ b/book/en/src/by-example/resources.md
@@ -1,4 +1,4 @@
-## Resources
+# Resources
The framework provides an abstraction to share data between any of the contexts
we saw in the previous section (task handlers, `init` and `idle`): resources.
@@ -116,7 +116,9 @@ are required to access the resource even if the resource is contended by several
tasks running at different priorities. The downside is that the task only gets a
shared reference (`&-`) to the resource, limiting the operations it can perform
on it, but where a shared reference is enough this approach reduces the number
-of required locks.
+of required locks. In addition to simple immutable data, this shared access can
+be useful where the resource type safely implements interior mutability, with
+appropriate locking or atomic operations of its own.
Note that in this release of RTIC it is not possible to request both exclusive
access (`&mut-`) and shared access (`&-`) to the *same* resource from different
diff --git a/book/en/src/by-example/tips.md b/book/en/src/by-example/tips.md
index d8264c90..090b30ad 100644
--- a/book/en/src/by-example/tips.md
+++ b/book/en/src/by-example/tips.md
@@ -116,6 +116,7 @@ Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes.
``` rust
{{#include ../../../../examples/pool.rs}}
```
+
``` console
$ cargo run --example pool
{{#include ../../../../ci/expected/pool.run}}
diff --git a/book/en/src/migration.md b/book/en/src/migration.md
index 7be30943..08feb81e 100644
--- a/book/en/src/migration.md
+++ b/book/en/src/migration.md
@@ -1,331 +1,4 @@
-# Migration of RTIC
+# Migration Guides
-## Migrating from v0.5.x to v0.6.0
-
-This section describes how to upgrade from v0.5.x to v0.6.0 of the RTIC framework.
-
-### `Cargo.toml` - version bump
-
-Change the version of `cortex-m-rtic` to `"0.6.0"`.
-
-### Module instead of Const
-
-With the support of attributes on modules the `const APP` workaround is not needed.
-
-Change
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- [code here]
-};
-```
-
-into
-
-``` rust
-#[rtic::app(/* .. */)]
-mod app {
- [code here]
-}
-```
-
-Now that a regular Rust module is used it means it is possible to have custom
-user code within that module.
-Additionally, it means that `use`-statements for resources etc may be required.
-
-### Init always returns late resources
-
-In order to make the API more symmetric the #[init]-task always returns a late resource.
-
-From this:
-
-``` rust
-#[rtic::app(device = lm3s6965)]
-mod app {
- #[init]
- fn init(_: init::Context) {
- rtic::pend(Interrupt::UART0);
- }
- [more code]
-}
-```
-
-to this:
-
-``` rust
-#[rtic::app(device = lm3s6965)]
-mod app {
- #[init]
- fn init(_: init::Context) -> init::LateResources {
- rtic::pend(Interrupt::UART0);
-
- init::LateResources {}
- }
- [more code]
-}
-```
-
-### Resources struct - #[resources]
-
-Previously the RTIC resources had to be in in a struct named exactly "Resources":
-
-``` rust
-struct Resources {
- // Resources defined in here
-}
-```
-
-With RTIC v0.6.0 the resources struct is annotated similarly like
-`#[task]`, `#[init]`, `#[idle]`: with an attribute `#[resources]`
-
-``` rust
-#[resources]
-struct Resources {
- // Resources defined in here
-}
-```
-
-In fact, the name of the struct is now up to the developer:
-
-``` rust
-#[resources]
-struct whateveryouwant {
- // Resources defined in here
-}
-```
-
-would work equally well.
-
-## Migrating from v0.4.x to v0.5.0
-
-This section covers how to upgrade an application written against RTIC v0.4.x to
-the version v0.5.0 of the framework.
-
-### `Cargo.toml`
-
-First, the version of the `cortex-m-rtic` dependency needs to be updated to
-`"0.5.0"`. The `timer-queue` feature needs to be removed.
-
-``` toml
-[dependencies.cortex-m-rtic]
-# change this
-version = "0.4.3"
-
-# into this
-version = "0.5.0"
-
-# and remove this Cargo feature
-features = ["timer-queue"]
-# ^^^^^^^^^^^^^
-```
-
-### `Context` argument
-
-All functions inside the `#[rtic::app]` item need to take as first argument a
-`Context` structure. This `Context` type will contain the variables that were
-magically injected into the scope of the function by version v0.4.x of the
-framework: `resources`, `spawn`, `schedule` -- these variables will become
-fields of the `Context` structure. Each function within the `#[rtic::app]` item
-gets a different `Context` type.
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- // change this
- #[task(resources = [x], spawn = [a], schedule = [b])]
- fn foo() {
- resources.x.lock(|x| /* .. */);
- spawn.a(message);
- schedule.b(baseline);
- }
-
- // into this
- #[task(resources = [x], spawn = [a], schedule = [b])]
- fn foo(mut cx: foo::Context) {
- // ^^^^^^^^^^^^^^^^^^^^
-
- cx.resources.x.lock(|x| /* .. */);
- // ^^^
-
- cx.spawn.a(message);
- // ^^^
-
- cx.schedule.b(message, baseline);
- // ^^^
- }
-
- // change this
- #[init]
- fn init() {
- // ..
- }
-
- // into this
- #[init]
- fn init(cx: init::Context) {
- // ^^^^^^^^^^^^^^^^^
- // ..
- }
-
- // ..
-};
-```
-
-### Resources
-
-The syntax used to declare resources has been changed from `static mut`
-variables to a `struct Resources`.
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- // change this
- static mut X: u32 = 0;
- static mut Y: u32 = (); // late resource
-
- // into this
- struct Resources {
- #[init(0)] // <- initial value
- X: u32, // NOTE: we suggest changing the naming style to `snake_case`
-
- Y: u32, // late resource
- }
-
- // ..
-};
-```
-
-### Device peripherals
-
-If your application was accessing the device peripherals in `#[init]` through
-the `device` variable then you'll need to add `peripherals = true` to the
-`#[rtic::app]` attribute to continue to access the device peripherals through
-the `device` field of the `init::Context` structure.
-
-Change this:
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- #[init]
- fn init() {
- device.SOME_PERIPHERAL.write(something);
- }
-
- // ..
-};
-```
-
-Into this:
-
-``` rust
-#[rtic::app(/* .. */, peripherals = true)]
-// ^^^^^^^^^^^^^^^^^^
-const APP: () = {
- #[init]
- fn init(cx: init::Context) {
- // ^^^^^^^^^^^^^^^^^
- cx.device.SOME_PERIPHERAL.write(something);
- // ^^^
- }
-
- // ..
-};
-```
-
-### `#[interrupt]` and `#[exception]`
-
-The `#[interrupt]` and `#[exception]` attributes have been removed. To declare
-hardware tasks in v0.5.x use the `#[task]` attribute with the `binds` argument.
-
-Change this:
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- // hardware tasks
- #[exception]
- fn SVCall() { /* .. */ }
-
- #[interrupt]
- fn UART0() { /* .. */ }
-
- // software task
- #[task]
- fn foo() { /* .. */ }
-
- // ..
-};
-```
-
-Into this:
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- #[task(binds = SVCall)]
- // ^^^^^^^^^^^^^^
- fn svcall(cx: svcall::Context) { /* .. */ }
- // ^^^^^^ we suggest you use a `snake_case` name here
-
- #[task(binds = UART0)]
- // ^^^^^^^^^^^^^
- fn uart0(cx: uart0::Context) { /* .. */ }
-
- #[task]
- fn foo(cx: foo::Context) { /* .. */ }
-
- // ..
-};
-```
-
-### `schedule`
-
-The `timer-queue` feature has been removed. To use the `schedule` API one must
-first define the monotonic timer the runtime will use using the `monotonic`
-argument of the `#[rtic::app]` attribute. To continue using the cycle counter
-(CYCCNT) as the monotonic timer, and match the behavior of version v0.4.x, add
-the `monotonic = rtic::cyccnt::CYCCNT` argument to the `#[rtic::app]` attribute.
-
-Also, the `Duration` and `Instant` types and the `U32Ext` trait have been moved
-into the `rtic::cyccnt` module. This module is only available on ARMv7-M+
-devices. The removal of the `timer-queue` also brings back the `DWT` peripheral
-inside the core peripherals struct, this will need to be enabled by the application
-inside `init`.
-
-Change this:
-
-``` rust
-use rtic::{Duration, Instant, U32Ext};
-
-#[rtic::app(/* .. */)]
-const APP: () = {
- #[task(schedule = [b])]
- fn a() {
- // ..
- }
-};
-```
-
-Into this:
-
-``` rust
-use rtic::cyccnt::{Duration, Instant, U32Ext};
-// ^^^^^^^^
-
-#[rtic::app(/* .. */, monotonic = rtic::cyccnt::CYCCNT)]
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-const APP: () = {
- #[init]
- fn init(cx: init::Context) {
- cx.core.DWT.enable_cycle_counter();
- // optional, configure the DWT run without a debugger connected
- cx.core.DCB.enable_trace();
- }
- #[task(schedule = [b])]
- fn a(cx: a::Context) {
- // ..
- }
-};
-```
+This section describes how to migrate between different version of RTIC.
+It also acts as a comparing reference between versions.
diff --git a/book/en/src/migration_rtic.md b/book/en/src/migration/migration_rtic.md
index 555f1bb7..c027da35 100644
--- a/book/en/src/migration_rtic.md
+++ b/book/en/src/migration/migration_rtic.md
@@ -8,14 +8,11 @@ change.
[RFC #33]: https://github.com/rtic-rs/rfcs/pull/33
-
-
## `Cargo.toml`
First, the `cortex-m-rtfm` dependency needs to be updated to
`cortex-m-rtic`.
-
``` toml
[dependencies]
# change this
@@ -51,4 +48,3 @@ const APP: () = {
};
```
-
diff --git a/book/en/src/migration/migration_v4.md b/book/en/src/migration/migration_v4.md
new file mode 100644
index 00000000..ac59d8c9
--- /dev/null
+++ b/book/en/src/migration/migration_v4.md
@@ -0,0 +1,233 @@
+# Migrating from v0.4.x to v0.5.0
+
+This section covers how to upgrade an application written against RTIC v0.4.x to
+the version v0.5.0 of the framework.
+
+## `Cargo.toml`
+
+First, the version of the `cortex-m-rtic` dependency needs to be updated to
+`"0.5.0"`. The `timer-queue` feature needs to be removed.
+
+``` toml
+[dependencies.cortex-m-rtic]
+# change this
+version = "0.4.3"
+
+# into this
+version = "0.5.0"
+
+# and remove this Cargo feature
+features = ["timer-queue"]
+# ^^^^^^^^^^^^^
+```
+
+## `Context` argument
+
+All functions inside the `#[rtic::app]` item need to take as first argument a
+`Context` structure. This `Context` type will contain the variables that were
+magically injected into the scope of the function by version v0.4.x of the
+framework: `resources`, `spawn`, `schedule` -- these variables will become
+fields of the `Context` structure. Each function within the `#[rtic::app]` item
+gets a different `Context` type.
+
+``` rust
+#[rtic::app(/* .. */)]
+const APP: () = {
+ // change this
+ #[task(resources = [x], spawn = [a], schedule = [b])]
+ fn foo() {
+ resources.x.lock(|x| /* .. */);
+ spawn.a(message);
+ schedule.b(baseline);
+ }
+
+ // into this
+ #[task(resources = [x], spawn = [a], schedule = [b])]
+ fn foo(mut cx: foo::Context) {
+ // ^^^^^^^^^^^^^^^^^^^^
+
+ cx.resources.x.lock(|x| /* .. */);
+ // ^^^
+
+ cx.spawn.a(message);
+ // ^^^
+
+ cx.schedule.b(message, baseline);
+ // ^^^
+ }
+
+ // change this
+ #[init]
+ fn init() {
+ // ..
+ }
+
+ // into this
+ #[init]
+ fn init(cx: init::Context) {
+ // ^^^^^^^^^^^^^^^^^
+ // ..
+ }
+
+ // ..
+};
+```
+
+## Resources
+
+The syntax used to declare resources has been changed from `static mut`
+variables to a `struct Resources`.
+
+``` rust
+#[rtic::app(/* .. */)]
+const APP: () = {
+ // change this
+ static mut X: u32 = 0;
+ static mut Y: u32 = (); // late resource
+
+ // into this
+ struct Resources {
+ #[init(0)] // <- initial value
+ X: u32, // NOTE: we suggest changing the naming style to `snake_case`
+
+ Y: u32, // late resource
+ }
+
+ // ..
+};
+```
+
+## Device peripherals
+
+If your application was accessing the device peripherals in `#[init]` through
+the `device` variable then you'll need to add `peripherals = true` to the
+`#[rtic::app]` attribute to continue to access the device peripherals through
+the `device` field of the `init::Context` structure.
+
+Change this:
+
+``` rust
+#[rtic::app(/* .. */)]
+const APP: () = {
+ #[init]
+ fn init() {
+ device.SOME_PERIPHERAL.write(something);
+ }
+
+ // ..
+};
+```
+
+Into this:
+
+``` rust
+#[rtic::app(/* .. */, peripherals = true)]
+// ^^^^^^^^^^^^^^^^^^
+const APP: () = {
+ #[init]
+ fn init(cx: init::Context) {
+ // ^^^^^^^^^^^^^^^^^
+ cx.device.SOME_PERIPHERAL.write(something);
+ // ^^^
+ }
+
+ // ..
+};
+```
+
+## `#[interrupt]` and `#[exception]`
+
+The `#[interrupt]` and `#[exception]` attributes have been removed. To declare
+hardware tasks in v0.5.x use the `#[task]` attribute with the `binds` argument.
+
+Change this:
+
+``` rust
+#[rtic::app(/* .. */)]
+const APP: () = {
+ // hardware tasks
+ #[exception]
+ fn SVCall() { /* .. */ }
+
+ #[interrupt]
+ fn UART0() { /* .. */ }
+
+ // software task
+ #[task]
+ fn foo() { /* .. */ }
+
+ // ..
+};
+```
+
+Into this:
+
+``` rust
+#[rtic::app(/* .. */)]
+const APP: () = {
+ #[task(binds = SVCall)]
+ // ^^^^^^^^^^^^^^
+ fn svcall(cx: svcall::Context) { /* .. */ }
+ // ^^^^^^ we suggest you use a `snake_case` name here
+
+ #[task(binds = UART0)]
+ // ^^^^^^^^^^^^^
+ fn uart0(cx: uart0::Context) { /* .. */ }
+
+ #[task]
+ fn foo(cx: foo::Context) { /* .. */ }
+
+ // ..
+};
+```
+
+## `schedule`
+
+The `schedule` API no longer requires the `timer-queue` cargo feature, which has
+been removed. To use the `schedule` API one must
+first define the monotonic timer the runtime will use using the `monotonic`
+argument of the `#[rtic::app]` attribute. To continue using the cycle counter
+(CYCCNT) as the monotonic timer, and match the behavior of version v0.4.x, add
+the `monotonic = rtic::cyccnt::CYCCNT` argument to the `#[rtic::app]` attribute.
+
+Also, the `Duration` and `Instant` types and the `U32Ext` trait have been moved
+into the `rtic::cyccnt` module. This module is only available on ARMv7-M+
+devices. The removal of the `timer-queue` also brings back the `DWT` peripheral
+inside the core peripherals struct, this will need to be enabled by the application
+inside `init`.
+
+Change this:
+
+``` rust
+use rtic::{Duration, Instant, U32Ext};
+
+#[rtic::app(/* .. */)]
+const APP: () = {
+ #[task(schedule = [b])]
+ fn a() {
+ // ..
+ }
+};
+```
+
+Into this:
+
+``` rust
+use rtic::cyccnt::{Duration, Instant, U32Ext};
+// ^^^^^^^^
+
+#[rtic::app(/* .. */, monotonic = rtic::cyccnt::CYCCNT)]
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+const APP: () = {
+ #[init]
+ fn init(cx: init::Context) {
+ cx.core.DWT.enable_cycle_counter();
+ // optional, configure the DWT run without a debugger connected
+ cx.core.DCB.enable_trace();
+ }
+ #[task(schedule = [b])]
+ fn a(cx: a::Context) {
+ // ..
+ }
+};
+```
diff --git a/book/en/src/migration/migration_v5.md b/book/en/src/migration/migration_v5.md
new file mode 100644
index 00000000..1d83444e
--- /dev/null
+++ b/book/en/src/migration/migration_v5.md
@@ -0,0 +1,96 @@
+# Migrating from v0.5.x to v0.6.0
+
+This section describes how to upgrade from v0.5.x to v0.6.0 of the RTIC framework.
+
+## `Cargo.toml` - version bump
+
+Change the version of `cortex-m-rtic` to `"0.6.0"`.
+
+## Module instead of Const
+
+With the support of attributes on modules the `const APP` workaround is not needed.
+
+Change
+
+``` rust
+#[rtic::app(/* .. */)]
+const APP: () = {
+ [code here]
+};
+```
+
+into
+
+``` rust
+#[rtic::app(/* .. */)]
+mod app {
+ [code here]
+}
+```
+
+Now that a regular Rust module is used it means it is possible to have custom
+user code within that module.
+Additionally, it means that `use`-statements for resources etc may be required.
+
+## Init always returns late resources
+
+In order to make the API more symmetric the #[init]-task always returns a late resource.
+
+From this:
+
+``` rust
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) {
+ rtic::pend(Interrupt::UART0);
+ }
+ [more code]
+}
+```
+
+to this:
+
+``` rust
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+
+ init::LateResources {}
+ }
+ [more code]
+}
+```
+
+## Resources struct - #[resources]
+
+Previously the RTIC resources had to be in in a struct named exactly "Resources":
+
+``` rust
+struct Resources {
+ // Resources defined in here
+}
+```
+
+With RTIC v0.6.0 the resources struct is annotated similarly like
+`#[task]`, `#[init]`, `#[idle]`: with an attribute `#[resources]`
+
+``` rust
+#[resources]
+struct Resources {
+ // Resources defined in here
+}
+```
+
+In fact, the name of the struct is now up to the developer:
+
+``` rust
+#[resources]
+struct whateveryouwant {
+ // Resources defined in here
+}
+```
+
+would work equally well.