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
#![allow(unused)] #![deny(unsafe_code)] #![deny(warnings)] #![no_main] #![no_std] fn main() { 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
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
use panic_rtt_target as _;
use rtic::app;
use rtic_monotonics::systick::prelude::*;
use rtt_target::{rprintln, rtt_init_print};
use stm32f3xx_hal::gpio::{Output, PushPull, PA5};
use stm32f3xx_hal::prelude::*;
systick_monotonic!(Mono, 1000);
#[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) {
// Setup clocks
let mut flash = cx.device.FLASH.constrain();
let mut rcc = cx.device.RCC.constrain();
// Initialize the systick interrupt & obtain the token to prove that we did
Mono::start(cx.core.SYST, 36_000_000); // default STM32F303 clock-rate is 36MHz
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().ok();
(Shared {}, Local { led, state: false })
}
#[task(local = [led, state])]
async fn blink(cx: blink::Context) {
loop {
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;
}
Mono::delay(1000.millis()).await;
}
}
}
A diff between the two projects
Note: This diff may not be 100% accurate, but it displays the important changes.
#![no_main]
#![no_std]
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::start(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;
+ }
+ }
+ }
}