aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bors[bot] <26634292+bors[bot]@users.noreply.github.com> 2019-10-17 06:16:43 +0000
committerGravatar GitHub <noreply@github.com> 2019-10-17 06:16:43 +0000
commite82fb497f091e7e182ae349baf7dd3c225cd18bf (patch)
treef9ecad666d36be55fcfcaf5eb1936a9c10f5fe37
parent47e4d999072ade9447616a91fbce61561810c75b (diff)
parent4b61c345eb93a06bf393e0f1f839bce421dc35da (diff)
downloadrtic-e82fb497f091e7e182ae349baf7dd3c225cd18bf.tar.gz
rtic-e82fb497f091e7e182ae349baf7dd3c225cd18bf.tar.zst
rtic-e82fb497f091e7e182ae349baf7dd3c225cd18bf.zip
Merge #256
256: add migration guide r=korken89 a=japaric Co-authored-by: Jorge Aparicio <jorge@japaric.io>
Diffstat (limited to '')
-rw-r--r--book/en/src/SUMMARY.md1
-rw-r--r--book/en/src/migration.md225
2 files changed, 226 insertions, 0 deletions
diff --git a/book/en/src/SUMMARY.md b/book/en/src/SUMMARY.md
index 8b626336..3d5a4f8e 100644
--- a/book/en/src/SUMMARY.md
+++ b/book/en/src/SUMMARY.md
@@ -9,6 +9,7 @@
- [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)
- [Under the hood](./internals.md)
- [Interrupt configuration](./internals/interrupt-configuration.md)
- [Non-reentrancy](./internals/non-reentrancy.md)
diff --git a/book/en/src/migration.md b/book/en/src/migration.md
new file mode 100644
index 00000000..dd0092d9
--- /dev/null
+++ b/book/en/src/migration.md
@@ -0,0 +1,225 @@
+# Migrating from v0.4.x to v0.5.0
+
+This section covers how to upgrade an application written against RTFM v0.4.x to
+the version v0.5.0 of the framework.
+
+## `Cargo.toml`
+
+First, the version of the `cortex-m-rtfm` dependency needs to be updated to
+`"0.5.0"`. The `timer-queue` feature needs to be removed.
+
+
+``` toml
+[dependencies.cortex-m-rtfm]
+# 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 `#[rtfm::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 `#[rtfm::app]` item
+gets a different `Context` type.
+
+``` rust
+#[rtfm::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
+#[rtfm::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
+`#[rtfm::app]` attribute to continue to access the device peripherals through
+the `device` field of the `init::Context` structure.
+
+Change this:
+
+``` rust
+#[rtfm::app(/* .. */)]
+const APP: () = {
+ #[init]
+ fn init() {
+ peripherals.SOME_PERIPHERAL.write(something);
+ }
+
+ // ..
+};
+```
+
+Into this:
+
+``` rust
+#[rtfm::app(/* .. */, peripherals = true)]
+// ^^^^^^^^^^^^^^^^^^
+const APP: () = {
+ #[init]
+ fn init(cx: init::Context) {
+ // ^^^^^^^^^^^^^^^^^
+ cx.peripherals.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
+#[rtfm::app(/* .. */)]
+const APP: () = {
+ // hardware tasks
+ #[exception]
+ fn SVCall() { /* .. */ }
+
+ #[interrupt]
+ fn UART0() { /* .. */ }
+
+ // software task
+ #[task]
+ fn foo() { /* .. */ }
+
+ // ..
+};
+```
+
+Into this:
+
+``` rust
+#[rtfm::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 `#[rtfm::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 = rtfm::cyccnt::CYCCNT` argument to the `#[rtfm::app]` attribute.
+
+Also, the `Duration` and `Instant` types and the `U32Ext` trait have been moved
+into the `rtfm::cyccnt` module. This module is only available on ARMv7-M+
+devices.
+
+Change this:
+
+``` rust
+use rtfm::{Duration, Instant, U32Ext};
+
+#[rtfm::app(/* .. */)]
+const APP: () = {
+ #[task(schedule = [b])]
+ fn a() {
+ // ..
+ }
+};
+```
+
+Into this:
+
+``` rust
+use rtfm::cyccnt::{Duration, Instant, U32Ext};
+// ^^^^^^^^
+
+#[rtfm::app(/* .. */, monotonic = rtfm::cyccnt::CYCCNT)]
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+const APP: () = {
+ #[task(schedule = [b])]
+ fn a(cx: a::Context) {
+ // ..
+ }
+};
+```