mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-01 16:04:33 +01:00
Merge #383
383: Split up migration guides into its own sections r=AfoHT a=korken89 Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
This commit is contained in:
commit
29d10766d3
5 changed files with 335 additions and 332 deletions
|
@ -10,8 +10,10 @@
|
||||||
- [Types, Send and Sync](./by-example/types-send-sync.md)
|
- [Types, Send and Sync](./by-example/types-send-sync.md)
|
||||||
- [Starting a new project](./by-example/new.md)
|
- [Starting a new project](./by-example/new.md)
|
||||||
- [Tips & tricks](./by-example/tips.md)
|
- [Tips & tricks](./by-example/tips.md)
|
||||||
- [Migrating from v0.4.x to v0.5.0](./migration.md)
|
- [Migration Guides](./migration.md)
|
||||||
- [Migrating from RTFM to RTIC](./migration_rtic.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)
|
- [Under the hood](./internals.md)
|
||||||
- [Interrupt configuration](./internals/interrupt-configuration.md)
|
- [Interrupt configuration](./internals/interrupt-configuration.md)
|
||||||
- [Non-reentrancy](./internals/non-reentrancy.md)
|
- [Non-reentrancy](./internals/non-reentrancy.md)
|
||||||
|
|
|
@ -1,331 +1,4 @@
|
||||||
# Migration of RTIC
|
# Migration Guides
|
||||||
|
|
||||||
## Migrating from v0.5.x to v0.6.0
|
This section describes how to migrate between different version of RTIC.
|
||||||
|
It also acts as a comparing reference between versions.
|
||||||
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) {
|
|
||||||
// ..
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
232
book/en/src/migration/migration_v4.md
Normal file
232
book/en/src/migration/migration_v4.md
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
# 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) {
|
||||||
|
// ..
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
96
book/en/src/migration/migration_v5.md
Normal file
96
book/en/src/migration/migration_v5.md
Normal file
|
@ -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.
|
Loading…
Reference in a new issue