aboutsummaryrefslogtreecommitdiff
path: root/book/en
diff options
context:
space:
mode:
authordatdenkikniet <jcdra1@gmail.com>2023-04-22 17:37:15 +0200
committerdatdenkikniet <jcdra1@gmail.com>2023-05-11 19:20:58 +0200
commit1dc2f80eb6cb6ac6d1eaede4169d8cabc51c5e7c (patch)
tree0c86b2a70ec77e9e12b3bf0d764110f235efc804 /book/en
parent16f8ea9ba7d0fed1c9f1622b2e9cbcdbbdd807f5 (diff)
Begin migration guide
Diffstat (limited to 'book/en')
-rw-r--r--book/en/src/SUMMARY.md12
-rw-r--r--book/en/src/migration/migration_v2.md16
-rw-r--r--book/en/src/migration/migration_v2/async_tasks.md55
-rw-r--r--book/en/src/migration/migration_v2/complete_example.md245
-rw-r--r--book/en/src/migration/migration_v2/monotonics.md11
-rw-r--r--book/en/src/migration/migration_v2/nightly.md5
-rw-r--r--book/en/src/migration/migration_v2/rtic-sync.md1
7 files changed, 344 insertions, 1 deletions
diff --git a/book/en/src/SUMMARY.md b/book/en/src/SUMMARY.md
index 587117c..ceed24e 100644
--- a/book/en/src/SUMMARY.md
+++ b/book/en/src/SUMMARY.md
@@ -24,6 +24,7 @@
- [RTIC vs. the world](./rtic_vs.md)
- [Awesome RTIC examples](./awesome_rtic.md)
<!-- - [Migration Guides](./migration.md)
+ - [v1.0.x to v2.0.0](./migration/migration_v2.md)
- [v0.5.x to v1.0.x](./migration/migration_v5.md)
- [v0.4.x to v0.5.x](./migration/migration_v4.md)
- [RTFM to RTIC](./migration/migration_rtic.md) -->
@@ -43,4 +44,13 @@
- [Message passing & `capacity`](./by-example/message_passing.md)
- [Task priorities](./by-example/app_priorities.md)
- [Monotonic & `spawn_{at/after}`](./by-example/monotonic.md)
- --> \ No newline at end of file
+ -->
+
+---
+
+- [Migrating from v1.0.x to v2.0.0](./migration/migration_v2.md)
+ - [Rust Nightly & features](./migration/migration_v2/nightly.md)
+ - [Migrating to `rtic-monotonics`](./migration/migration_v2/monotonics.md)
+ - [Software tasks must now be `async`](./migration/migration_v2/async_tasks.md)
+ - [Using and understanding `rtic-sync`](./migration/migration_v2/rtic-sync.md)
+ - [A code example on migration](./migration/migration_v2/complete_example.md) \ No newline at end of file
diff --git a/book/en/src/migration/migration_v2.md b/book/en/src/migration/migration_v2.md
new file mode 100644
index 0000000..071d34c
--- /dev/null
+++ b/book/en/src/migration/migration_v2.md
@@ -0,0 +1,16 @@
+# 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` to solve migration problems.
+
+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
+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
new file mode 100644
index 0000000..54e0893
--- /dev/null
+++ b/book/en/src/migration/migration_v2/async_tasks.md
@@ -0,0 +1,55 @@
+# 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
new file mode 100644
index 0000000..fec475d
--- /dev/null
+++ b/book/en/src/migration/migration_v2/complete_example.md
@@ -0,0 +1,245 @@
+# 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
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+#![feature(type_alias_impl_trait)]
+
+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 rtic_monotonics::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,
+ }
+
+ #[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_token = rtic_monotonics::create_systick_token!();
+ let mono = Systick::new(cx.core.SYST, 36_000_000, mono_token);
+
+ 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().unwrap();
+
+ (
+ Shared {},
+ Local { led, state: false },
+ init::Monotonics(mono),
+ )
+ }
+
+ #[task(local = [led, state])]
+ 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;
+ }
+ }
+ }
+}
+```
+
+## A diff between the two projects
+
+``` 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
new file mode 100644
index 0000000..f794bec
--- /dev/null
+++ b/book/en/src/migration/migration_v2/monotonics.md
@@ -0,0 +1,11 @@
+# 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 `Monotonic::delay` and `Monotonics::delay_until`. The `Monotonic` trait is provided by `rtic-time`.
+
+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). \ 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
new file mode 100644
index 0000000..09f6e33
--- /dev/null
+++ b/book/en/src/migration/migration_v2/nightly.md
@@ -0,0 +1,5 @@
+# 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
new file mode 100644
index 0000000..d086d5d
--- /dev/null
+++ b/book/en/src/migration/migration_v2/rtic-sync.md
@@ -0,0 +1 @@
+# Using `rtic-sync` \ No newline at end of file