aboutsummaryrefslogtreecommitdiff
path: root/book/en/src/migration
diff options
context:
space:
mode:
authordatdenkikniet <jcdra1@gmail.com>2023-04-22 21:27:26 +0200
committerdatdenkikniet <jcdra1@gmail.com>2023-05-11 19:20:58 +0200
commit3d97c9e431d7fcb20b1b30bc15c34ccffee03c79 (patch)
tree6842b788361e247cc50423bee972cc7a3c6ba974 /book/en/src/migration
parented465b0c3b8b4c588f5cc7945af79a504f928cc8 (diff)
Move deprecated migration guides to deprecated folder
Diffstat (limited to 'book/en/src/migration')
-rw-r--r--book/en/src/migration/migration_rtic.md50
-rw-r--r--book/en/src/migration/migration_v2.md18
-rw-r--r--book/en/src/migration/migration_v2/async_tasks.md55
-rw-r--r--book/en/src/migration/migration_v2/complete_example.md169
-rw-r--r--book/en/src/migration/migration_v2/monotonics.md13
-rw-r--r--book/en/src/migration/migration_v2/nightly.md5
-rw-r--r--book/en/src/migration/migration_v2/rtic-sync.md9
-rw-r--r--book/en/src/migration/migration_v4.md247
-rw-r--r--book/en/src/migration/migration_v5.md372
9 files changed, 0 insertions, 938 deletions
diff --git a/book/en/src/migration/migration_rtic.md b/book/en/src/migration/migration_rtic.md
deleted file mode 100644
index c027da3..0000000
--- a/book/en/src/migration/migration_rtic.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Migrating from RTFM to RTIC
-
-This section covers how to upgrade an application written against RTFM v0.5.x to
-the same version of RTIC. This applies since the renaming of the framework as per [RFC #33].
-
-**Note:** There are no code differences between RTFM v0.5.3 and RTIC v0.5.3, it is purely a name
-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
-cortex-m-rtfm = "0.5.3"
-
-# into this
-cortex-m-rtic = "0.5.3"
-```
-
-## Code changes
-
-The only code change that needs to be made is that any reference to `rtfm` before now need to point
-to `rtic` as follows:
-
-``` rust
-//
-// Change this
-//
-
-#[rtfm::app(/* .. */, monotonic = rtfm::cyccnt::CYCCNT)]
-const APP: () = {
- // ...
-
-};
-
-//
-// Into this
-//
-
-#[rtic::app(/* .. */, monotonic = rtic::cyccnt::CYCCNT)]
-const APP: () = {
- // ...
-
-};
-```
diff --git a/book/en/src/migration/migration_v2.md b/book/en/src/migration/migration_v2.md
deleted file mode 100644
index 96fa231..0000000
--- a/book/en/src/migration/migration_v2.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Migrating from v1.0.x to v2.0.0
-
-Migrating a project from RTIC `v1.0.x` to `v2.0.0` involves the following steps:
-
-1. `v2.0.0` requires [`#![type_alias_impl_trait]`](https://github.com/rust-lang/rust/issues/63063) and Rust Nightly.
-2. Migrating from the monotonics included in `v1.0.x` to `rtic-time` and `rtic-monotonics`, replacing `spawn_after`, `spawn_at`.
-3. Software tasks are now required to be `async`, and using them correctly.
-4. Understanding and using data types provided by `rtic-sync`.
-
-For a detailed description of the changes, refer to the subchapters.
-
-If you wish to see a code example of changes required, you can check out [the full example migration page](./migration_v2/complete_example.md).
-
-#### TL;DR (Too Long; Didn't Read)
-1. Add `#![type_alias_impl_trait]` to your crate, and use `cargo +nightly`.
-2. Instead of `spawn_after` and `spawn_at`, you now use the `async` functions `delay`, `delay_until` (and related) with impls provided by `rtic-monotonics`.
-3. Software tasks _must_ be `async fn`s now. Not returning from a task is allowed so long as there is an `await` in the task. You can still `lock` shared resources.
-4. Use `rtic_sync::Arbiter` to `await` access to a shared resource, and `rtic-channel` to communicate between tasks instead of `spawn`-ing new ones. \ No newline at end of file
diff --git a/book/en/src/migration/migration_v2/async_tasks.md b/book/en/src/migration/migration_v2/async_tasks.md
deleted file mode 100644
index 54e0893..0000000
--- a/book/en/src/migration/migration_v2/async_tasks.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Using `async` softare tasks.
-
-There have been a few changes to software tasks. They are outlined below.
-
-### Software tasks must now be `async`.
-
-All software tasks are now required to be `async`.
-
-#### Required changes.
-
-All of the tasks in your project that do not bind to an interrupt must now be an `async fn`. For example:
-
-``` rust
-#[task(
- local = [ some_resource ],
- shared = [ my_shared_resource ],
- priority = 2
-)]
-fn my_task(cx: my_task::Context) {
- cx.local.some_resource.do_trick();
- cx.shared.my_shared_resource.lock(|s| s.do_shared_thing());
-}
-```
-
-becomes
-
-``` rust
-#[task(
- local = [ some_resource ],
- shared = [ my_shared_resource ],
- priority = 2
-)]
-async fn my_task(cx: my_task::Context) {
- cx.local.some_resource.do_trick();
- cx.shared.my_shared_resource.lock(|s| s.do_shared_thing());
-}
-```
-
-## Software tasks may now run forever
-
-The new `async` software tasks are allowed to run forever, on one precondition: **there must be an `await` within the infinite loop of the task**. An example of such a task:
-
-``` rust
-#[task(local = [ my_channel ] )]
-async fn my_task_that_runs_forever(cx: my_task_that_runs_forever::Context) {
- loop {
- let value = cx.local.my_channel.recv().await;
- do_something_with_value(value);
- }
-}
-```
-
-## `spawn_after` and `spawn_at` have been removed.
-
-As discussed in the [Migrating to `rtic-monotonics`](./monotonics.md) chapter, `spawn_after` and `spawn_at` are no longer available. \ No newline at end of file
diff --git a/book/en/src/migration/migration_v2/complete_example.md b/book/en/src/migration/migration_v2/complete_example.md
deleted file mode 100644
index b68f1ef..0000000
--- a/book/en/src/migration/migration_v2/complete_example.md
+++ /dev/null
@@ -1,169 +0,0 @@
-# A complete example of migration
-
-Below you can find the code for the implementation of the `stm32f3_blinky` example for v1.0.x and for v2.0.0. Further down, a diff is displayed.
-
-# v1.0.X
-
-```rust
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![no_main]
-#![no_std]
-
-use panic_rtt_target as _;
-use rtic::app;
-use rtt_target::{rprintln, rtt_init_print};
-use stm32f3xx_hal::gpio::{Output, PushPull, PA5};
-use stm32f3xx_hal::prelude::*;
-use systick_monotonic::{fugit::Duration, Systick};
-
-#[app(device = stm32f3xx_hal::pac, peripherals = true, dispatchers = [SPI1])]
-mod app {
- use super::*;
-
- #[shared]
- struct Shared {}
-
- #[local]
- struct Local {
- led: PA5<Output<PushPull>>,
- state: bool,
- }
-
- #[monotonic(binds = SysTick, default = true)]
- type MonoTimer = Systick<1000>;
-
- #[init]
- fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
- // Setup clocks
- let mut flash = cx.device.FLASH.constrain();
- let mut rcc = cx.device.RCC.constrain();
-
- let mono = Systick::new(cx.core.SYST, 36_000_000);
-
- rtt_init_print!();
- rprintln!("init");
-
- let _clocks = rcc
- .cfgr
- .use_hse(8.MHz())
- .sysclk(36.MHz())
- .pclk1(36.MHz())
- .freeze(&mut flash.acr);
-
- // Setup LED
- let mut gpioa = cx.device.GPIOA.split(&mut rcc.ahb);
- let mut led = gpioa
- .pa5
- .into_push_pull_output(&mut gpioa.moder, &mut gpioa.otyper);
- led.set_high().unwrap();
-
- // Schedule the blinking task
- blink::spawn_after(Duration::<u64, 1, 1000>::from_ticks(1000)).unwrap();
-
- (
- Shared {},
- Local { led, state: false },
- init::Monotonics(mono),
- )
- }
-
- #[task(local = [led, state])]
- fn blink(cx: blink::Context) {
- rprintln!("blink");
- if *cx.local.state {
- cx.local.led.set_high().unwrap();
- *cx.local.state = false;
- } else {
- cx.local.led.set_low().unwrap();
- *cx.local.state = true;
- }
- blink::spawn_after(Duration::<u64, 1, 1000>::from_ticks(1000)).unwrap();
- }
-}
-
-```
-
-# V2.0.0
-
-``` rust
-{{ #include ../../../../../examples/stm32f3_blinky/src/main.rs }}
-```
-
-## A diff between the two projects
-
-_Note_: This diff may not be 100% accurate, but it displays the important changes.
-
-``` diff
-#![no_main]
- #![no_std]
-+#![feature(type_alias_impl_trait)]
-
- use panic_rtt_target as _;
- use rtic::app;
- use stm32f3xx_hal::gpio::{Output, PushPull, PA5};
- use stm32f3xx_hal::prelude::*;
--use systick_monotonic::{fugit::Duration, Systick};
-+use rtic_monotonics::Systick;
-
- #[app(device = stm32f3xx_hal::pac, peripherals = true, dispatchers = [SPI1])]
- mod app {
-@@ -20,16 +21,14 @@ mod app {
- state: bool,
- }
-
-- #[monotonic(binds = SysTick, default = true)]
-- type MonoTimer = Systick<1000>;
--
- #[init]
- fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
- // Setup clocks
- let mut flash = cx.device.FLASH.constrain();
- let mut rcc = cx.device.RCC.constrain();
-
-- let mono = Systick::new(cx.core.SYST, 36_000_000);
-+ let mono_token = rtic_monotonics::create_systick_token!();
-+ let mono = Systick::new(cx.core.SYST, 36_000_000, mono_token);
-
- let _clocks = rcc
- .cfgr
-@@ -46,7 +45,7 @@ mod app {
- led.set_high().unwrap();
-
- // Schedule the blinking task
-- blink::spawn_after(Duration::<u64, 1, 1000>::from_ticks(1000)).unwrap();
-+ blink::spawn().unwrap();
-
- (
- Shared {},
-@@ -56,14 +55,18 @@ mod app {
- }
-
- #[task(local = [led, state])]
-- fn blink(cx: blink::Context) {
-- rprintln!("blink");
-- if *cx.local.state {
-- cx.local.led.set_high().unwrap();
-- *cx.local.state = false;
-- } else {
-- cx.local.led.set_low().unwrap();
-- *cx.local.state = true;
-- blink::spawn_after(Duration::<u64, 1, 1000>::from_ticks(1000)).unwrap();
-- }
-+ async fn blink(cx: blink::Context) {
-+ loop {
-+ // A task is now allowed to run forever, provided that
-+ // there is an `await` somewhere in the loop.
-+ SysTick::delay(1000.millis()).await;
-+ rprintln!("blink");
-+ if *cx.local.state {
-+ cx.local.led.set_high().unwrap();
-+ *cx.local.state = false;
-+ } else {
-+ cx.local.led.set_low().unwrap();
-+ *cx.local.state = true;
-+ }
-+ }
-+ }
- }
-``` \ No newline at end of file
diff --git a/book/en/src/migration/migration_v2/monotonics.md b/book/en/src/migration/migration_v2/monotonics.md
deleted file mode 100644
index a8b0dba..0000000
--- a/book/en/src/migration/migration_v2/monotonics.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Migrating to `rtic-monotonics`
-
-In previous versions of `rtic`, monotonics were an integral, tightly coupled part of the `#[rtic::app]`. In this new version, [`rtic-monotonics`] provides them in a more decoupled way.
-
-The `#[monotonic]` attribute is no longer used. Instead, you use a `create_X_token` from [`rtic-monotonics`]. An invocation of this macro returns an interrupt registration token, which can be used to construct an instance of your desired monotonic.
-
-`spawn_after` and `spawn_at` are no longer available. Instead, you use the async functions `delay` and `delay_until` provided by ipmlementations of the `rtic_time::Monotonic` trait, available through [`rtic-monotonics`].
-
-Check out the [code example](./complete_example.md) for an overview of the required changes.
-
-For more information on current monotonic implementations, see [the `rtic-monotonics` documentation](https://docs.rs/rtic-monotonics), and [the examples](https://github.com/rtic-rs/rtic/tree/master/examples).
-
-[`rtic-monotonics`]: ghttps://github.com/rtic/rtic-monotonics \ No newline at end of file
diff --git a/book/en/src/migration/migration_v2/nightly.md b/book/en/src/migration/migration_v2/nightly.md
deleted file mode 100644
index 09f6e33..0000000
--- a/book/en/src/migration/migration_v2/nightly.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# RTIC now requires Rust Nightly
-
-The new `async` features require that you use a nightly compiler, and that the feature `type_alias_impl_trait` is enabled for your applications.
-
-To enable this feature, you must add the line `#![type_alias_impl_trait]` to the root file of your project, on the lines below or above where `#![no_std]` and `#![no_main]` are defined. \ No newline at end of file
diff --git a/book/en/src/migration/migration_v2/rtic-sync.md b/book/en/src/migration/migration_v2/rtic-sync.md
deleted file mode 100644
index fefde03..0000000
--- a/book/en/src/migration/migration_v2/rtic-sync.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Using `rtic-sync`
-
-`rtic-sync` provides primitives that can be used for message passing and resource sharing in async context.
-
-The important structs are:
-* The `Arbiter`, which allows you to await access to a shared resource in async contexts without using `lock`.
-* `Channel`, which allows you to communicate between tasks (both `async` and non-`async`).
-
-For more information on these structs, see the [`rtic-sync` docs](https://docs.rs/rtic-sync) \ No newline at end of file
diff --git a/book/en/src/migration/migration_v4.md b/book/en/src/migration/migration_v4.md
deleted file mode 100644
index d1a7ebe..0000000
--- a/book/en/src/migration/migration_v4.md
+++ /dev/null
@@ -1,247 +0,0 @@
-# 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.
-
-## Project name change RTFM -> RTIC
-
-With release [v0.5.2][rtic0.5.2] the name was change to Real-Time Interrupt-driven Concurrency
-
-All occurrences of `RTFM` needs to change to `RTIC`.
-
-See [migration guide RTFM to RTIC](./migration_rtic.md)
-
-[rtic0.5.2]: https://crates.io/crates/cortex-m-rtic/0.5.2
-
-## `Cargo.toml`
-
-Change the version of `cortex-m-rtfm` to
-`"0.5.0"`, change `rtfm` to `rtic`.
-Remove the `timer-queue` feature.
-
-``` toml
-[dependencies.cortex-m-rtfm]
-# change this
-version = "0.4.3"
-
-# into this
-[dependencies.cortex-m-rtic]
-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 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() {
- device.SOME_PERIPHERAL.write(something);
- }
-
- // ..
-};
-```
-
-Into this:
-
-``` rust
-#[rtfm::app(/* .. */, peripherals = true)]
-// ^^^^^^^^^^^^^^^^^^
-const APP: () = {
- #[init]
- fn init(cx: init::Context) {
- // ^^^^^^^^^^^^^^^^^
- cx.device.SOME_PERIPHERAL.write(something);
- // ^^^
- }
-
- // ..
-};
-```
-
-## `#[interrupt]` and `#[exception]`
-
-Remove the attributes `#[interrupt]` and `#[exception]`.
-To declare hardware tasks in v0.5.x use the `#[task]`
-attribute with the `binds` argument instead.
-
-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 `schedule` API no longer requires the `timer-queue` cargo feature.
-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 moved
-into the `rtfm::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, if `DWT` is required,
-ensure it is enabled by the application inside `init`.
-
-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: () = {
- #[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
deleted file mode 100644
index 5a8fabc..0000000
--- a/book/en/src/migration/migration_v5.md
+++ /dev/null
@@ -1,372 +0,0 @@
-# Migrating from v0.5.x to v1.0.0
-
-This section describes how to upgrade from v0.5.x to v1.0.0 of the RTIC framework.
-
-## `Cargo.toml` - version bump
-
-Change the version of `cortex-m-rtic` to `"1.0.0"`.
-
-## `mod` 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 used in user
-code must be moved inside `mod app`, or be referred to with `super`. For
-example, change:
-
-```rust
-use some_crate::some_func;
-
-#[rtic::app(/* .. */)]
-const APP: () = {
- fn func() {
- some_crate::some_func();
- }
-};
-```
-
-into
-
-```rust
-#[rtic::app(/* .. */)]
-mod app {
- use some_crate::some_func;
-
- fn func() {
- some_crate::some_func();
- }
-}
-```
-
-or
-
-```rust
-use some_crate::some_func;
-
-#[rtic::app(/* .. */)]
-mod app {
- fn func() {
- super::some_crate::some_func();
- }
-}
-```
-
-## Move Dispatchers from `extern "C"` to app arguments
-
-Change
-
-``` rust
-#[rtic::app(/* .. */)]
-const APP: () = {
- [code here]
-
- // RTIC requires that unused interrupts are declared in an extern block when
- // using software tasks; these free interrupts will be used to dispatch the
- // software tasks.
- extern "C" {
- fn SSI0();
- fn QEI0();
- }
-};
-```
-
-into
-
-``` rust
-#[rtic::app(/* .. */, dispatchers = [SSI0, QEI0])]
-mod app {
- [code here]
-}
-```
-
-This works also for ram functions, see examples/ramfunc.rs
-
-
-## Resources structs - `#[shared]`, `#[local]`
-
-Previously the RTIC resources had to be in in a struct named exactly "Resources":
-
-``` rust
-struct Resources {
- // Resources defined in here
-}
-```
-
-With RTIC v1.0.0 the resources structs are annotated similarly like
-`#[task]`, `#[init]`, `#[idle]`: with the attributes `#[shared]` and `#[local]`
-
-``` rust
-#[shared]
-struct MySharedResources {
- // Resources shared between tasks are defined here
-}
-
-#[local]
-struct MyLocalResources {
- // Resources defined here cannot be shared between tasks; each one is local to a single task
-}
-```
-
-These structs can be freely named by the developer.
-
-## `shared` and `local` arguments in `#[task]`s
-
-In v1.0.0 resources are split between `shared` resources and `local` resources.
-`#[task]`, `#[init]` and `#[idle]` no longer have a `resources` argument; they must now use the `shared` and `local` arguments.
-
-In v0.5.x:
-
-``` rust
-struct Resources {
- local_to_b: i64,
- shared_by_a_and_b: i64,
-}
-
-#[task(resources = [shared_by_a_and_b])]
-fn a(_: a::Context) {}
-
-#[task(resources = [shared_by_a_and_b, local_to_b])]
-fn b(_: b::Context) {}
-```
-
-In v1.0.0:
-
-``` rust
-#[shared]
-struct Shared {
- shared_by_a_and_b: i64,
-}
-
-#[local]
-struct Local {
- local_to_b: i64,
-}
-
-#[task(shared = [shared_by_a_and_b])]
-fn a(_: a::Context) {}
-
-#[task(shared = [shared_by_a_and_b], local = [local_to_b])]
-fn b(_: b::Context) {}
-```
-
-## Symmetric locks
-
-Now RTIC utilizes symmetric locks, this means that the `lock` method need
-to be used for all `shared` resource access.
-In old code one could do the following as the high priority
-task has exclusive access to the resource:
-
-``` rust
-#[task(priority = 2, resources = [r])]
-fn foo(cx: foo::Context) {
- cx.resources.r = /* ... */;
-}
-
-#[task(resources = [r])]
-fn bar(cx: bar::Context) {
- cx.resources.r.lock(|r| r = /* ... */);
-}
-```
-
-And with symmetric locks one needs to use locks in both tasks:
-
-``` rust
-#[task(priority = 2, shared = [r])]
-fn foo(cx: foo::Context) {
- cx.shared.r.lock(|r| r = /* ... */);
-}
-
-#[task(shared = [r])]
-fn bar(cx: bar::Context) {
- cx.shared.r.lock(|r| r = /* ... */);
-}
-```
-
-Note that the performance does not change thanks to LLVM's optimizations which optimizes away unnecessary locks.
-
-## Lock-free resource access
-
-In RTIC 0.5 resources shared by tasks running at the same priority could be accessed *without* the `lock` API.
-This is still possible in 1.0: the `#[shared]` resource must be annotated with the field-level `#[lock_free]` attribute.
-
-v0.5 code:
-
-``` rust
-struct Resources {
- counter: u64,
-}
-
-#[task(resources = [counter])]
-fn a(cx: a::Context) {
- *cx.resources.counter += 1;
-}
-
-#[task(resources = [counter])]
-fn b(cx: b::Context) {
- *cx.resources.counter += 1;
-}
-```
-
-v1.0 code:
-
-``` rust
-#[shared]
-struct Shared {
- #[lock_free]
- counter: u64,
-}
-
-#[task(shared = [counter])]
-fn a(cx: a::Context) {
- *cx.shared.counter += 1;
-}
-
-#[task(shared = [counter])]
-fn b(cx: b::Context) {
- *cx.shared.counter += 1;
-}
-```
-
-## no `static mut` transform
-
-`static mut` variables are no longer transformed to safe `&'static mut` references.
-Instead of that syntax, use the `local` argument in `#[init]`.
-
-v0.5.x code:
-
-``` rust
-#[init]
-fn init(_: init::Context) {
- static mut BUFFER: [u8; 1024] = [0; 1024];
- let buffer: &'static mut [u8; 1024] = BUFFER;
-}
-```
-
-v1.0.0 code:
-
-``` rust
-#[init(local = [
- buffer: [u8; 1024] = [0; 1024]
-// type ^^^^^^^^^^^^ ^^^^^^^^^ initial value
-])]
-fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
- let buffer: &'static mut [u8; 1024] = cx.local.buffer;
-
- (Shared {}, Local {}, init::Monotonics())
-}
-```
-
-## 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)]
-const APP: () = {
- #[init]
- fn init(_: init::Context) {
- rtic::pend(Interrupt::UART0);
- }
-
- // [more code]
-};
-```
-
-to this:
-
-``` rust
-#[rtic::app(device = lm3s6965)]
-mod app {
- #[shared]
- struct MySharedResources {}
-
- #[local]
- struct MyLocalResources {}
-
- #[init]
- fn init(_: init::Context) -> (MySharedResources, MyLocalResources, init::Monotonics) {
- rtic::pend(Interrupt::UART0);
-
- (MySharedResources, MyLocalResources, init::Monotonics())
- }
-
- // [more code]
-}
-```
-
-## Spawn from anywhere
-
-With the new spawn/spawn_after/spawn_at interface,
-old code requiring the context `cx` for spawning such as:
-
-``` rust
-#[task(spawn = [bar])]
-fn foo(cx: foo::Context) {
- cx.spawn.bar().unwrap();
-}
-
-#[task(schedule = [bar])]
-fn bar(cx: bar::Context) {
- cx.schedule.foo(/* ... */).unwrap();
-}
-```
-
-Will now be written as:
-
-``` rust
-#[task]
-fn foo(_c: foo::Context) {
- bar::spawn().unwrap();
-}
-
-#[task]
-fn bar(_c: bar::Context) {
- // Takes a Duration, relative to “now”
- let spawn_handle = foo::spawn_after(/* ... */);
-}
-
-#[task]
-fn bar(_c: bar::Context) {
- // Takes an Instant
- let spawn_handle = foo::spawn_at(/* ... */);
-}
-```
-
-Thus the requirement of having access to the context is dropped.
-
-Note that the attributes `spawn`/`schedule` in the task definition are no longer needed.
-
----
-
-## Additions
-
-### Extern tasks
-
-Both software and hardware tasks can now be defined external to the `mod app`.
-Previously this was possible only by implementing a trampoline calling out the task implementation.
-
-See examples `examples/extern_binds.rs` and `examples/extern_spawn.rs`.
-
-This enables breaking apps into multiple files.