aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/baseline.rs39
-rw-r--r--examples/binds.rs28
-rw-r--r--examples/capacity.rs40
-rw-r--r--examples/cfg.rs58
-rw-r--r--examples/destructure.rs50
-rw-r--r--examples/double_schedule.rs39
-rw-r--r--examples/generics.rs54
-rw-r--r--examples/hardware.rs (renamed from examples/interrupt.rs)30
-rw-r--r--examples/idle.rs20
-rw-r--r--examples/init.rs22
-rw-r--r--examples/late.rs49
-rw-r--r--examples/lock.rs50
-rw-r--r--examples/message.rs33
-rw-r--r--examples/not-send.rs50
-rw-r--r--examples/not-sync.rs40
-rw-r--r--examples/only-shared-access.rs39
-rw-r--r--examples/periodic.rs31
-rw-r--r--examples/peripherals-taken.rs18
-rw-r--r--examples/pool.rs76
-rw-r--r--examples/preempt.rs39
-rw-r--r--examples/ramfunc.rs22
-rw-r--r--examples/resource-user-struct.rs63
-rw-r--r--examples/resource.rs60
-rw-r--r--examples/schedule.rs39
-rw-r--r--examples/shared-with-init.rs45
-rw-r--r--examples/singleton.rs61
-rw-r--r--examples/smallest.rs13
-rw-r--r--examples/static.rs37
-rw-r--r--examples/t-binds.rs34
-rw-r--r--examples/t-cfg-resources.rs36
-rw-r--r--examples/t-cfg.rs58
-rw-r--r--examples/t-htask-main.rs22
-rw-r--r--examples/t-idle-main.rs23
-rw-r--r--examples/t-init-main.rs17
-rw-r--r--examples/t-late-not-send.rs41
-rw-r--r--examples/t-resource.rs92
-rw-r--r--examples/t-schedule.rs66
-rw-r--r--examples/t-spawn.rs65
-rw-r--r--examples/t-stask-main.rs29
-rw-r--r--examples/task.rs40
-rw-r--r--examples/types.rs75
41 files changed, 1303 insertions, 440 deletions
diff --git a/examples/baseline.rs b/examples/baseline.rs
index fdf3683..3ab40db 100644
--- a/examples/baseline.rs
+++ b/examples/baseline.rs
@@ -5,47 +5,52 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::app;
+use panic_semihosting as _;
// NOTE: does NOT properly work on QEMU
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
#[init(spawn = [foo])]
- fn init() {
- hprintln!("init(baseline = {:?})", start).unwrap();
+ fn init(cx: init::Context) -> init::LateResources {
+ // omitted: initialization of `CYCCNT`
+
+ hprintln!("init(baseline = {:?})", cx.start).unwrap();
// `foo` inherits the baseline of `init`: `Instant(0)`
- spawn.foo().unwrap();
+ cx.spawn.foo().unwrap();
+
+ init::LateResources {}
}
#[task(schedule = [foo])]
- fn foo() {
+ fn foo(cx: foo::Context) {
static mut ONCE: bool = true;
- hprintln!("foo(baseline = {:?})", scheduled).unwrap();
+ hprintln!("foo(baseline = {:?})", cx.scheduled).unwrap();
if *ONCE {
*ONCE = false;
- rtfm::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART0);
} else {
debug::exit(debug::EXIT_SUCCESS);
}
}
- #[interrupt(spawn = [foo])]
- fn UART0() {
- hprintln!("UART0(baseline = {:?})", start).unwrap();
+ #[task(binds = UART0, spawn = [foo])]
+ fn uart0(cx: uart0::Context) {
+ hprintln!("UART0(baseline = {:?})", cx.start).unwrap();
// `foo` inherits the baseline of `UART0`: its `start` time
- spawn.foo().unwrap();
+ cx.spawn.foo().unwrap();
}
+ // 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 UART1();
+ fn SSI0();
}
-};
+}
diff --git a/examples/binds.rs b/examples/binds.rs
index a8b386f..42010ae 100644
--- a/examples/binds.rs
+++ b/examples/binds.rs
@@ -5,35 +5,37 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::app;
+use panic_semihosting as _;
// `examples/interrupt.rs` rewritten to use `binds`
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init]
- fn init() {
- rtfm::pend(Interrupt::UART0);
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
hprintln!("init").unwrap();
+
+ init::LateResources {}
}
#[idle]
- fn idle() -> ! {
+ fn idle(_: idle::Context) -> ! {
hprintln!("idle").unwrap();
- rtfm::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART0);
debug::exit(debug::EXIT_SUCCESS);
- loop {}
+ loop {
+ cortex_m::asm::nop();
+ }
}
- #[interrupt(binds = UART0)]
- fn foo() {
+ #[task(binds = UART0)]
+ fn foo(_: foo::Context) {
static mut TIMES: u32 = 0;
*TIMES += 1;
@@ -45,4 +47,4 @@ const APP: () = {
)
.unwrap();
}
-};
+}
diff --git a/examples/capacity.rs b/examples/capacity.rs
index a7132ba..ba8b15b 100644
--- a/examples/capacity.rs
+++ b/examples/capacity.rs
@@ -5,43 +5,45 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init]
- fn init() {
- rtfm::pend(Interrupt::UART0);
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+
+ init::LateResources {}
}
- #[interrupt(spawn = [foo, bar])]
- fn UART0() {
- spawn.foo(0).unwrap();
- spawn.foo(1).unwrap();
- spawn.foo(2).unwrap();
- spawn.foo(3).unwrap();
+ #[task(binds = UART0, spawn = [foo, bar])]
+ fn uart0(c: uart0::Context) {
+ c.spawn.foo(0).unwrap();
+ c.spawn.foo(1).unwrap();
+ c.spawn.foo(2).unwrap();
+ c.spawn.foo(3).unwrap();
- spawn.bar().unwrap();
+ c.spawn.bar().unwrap();
}
#[task(capacity = 4)]
- fn foo(x: u32) {
+ fn foo(_: foo::Context, x: u32) {
hprintln!("foo({})", x).unwrap();
}
#[task]
- fn bar() {
+ fn bar(_: bar::Context) {
hprintln!("bar").unwrap();
debug::exit(debug::EXIT_SUCCESS);
}
- // Interrupt handlers used to dispatch software tasks
+ // 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 UART1();
+ fn SSI0();
}
-};
+}
diff --git a/examples/cfg.rs b/examples/cfg.rs
index 3f4ca90..d49f54c 100644
--- a/examples/cfg.rs
+++ b/examples/cfg.rs
@@ -5,40 +5,55 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
+use cortex_m_semihosting::debug;
#[cfg(debug_assertions)]
use cortex_m_semihosting::hprintln;
-use rtfm::app;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ #[cfg(debug_assertions)] // <- `true` when using the `dev` profile
+ #[init(0)]
+ count: u32,
+ }
-#[app(device = lm3s6965)]
-const APP: () = {
- #[cfg(debug_assertions)] // <- `true` when using the `dev` profile
- static mut COUNT: u32 = 0;
+ #[init(spawn = [foo])]
+ fn init(cx: init::Context) -> init::LateResources {
+ cx.spawn.foo().unwrap();
+ cx.spawn.foo().unwrap();
- #[init]
- fn init() {
- // ..
+ init::LateResources {}
+ }
+
+ #[idle]
+ fn idle(_: idle::Context) -> ! {
+ debug::exit(debug::EXIT_SUCCESS);
+
+ loop {
+ cortex_m::asm::nop();
+ }
}
- #[task(priority = 3, resources = [COUNT], spawn = [log])]
- fn foo() {
+ #[task(capacity = 2, resources = [count], spawn = [log])]
+ fn foo(_cx: foo::Context) {
#[cfg(debug_assertions)]
{
- *resources.COUNT += 1;
+ *_cx.resources.count += 1;
- spawn.log(*resources.COUNT).ok();
+ _cx.spawn.log(*_cx.resources.count).unwrap();
}
// this wouldn't compile in `release` mode
- // *resources.COUNT += 1;
+ // *_cx.resources.count += 1;
// ..
}
#[cfg(debug_assertions)]
- #[task]
- fn log(n: u32) {
+ #[task(capacity = 2)]
+ fn log(_: log::Context, n: u32) {
hprintln!(
"foo has been called {} time{}",
n,
@@ -47,8 +62,11 @@ const APP: () = {
.ok();
}
+ // 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 UART0();
- fn UART1();
+ fn SSI0();
+ fn QEI0();
}
-};
+}
diff --git a/examples/destructure.rs b/examples/destructure.rs
new file mode 100644
index 0000000..e7c5323
--- /dev/null
+++ b/examples/destructure.rs
@@ -0,0 +1,50 @@
+//! examples/destructure.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::hprintln;
+use lm3s6965::Interrupt;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ // Some resources to work with
+ #[init(0)]
+ a: u32,
+ #[init(0)]
+ b: u32,
+ #[init(0)]
+ c: u32,
+ }
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
+
+ init::LateResources {}
+ }
+
+ // Direct destructure
+ #[task(binds = UART0, resources = [a, b, c])]
+ fn uart0(cx: uart0::Context) {
+ let a = cx.resources.a;
+ let b = cx.resources.b;
+ let c = cx.resources.c;
+
+ hprintln!("UART0: a = {}, b = {}, c = {}", a, b, c).unwrap();
+ }
+
+ // De-structure-ing syntax
+ #[task(binds = UART1, resources = [a, b, c])]
+ fn uart1(cx: uart1::Context) {
+ let uart1::Resources { a, b, c } = cx.resources;
+
+ hprintln!("UART0: a = {}, b = {}, c = {}", a, b, c).unwrap();
+ }
+}
diff --git a/examples/double_schedule.rs b/examples/double_schedule.rs
new file mode 100644
index 0000000..b1b78b8
--- /dev/null
+++ b/examples/double_schedule.rs
@@ -0,0 +1,39 @@
+//! examples/double_schedule.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use panic_semihosting as _;
+use rtic::cyccnt::U32Ext;
+
+#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
+
+ #[resources]
+ struct Resources {
+ nothing: (),
+ }
+
+ #[init(spawn = [task1])]
+ fn init(cx: init::Context) -> init::LateResources {
+ cx.spawn.task1().ok();
+
+ init::LateResources { nothing: () }
+ }
+
+ #[task(schedule = [task2])]
+ fn task1(_cx: task1::Context) {
+ _cx.schedule.task2(_cx.scheduled + 100.cycles()).ok();
+ }
+
+ #[task(schedule = [task1])]
+ fn task2(_cx: task2::Context) {
+ _cx.schedule.task1(_cx.scheduled + 100.cycles()).ok();
+ }
+
+ extern "C" {
+ fn SSI0();
+ }
+}
diff --git a/examples/generics.rs b/examples/generics.rs
index c8ce839..3107dd1 100644
--- a/examples/generics.rs
+++ b/examples/generics.rs
@@ -5,58 +5,64 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::{app, Mutex};
-
-#[app(device = lm3s6965)]
-const APP: () = {
- static mut SHARED: u32 = 0;
+use panic_semihosting as _;
+use rtic::{Exclusive, Mutex};
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ #[init(0)]
+ shared: u32,
+ }
#[init]
- fn init() {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
+
+ init::LateResources {}
}
- #[interrupt(resources = [SHARED])]
- fn UART0() {
+ #[task(binds = UART0, resources = [shared])]
+ fn uart0(c: uart0::Context) {
static mut STATE: u32 = 0;
hprintln!("UART0(STATE = {})", *STATE).unwrap();
- advance(STATE, resources.SHARED);
+ // second argument has type `resources::shared`
+ advance(STATE, c.resources.shared);
- rtfm::pend(Interrupt::UART1);
+ rtic::pend(Interrupt::UART1);
debug::exit(debug::EXIT_SUCCESS);
}
- #[interrupt(priority = 2, resources = [SHARED])]
- fn UART1() {
+ #[task(binds = UART1, priority = 2, resources = [shared])]
+ fn uart1(c: uart1::Context) {
static mut STATE: u32 = 0;
hprintln!("UART1(STATE = {})", *STATE).unwrap();
- // just to show that `SHARED` can be accessed directly and ..
- *resources.SHARED += 0;
- // .. also through a (no-op) `lock`
- resources.SHARED.lock(|shared| *shared += 0);
+ // just to show that `shared` can be accessed directly
+ *c.resources.shared += 0;
- advance(STATE, resources.SHARED);
+ // second argument has type `Exclusive<u32>`
+ advance(STATE, Exclusive(c.resources.shared));
}
-};
+}
+// the second parameter is generic: it can be any type that implements the `Mutex` trait
fn advance(state: &mut u32, mut shared: impl Mutex<T = u32>) {
*state += 1;
- let (old, new) = shared.lock(|shared| {
+ let (old, new) = shared.lock(|shared: &mut u32| {
let old = *shared;
*shared += *state;
(old, *shared)
});
- hprintln!("SHARED: {} -> {}", old, new).unwrap();
+ hprintln!("shared: {} -> {}", old, new).unwrap();
}
diff --git a/examples/interrupt.rs b/examples/hardware.rs
index 3c669d9..f6a2d37 100644
--- a/examples/interrupt.rs
+++ b/examples/hardware.rs
@@ -1,42 +1,44 @@
-//! examples/interrupt.rs
+//! examples/hardware.rs
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init]
- fn init() {
+ fn init(_: init::Context) -> init::LateResources {
// Pends the UART0 interrupt but its handler won't run until *after*
// `init` returns because interrupts are disabled
- rtfm::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend
hprintln!("init").unwrap();
+
+ init::LateResources {}
}
#[idle]
- fn idle() -> ! {
+ fn idle(_: idle::Context) -> ! {
// interrupts are enabled again; the `UART0` handler runs at this point
hprintln!("idle").unwrap();
- rtfm::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART0);
debug::exit(debug::EXIT_SUCCESS);
- loop {}
+ loop {
+ cortex_m::asm::nop();
+ }
}
- #[interrupt]
- fn UART0() {
+ #[task(binds = UART0)]
+ fn uart0(_: uart0::Context) {
static mut TIMES: u32 = 0;
// Safe access to local `static mut` variable
@@ -49,4 +51,4 @@ const APP: () = {
)
.unwrap();
}
-};
+}
diff --git a/examples/idle.rs b/examples/idle.rs
index 1f21a37..58c3c87 100644
--- a/examples/idle.rs
+++ b/examples/idle.rs
@@ -5,20 +5,20 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init]
- fn init() {
+ fn init(_: init::Context) -> init::LateResources {
hprintln!("init").unwrap();
+
+ init::LateResources {}
}
#[idle]
- fn idle() -> ! {
+ fn idle(_: idle::Context) -> ! {
static mut X: u32 = 0;
// Safe access to local `static mut` variable
@@ -28,6 +28,8 @@ const APP: () = {
debug::exit(debug::EXIT_SUCCESS);
- loop {}
+ loop {
+ cortex_m::asm::nop();
+ }
}
-};
+}
diff --git a/examples/init.rs b/examples/init.rs
index be6cfe3..6ac284a 100644
--- a/examples/init.rs
+++ b/examples/init.rs
@@ -5,28 +5,32 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965, peripherals = true)]
+mod app {
#[init]
- fn init() {
+ fn init(cx: init::Context) -> init::LateResources {
static mut X: u32 = 0;
// Cortex-M peripherals
- let _core: rtfm::Peripherals = core;
+ let _core: cortex_m::Peripherals = cx.core;
// Device specific peripherals
- let _device: lm3s6965::Peripherals = device;
+ let _device: lm3s6965::Peripherals = cx.device;
// Safe access to local `static mut` variable
let _x: &'static mut u32 = X;
+ // Access to the critical section token,
+ // to indicate that this is a critical seciton
+ let _cs_token: bare_metal::CriticalSection = cx.cs;
+
hprintln!("init").unwrap();
debug::exit(debug::EXIT_SUCCESS);
+
+ init::LateResources {}
}
-};
+}
diff --git a/examples/late.rs b/examples/late.rs
index 622008a..761c68f 100644
--- a/examples/late.rs
+++ b/examples/late.rs
@@ -5,50 +5,53 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use heapless::{
consts::*,
+ i,
spsc::{Consumer, Producer, Queue},
};
use lm3s6965::Interrupt;
-use rtfm::app;
-
-#[app(device = lm3s6965)]
-const APP: () = {
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ use heapless::{
+ consts::*,
+ spsc::{Consumer, Producer},
+ };
// Late resources
- static mut P: Producer<'static, u32, U4> = ();
- static mut C: Consumer<'static, u32, U4> = ();
+ #[resources]
+ struct Resources {
+ p: Producer<'static, u32, U4>,
+ c: Consumer<'static, u32, U4>,
+ }
#[init]
- fn init() -> init::LateResources {
- // NOTE: we use `Option` here to work around the lack of
- // a stable `const` constructor
- static mut Q: Option<Queue<u32, U4>> = None;
+ fn init(_: init::Context) -> init::LateResources {
+ static mut Q: Queue<u32, U4> = Queue(i::Queue::new());
- *Q = Some(Queue::new());
- let (p, c) = Q.as_mut().unwrap().split();
+ let (p, c) = Q.split();
// Initialization of late resources
- init::LateResources { P: p, C: c }
+ init::LateResources { p, c }
}
- #[idle(resources = [C])]
- fn idle() -> ! {
+ #[idle(resources = [c])]
+ fn idle(c: idle::Context) -> ! {
loop {
- if let Some(byte) = resources.C.dequeue() {
+ if let Some(byte) = c.resources.c.dequeue() {
hprintln!("received message: {}", byte).unwrap();
debug::exit(debug::EXIT_SUCCESS);
} else {
- rtfm::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART0);
}
}
}
- #[interrupt(resources = [P])]
- fn UART0() {
- resources.P.enqueue(42).unwrap();
+ #[task(binds = UART0, resources = [p])]
+ fn uart0(c: uart0::Context) {
+ c.resources.p.enqueue(42).unwrap();
}
-};
+}
diff --git a/examples/lock.rs b/examples/lock.rs
index 4ca862e..669b1ae 100644
--- a/examples/lock.rs
+++ b/examples/lock.rs
@@ -5,38 +5,42 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::app;
-
-#[app(device = lm3s6965)]
-const APP: () = {
- static mut SHARED: u32 = 0;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ #[init(0)]
+ shared: u32,
+ }
#[init]
- fn init() {
- rtfm::pend(Interrupt::GPIOA);
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::GPIOA);
+
+ init::LateResources {}
}
// when omitted priority is assumed to be `1`
- #[interrupt(resources = [SHARED])]
- fn GPIOA() {
+ #[task(binds = GPIOA, resources = [shared])]
+ fn gpioa(mut c: gpioa::Context) {
hprintln!("A").unwrap();
// the lower priority task requires a critical section to access the data
- resources.SHARED.lock(|shared| {
+ c.resources.shared.lock(|shared| {
// data can only be modified within this critical section (closure)
*shared += 1;
// GPIOB will *not* run right now due to the critical section
- rtfm::pend(Interrupt::GPIOB);
+ rtic::pend(Interrupt::GPIOB);
- hprintln!("B - SHARED = {}", *shared).unwrap();
+ hprintln!("B - shared = {}", *shared).unwrap();
- // GPIOC does not contend for `SHARED` so it's allowed to run now
- rtfm::pend(Interrupt::GPIOC);
+ // GPIOC does not contend for `shared` so it's allowed to run now
+ rtic::pend(Interrupt::GPIOC);
});
// critical section is over: GPIOB can now start
@@ -46,16 +50,16 @@ const APP: () = {
debug::exit(debug::EXIT_SUCCESS);
}
- #[interrupt(priority = 2, resources = [SHARED])]
- fn GPIOB() {
+ #[task(binds = GPIOB, priority = 2, resources = [shared])]
+ fn gpiob(c: gpiob::Context) {
// the higher priority task does *not* need a critical section
- *resources.SHARED += 1;
+ *c.resources.shared += 1;
- hprintln!("D - SHARED = {}", *resources.SHARED).unwrap();
+ hprintln!("D - shared = {}", *c.resources.shared).unwrap();
}
- #[interrupt(priority = 3)]
- fn GPIOC() {
+ #[task(binds = GPIOC, priority = 3)]
+ fn gpioc(_: gpioc::Context) {
hprintln!("C").unwrap();
}
-};
+}
diff --git a/examples/message.rs b/examples/message.rs
index b5d68a6..f973672 100644
--- a/examples/message.rs
+++ b/examples/message.rs
@@ -5,47 +5,50 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init(spawn = [foo])]
- fn init() {
- spawn.foo(/* no message */).unwrap();
+ fn init(c: init::Context) -> init::LateResources {
+ c.spawn.foo(/* no message */).unwrap();
+
+ init::LateResources {}
}
#[task(spawn = [bar])]
- fn foo() {
+ fn foo(c: foo::Context) {
static mut COUNT: u32 = 0;
hprintln!("foo").unwrap();
- spawn.bar(*COUNT).unwrap();
+ c.spawn.bar(*COUNT).unwrap();
*COUNT += 1;
}
#[task(spawn = [baz])]
- fn bar(x: u32) {
+ fn bar(c: bar::Context, x: u32) {
hprintln!("bar({})", x).unwrap();
- spawn.baz(x + 1, x + 2).unwrap();
+ c.spawn.baz(x + 1, x + 2).unwrap();
}
#[task(spawn = [foo])]
- fn baz(x: u32, y: u32) {
+ fn baz(c: baz::Context, x: u32, y: u32) {
hprintln!("baz({}, {})", x, y).unwrap();
if x + y > 4 {
debug::exit(debug::EXIT_SUCCESS);
}
- spawn.foo().unwrap();
+ c.spawn.foo().unwrap();
}
+ // 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 UART0();
+ fn SSI0();
}
-};
+}
diff --git a/examples/not-send.rs b/examples/not-send.rs
index be78c33..18071fc 100644
--- a/examples/not-send.rs
+++ b/examples/not-send.rs
@@ -5,54 +5,64 @@
#![no_main]
#![no_std]
-extern crate panic_halt;
-
use core::marker::PhantomData;
use cortex_m_semihosting::debug;
-use rtfm::app;
+use panic_halt as _;
+use rtic::app;
pub struct NotSend {
_0: PhantomData<*const ()>,
}
#[app(device = lm3s6965)]
-const APP: () = {
- static mut SHARED: Option<NotSend> = None;
+mod app {
+ use super::NotSend;
+
+ #[resources]
+ struct Resources {
+ #[init(None)]
+ shared: Option<NotSend>,
+ }
#[init(spawn = [baz, quux])]
- fn init() {
- spawn.baz().unwrap();
- spawn.quux().unwrap();
+ fn init(c: init::Context) -> init::LateResources {
+ c.spawn.baz().unwrap();
+ c.spawn.quux().unwrap();
+
+ init::LateResources {}
}
#[task(spawn = [bar])]
- fn foo() {
+ fn foo(c: foo::Context) {
// scenario 1: message passed to task that runs at the same priority
- spawn.bar(NotSend { _0: PhantomData }).ok();
+ c.spawn.bar(NotSend { _0: PhantomData }).ok();
}
#[task]
- fn bar(_x: NotSend) {
+ fn bar(_: bar::Context, _x: NotSend) {
// scenario 1
}
- #[task(priority = 2, resources = [SHARED])]
- fn baz() {
+ #[task(priority = 2, resources = [shared])]
+ fn baz(c: baz::Context) {
// scenario 2: resource shared between tasks that run at the same priority
- *resources.SHARED = Some(NotSend { _0: PhantomData });
+ *c.resources.shared = Some(NotSend { _0: PhantomData });
}
- #[task(priority = 2, resources = [SHARED])]
- fn quux() {
+ #[task(priority = 2, resources = [shared])]
+ fn quux(c: quux::Context) {
// scenario 2
- let _not_send = resources.SHARED.take().unwrap();
+ let _not_send = c.resources.shared.take().unwrap();
debug::exit(debug::EXIT_SUCCESS);
}
+ // 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 UART0();
- fn UART1();
+ fn SSI0();
+ fn QEI0();
}
-};
+}
diff --git a/examples/not-sync.rs b/examples/not-sync.rs
index d94e0a0..75412e6 100644
--- a/examples/not-sync.rs
+++ b/examples/not-sync.rs
@@ -5,37 +5,47 @@
#![no_main]
#![no_std]
-extern crate panic_halt;
-
use core::marker::PhantomData;
use cortex_m_semihosting::debug;
-use rtfm::app;
+use panic_halt as _;
pub struct NotSync {
_0: PhantomData<*const ()>,
}
-#[app(device = lm3s6965)]
-const APP: () = {
- static SHARED: NotSync = NotSync { _0: PhantomData };
+#[rtic::app(device = lm3s6965)]
+mod app {
+ use super::NotSync;
+ use core::marker::PhantomData;
+
+ #[resources]
+ struct Resources {
+ #[init(NotSync { _0: PhantomData })]
+ shared: NotSync,
+ }
#[init]
- fn init() {
+ fn init(_: init::Context) -> init::LateResources {
debug::exit(debug::EXIT_SUCCESS);
+
+ init::LateResources {}
}
- #[task(resources = [SHARED])]
- fn foo() {
- let _: &NotSync = resources.SHARED;
+ #[task(resources = [&shared])]
+ fn foo(c: foo::Context) {
+ let _: &NotSync = c.resources.shared;
}
- #[task(resources = [SHARED])]
- fn bar() {
- let _: &NotSync = resources.SHARED;
+ #[task(resources = [&shared])]
+ fn bar(c: bar::Context) {
+ let _: &NotSync = c.resources.shared;
}
+ // 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 UART0();
+ fn SSI0();
}
-};
+}
diff --git a/examples/only-shared-access.rs b/examples/only-shared-access.rs
new file mode 100644
index 0000000..91d0b7a
--- /dev/null
+++ b/examples/only-shared-access.rs
@@ -0,0 +1,39 @@
+//! examples/static.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::{debug, hprintln};
+use lm3s6965::Interrupt;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ key: u32,
+ }
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
+
+ init::LateResources { key: 0xdeadbeef }
+ }
+
+ #[task(binds = UART0, resources = [&key])]
+ fn uart0(cx: uart0::Context) {
+ let key: &u32 = cx.resources.key;
+ hprintln!("UART0(key = {:#x})", key).unwrap();
+
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+
+ #[task(binds = UART1, priority = 2, resources = [&key])]
+ fn uart1(cx: uart1::Context) {
+ hprintln!("UART1(key = {:#x})", cx.resources.key).unwrap();
+ }
+}
diff --git a/examples/periodic.rs b/examples/periodic.rs
index ba2b493..d3aedd3 100644
--- a/examples/periodic.rs
+++ b/examples/periodic.rs
@@ -5,30 +5,37 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::hprintln;
-use rtfm::{app, Instant};
+use panic_semihosting as _;
+use rtic::cyccnt::{Instant, U32Ext};
const PERIOD: u32 = 8_000_000;
// NOTE: does NOT work on QEMU!
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
+
#[init(schedule = [foo])]
- fn init() {
- schedule.foo(Instant::now() + PERIOD.cycles()).unwrap();
+ fn init(cx: init::Context) -> init::LateResources {
+ // omitted: initialization of `CYCCNT`
+
+ cx.schedule.foo(cx.start + PERIOD.cycles()).unwrap();
+
+ init::LateResources {}
}
#[task(schedule = [foo])]
- fn foo() {
+ fn foo(cx: foo::Context) {
let now = Instant::now();
- hprintln!("foo(scheduled = {:?}, now = {:?})", scheduled, now).unwrap();
+ hprintln!("foo(scheduled = {:?}, now = {:?})", cx.scheduled, now).unwrap();
- schedule.foo(scheduled + PERIOD.cycles()).unwrap();
+ cx.schedule.foo(cx.scheduled + PERIOD.cycles()).unwrap();
}
+ // 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 UART0();
+ fn SSI0();
}
-};
+}
diff --git a/examples/peripherals-taken.rs b/examples/peripherals-taken.rs
new file mode 100644
index 0000000..09f9242
--- /dev/null
+++ b/examples/peripherals-taken.rs
@@ -0,0 +1,18 @@
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::debug;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ assert!(cortex_m::Peripherals::take().is_none());
+ debug::exit(debug::EXIT_SUCCESS);
+
+ init::LateResources {}
+ }
+}
diff --git a/examples/pool.rs b/examples/pool.rs
new file mode 100644
index 0000000..cdbabca
--- /dev/null
+++ b/examples/pool.rs
@@ -0,0 +1,76 @@
+//! examples/pool.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::{debug, hprintln};
+use heapless::{
+ pool,
+ pool::singleton::{Box, Pool},
+};
+use lm3s6965::Interrupt;
+use panic_semihosting as _;
+use rtic::app;
+
+// Declare a pool of 128-byte memory blocks
+pool!(P: [u8; 128]);
+
+#[app(device = lm3s6965)]
+mod app {
+ use crate::Box;
+
+ // Import the memory pool into scope
+ use super::P;
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ static mut MEMORY: [u8; 512] = [0; 512];
+
+ // Increase the capacity of the memory pool by ~4
+ P::grow(MEMORY);
+
+ rtic::pend(Interrupt::I2C0);
+
+ init::LateResources {}
+ }
+
+ #[task(binds = I2C0, priority = 2, spawn = [foo, bar])]
+ fn i2c0(c: i2c0::Context) {
+ // claim a memory block, leave it uninitialized and ..
+ let x = P::alloc().unwrap().freeze();
+
+ // .. send it to the `foo` task
+ c.spawn.foo(x).ok().unwrap();
+
+ // send another block to the task `bar`
+ c.spawn.bar(P::alloc().unwrap().freeze()).ok().unwrap();
+ }
+
+ #[task]
+ fn foo(_: foo::Context, x: Box<P>) {
+ hprintln!("foo({:?})", x.as_ptr()).unwrap();
+
+ // explicitly return the block to the pool
+ drop(x);
+
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+
+ #[task(priority = 2)]
+ fn bar(_: bar::Context, x: Box<P>) {
+ hprintln!("bar({:?})", x.as_ptr()).unwrap();
+
+ // this is done automatically so we can omit the call to `drop`
+ // drop(x);
+ }
+
+ // 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();
+ }
+}
diff --git a/examples/preempt.rs b/examples/preempt.rs
new file mode 100644
index 0000000..f6fc4b0
--- /dev/null
+++ b/examples/preempt.rs
@@ -0,0 +1,39 @@
+//! examples/preempt.rs
+
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::{debug, hprintln};
+use lm3s6965::Interrupt;
+use panic_semihosting as _;
+use rtic::app;
+
+#[app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::GPIOA);
+
+ init::LateResources {}
+ }
+
+ #[task(binds = GPIOA, priority = 1)]
+ fn gpioa(_: gpioa::Context) {
+ hprintln!("GPIOA - start").unwrap();
+ rtic::pend(Interrupt::GPIOC);
+ hprintln!("GPIOA - end").unwrap();
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+
+ #[task(binds = GPIOB, priority = 2)]
+ fn gpiob(_: gpiob::Context) {
+ hprintln!(" GPIOB").unwrap();
+ }
+
+ #[task(binds = GPIOC, priority = 2)]
+ fn gpioc(_: gpioc::Context) {
+ hprintln!(" GPIOC - start").unwrap();
+ rtic::pend(Interrupt::GPIOB);
+ hprintln!(" GPIOC - end").unwrap();
+ }
+}
diff --git a/examples/ramfunc.rs b/examples/ramfunc.rs
index 37ea82a..5ff167a 100644
--- a/examples/ramfunc.rs
+++ b/examples/ramfunc.rs
@@ -5,21 +5,21 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init(spawn = [bar])]
- fn init() {
- spawn.bar().unwrap();
+ fn init(c: init::Context) -> init::LateResources {
+ c.spawn.bar().unwrap();
+
+ init::LateResources {}
}
#[inline(never)]
#[task]
- fn foo() {
+ fn foo(_: foo::Context) {
hprintln!("foo").unwrap();
debug::exit(debug::EXIT_SUCCESS);
@@ -29,8 +29,8 @@ const APP: () = {
#[inline(never)]
#[link_section = ".data.bar"]
#[task(priority = 2, spawn = [foo])]
- fn bar() {
- spawn.foo().unwrap();
+ fn bar(c: bar::Context) {
+ c.spawn.foo().unwrap();
}
extern "C" {
@@ -40,4 +40,4 @@ const APP: () = {
#[link_section = ".data.UART1"]
fn UART1();
}
-};
+}
diff --git a/examples/resource-user-struct.rs b/examples/resource-user-struct.rs
new file mode 100644
index 0000000..a5bd0dd
--- /dev/null
+++ b/examples/resource-user-struct.rs
@@ -0,0 +1,63 @@
+//! examples/resource.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::{debug, hprintln};
+use lm3s6965::Interrupt;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ // A resource
+ #[init(0)]
+ shared: u32,
+ }
+
+ // Should not collide with the struct above
+ #[allow(dead_code)]
+ struct Resources2 {
+ // A resource
+ shared: u32,
+ }
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
+
+ init::LateResources {}
+ }
+
+ // `shared` cannot be accessed from this context
+ #[idle]
+ fn idle(_cx: idle::Context) -> ! {
+ debug::exit(debug::EXIT_SUCCESS);
+
+ // error: no `resources` field in `idle::Context`
+ // _cx.resources.shared += 1;
+
+ loop {}
+ }
+
+ // `shared` can be accessed from this context
+ #[task(binds = UART0, resources = [shared])]
+ fn uart0(cx: uart0::Context) {
+ let shared: &mut u32 = cx.resources.shared;
+ *shared += 1;
+
+ hprintln!("UART0: shared = {}", shared).unwrap();
+ }
+
+ // `shared` can be accessed from this context
+ #[task(binds = UART1, resources = [shared])]
+ fn uart1(cx: uart1::Context) {
+ *cx.resources.shared += 1;
+
+ hprintln!("UART1: shared = {}", cx.resources.shared).unwrap();
+ }
+}
diff --git a/examples/resource.rs b/examples/resource.rs
index 5ddab9e..273af26 100644
--- a/examples/resource.rs
+++ b/examples/resource.rs
@@ -5,46 +5,54 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
-use rtfm::app;
-
-#[app(device = lm3s6965)]
-const APP: () = {
- // A resource
- static mut SHARED: u32 = 0;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ // A resource
+ #[init(0)]
+ shared: u32,
+ }
#[init]
- fn init() {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
+
+ init::LateResources {}
}
+ // `shared` cannot be accessed from this context
#[idle]
- fn idle() -> ! {
+ fn idle(_cx: idle::Context) -> ! {
debug::exit(debug::EXIT_SUCCESS);
- // error: `SHARED` can't be accessed from this context
- // SHARED += 1;
+ // error: no `resources` field in `idle::Context`
+ // _cx.resources.shared += 1;
- loop {}
+ loop {
+ cortex_m::asm::nop();
+ }
}
- // `SHARED` can be access from this context
- #[interrupt(resources = [SHARED])]
- fn UART0() {
- *resources.SHARED += 1;
+ // `shared` can be accessed from this context
+ #[task(binds = UART0, resources = [shared])]
+ fn uart0(cx: uart0::Context) {
+ let shared: &mut u32 = cx.resources.shared;
+ *shared += 1;
- hprintln!("UART0: SHARED = {}", resources.SHARED).unwrap();
+ hprintln!("UART0: shared = {}", shared).unwrap();
}
- // `SHARED` can be access from this context
- #[interrupt(resources = [SHARED])]
- fn UART1() {
- *resources.SHARED += 1;
+ // `shared` can be accessed from this context
+ #[task(binds = UART1, resources = [shared])]
+ fn uart1(cx: uart1::Context) {
+ *cx.resources.shared += 1;
- hprintln!("UART1: SHARED = {}", resources.SHARED).unwrap();
+ hprintln!("UART1: shared = {}", cx.resources.shared).unwrap();
}
-};
+}
diff --git a/examples/schedule.rs b/examples/schedule.rs
index fd63347..7e6adc1 100644
--- a/examples/schedule.rs
+++ b/examples/schedule.rs
@@ -5,38 +5,51 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
+use cortex_m::peripheral::DWT;
use cortex_m_semihosting::hprintln;
-use rtfm::{app, Instant};
+use panic_halt as _;
+use rtic::cyccnt::{Instant, U32Ext as _};
// NOTE: does NOT work on QEMU!
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
#[init(schedule = [foo, bar])]
- fn init() {
- let now = Instant::now();
+ fn init(mut cx: init::Context) -> init::LateResources {
+ // Initialize (enable) the monotonic timer (CYCCNT)
+ cx.core.DCB.enable_trace();
+ // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7)
+ DWT::unlock();
+ cx.core.DWT.enable_cycle_counter();
+
+ // semantically, the monotonic timer is frozen at time "zero" during `init`
+ // NOTE do *not* call `Instant::now` in this context; it will return a nonsense value
+ let now = cx.start; // the start time of the system
hprintln!("init @ {:?}", now).unwrap();
// Schedule `foo` to run 8e6 cycles (clock cycles) in the future
- schedule.foo(now + 8_000_000.cycles()).unwrap();
+ cx.schedule.foo(now + 8_000_000.cycles()).unwrap();
// Schedule `bar` to run 4e6 cycles in the future
- schedule.bar(now + 4_000_000.cycles()).unwrap();
+ cx.schedule.bar(now + 4_000_000.cycles()).unwrap();
+
+ init::LateResources {}
}
#[task]
- fn foo() {
+ fn foo(_: foo::Context) {
hprintln!("foo @ {:?}", Instant::now()).unwrap();
}
#[task]
- fn bar() {
+ fn bar(_: bar::Context) {
hprintln!("bar @ {:?}", Instant::now()).unwrap();
}
+ // 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 UART0();
+ fn SSI0();
}
-};
+}
diff --git a/examples/shared-with-init.rs b/examples/shared-with-init.rs
new file mode 100644
index 0000000..85c7276
--- /dev/null
+++ b/examples/shared-with-init.rs
@@ -0,0 +1,45 @@
+//! `examples/shared-with-init.rs`
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::debug;
+use lm3s6965::Interrupt;
+use panic_halt as _;
+use rtic::app;
+
+pub struct MustBeSend;
+
+#[app(device = lm3s6965)]
+mod app {
+ use super::MustBeSend;
+
+ #[resources]
+ struct Resources {
+ #[init(None)]
+ shared: Option<MustBeSend>,
+ }
+
+ #[init(resources = [shared])]
+ fn init(c: init::Context) -> init::LateResources {
+ // this `message` will be sent to task `UART0`
+ let message = MustBeSend;
+ *c.resources.shared = Some(message);
+
+ rtic::pend(Interrupt::UART0);
+
+ init::LateResources {}
+ }
+
+ #[task(binds = UART0, resources = [shared])]
+ fn uart0(c: uart0::Context) {
+ if let Some(message) = c.resources.shared.take() {
+ // `message` has been received
+ drop(message);
+
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+ }
+}
diff --git a/examples/singleton.rs b/examples/singleton.rs
deleted file mode 100644
index 9e48e54..0000000
--- a/examples/singleton.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-//! examples/singleton.rs
-
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![no_main]
-#![no_std]
-
-extern crate panic_semihosting;
-
-use alloc_singleton::stable::pool::{Box, Pool};
-use cortex_m_semihosting::{debug, hprintln};
-use lm3s6965::Interrupt;
-use rtfm::app;
-
-#[app(device = lm3s6965)]
-const APP: () = {
- #[Singleton(Send)]
- static mut M: [u32; 2] = [0; 2];
-
- static mut P: Pool<M> = ();
-
- #[init(resources = [M])]
- fn init() -> init::LateResources {
- rtfm::pend(Interrupt::I2C0);
-
- init::LateResources {
- P: Pool::new(resources.M),
- }
- }
-
- #[interrupt(
- priority = 2,
- resources = [P],
- spawn = [foo, bar],
- )]
- fn I2C0() {
- spawn.foo(resources.P.alloc(1).unwrap()).unwrap();
- spawn.bar(resources.P.alloc(2).unwrap()).unwrap();
- }
-
- #[task(resources = [P])]
- fn foo(x: Box<M>) {
- hprintln!("foo({})", x).unwrap();
-
- resources.P.lock(|p| p.dealloc(x));
-
- debug::exit(debug::EXIT_SUCCESS);
- }
-
- #[task(priority = 2, resources = [P])]
- fn bar(x: Box<M>) {
- hprintln!("bar({})", x).unwrap();
-
- resources.P.dealloc(x);
- }
-
- extern "C" {
- fn UART0();
- fn UART1();
- }
-};
diff --git a/examples/smallest.rs b/examples/smallest.rs
index e4d86be..b8cbf87 100644
--- a/examples/smallest.rs
+++ b/examples/smallest.rs
@@ -1,17 +1,10 @@
//! examples/smallest.rs
-#![deny(unsafe_code)]
-#![deny(warnings)]
#![no_main]
#![no_std]
-// panic-handler crate
-extern crate panic_semihosting;
-
-use rtfm::app;
+use panic_semihosting as _; // panic handler
+use rtic::app;
#[app(device = lm3s6965)]
-const APP: () = {
- #[init]
- fn init() {}
-};
+mod app {}
diff --git a/examples/static.rs b/examples/static.rs
deleted file mode 100644
index 0309b68..0000000
--- a/examples/static.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-//! examples/static.rs
-
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![no_main]
-#![no_std]
-
-extern crate panic_semihosting;
-
-use cortex_m_semihosting::{debug, hprintln};
-use lm3s6965::Interrupt;
-use rtfm::app;
-
-#[app(device = lm3s6965)]
-const APP: () = {
- static KEY: u32 = ();
-
- #[init]
- fn init() -> init::LateResources {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
-
- init::LateResources { KEY: 0xdeadbeef }
- }
-
- #[interrupt(resources = [KEY])]
- fn UART0() {
- hprintln!("UART0(KEY = {:#x})", resources.KEY).unwrap();
-
- debug::exit(debug::EXIT_SUCCESS);
- }
-
- #[interrupt(priority = 2, resources = [KEY])]
- fn UART1() {
- hprintln!("UART1(KEY = {:#x})", resources.KEY).unwrap();
- }
-};
diff --git a/examples/t-binds.rs b/examples/t-binds.rs
new file mode 100644
index 0000000..3ca4c66
--- /dev/null
+++ b/examples/t-binds.rs
@@ -0,0 +1,34 @@
+//! [compile-pass] Check that `binds` works as advertised
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ init::LateResources {}
+ }
+
+ // Cortex-M exception
+ #[task(binds = SVCall)]
+ fn foo(c: foo::Context) {
+ foo_trampoline(c)
+ }
+
+ // LM3S6965 interrupt
+ #[task(binds = UART0)]
+ fn bar(c: bar::Context) {
+ bar_trampoline(c)
+ }
+}
+
+#[allow(dead_code)]
+fn foo_trampoline(_: foo::Context) {}
+
+#[allow(dead_code)]
+fn bar_trampoline(_: bar::Context) {}
diff --git a/examples/t-cfg-resources.rs b/examples/t-cfg-resources.rs
new file mode 100644
index 0000000..61eb4c7
--- /dev/null
+++ b/examples/t-cfg-resources.rs
@@ -0,0 +1,36 @@
+//! [compile-pass] check that `#[cfg]` attributes applied on resources work
+//!
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ // A resource
+ #[init(0)]
+ shared: u32,
+ // A conditionally compiled resource behind feature_x
+ #[cfg(feature = "feature_x")]
+ x: u32,
+ dummy: (), // dummy such that we have at least one late resource
+ }
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ init::LateResources {
+ // The feature needs to be applied everywhere x is defined or used
+ #[cfg(feature = "feature_x")]
+ x: 0,
+ dummy: (), // dummy such that we have at least one late resource
+ }
+ }
+
+ #[idle]
+ fn idle(_cx: idle::Context) -> ! {
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+}
diff --git a/examples/t-cfg.rs b/examples/t-cfg.rs
new file mode 100644
index 0000000..3da20d4
--- /dev/null
+++ b/examples/t-cfg.rs
@@ -0,0 +1,58 @@
+//! [compile-pass] check that `#[cfg]` attributes are respected
+
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+
+#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
+ #[resources]
+ struct Resources {
+ #[cfg(never)]
+ #[init(0)]
+ foo: u32,
+ }
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ #[cfg(never)]
+ static mut BAR: u32 = 0;
+
+ init::LateResources {}
+ }
+
+ #[idle]
+ fn idle(_: idle::Context) -> ! {
+ #[cfg(never)]
+ static mut BAR: u32 = 0;
+
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+
+ #[task(resources = [foo], schedule = [quux], spawn = [quux])]
+ fn foo(_: foo::Context) {
+ #[cfg(never)]
+ static mut BAR: u32 = 0;
+ }
+
+ #[task(priority = 3, resources = [foo], schedule = [quux], spawn = [quux])]
+ fn bar(_: bar::Context) {
+ #[cfg(never)]
+ static mut BAR: u32 = 0;
+ }
+
+ #[cfg(never)]
+ #[task]
+ fn quux(_: quux::Context) {}
+
+ // 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();
+ }
+}
diff --git a/examples/t-htask-main.rs b/examples/t-htask-main.rs
new file mode 100644
index 0000000..1e38e31
--- /dev/null
+++ b/examples/t-htask-main.rs
@@ -0,0 +1,22 @@
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::debug;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(lm3s6965::Interrupt::UART0);
+
+ init::LateResources {}
+ }
+
+ #[task(binds = UART0)]
+ fn taskmain(_: taskmain::Context) {
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+}
diff --git a/examples/t-idle-main.rs b/examples/t-idle-main.rs
new file mode 100644
index 0000000..9078628
--- /dev/null
+++ b/examples/t-idle-main.rs
@@ -0,0 +1,23 @@
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::debug;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ init::LateResources {}
+ }
+
+ #[idle]
+ fn taskmain(_: taskmain::Context) -> ! {
+ debug::exit(debug::EXIT_SUCCESS);
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+}
diff --git a/examples/t-init-main.rs b/examples/t-init-main.rs
new file mode 100644
index 0000000..7c23cc8
--- /dev/null
+++ b/examples/t-init-main.rs
@@ -0,0 +1,17 @@
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::debug;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ debug::exit(debug::EXIT_SUCCESS);
+
+ init::LateResources {}
+ }
+}
diff --git a/examples/t-late-not-send.rs b/examples/t-late-not-send.rs
new file mode 100644
index 0000000..345d9ae
--- /dev/null
+++ b/examples/t-late-not-send.rs
@@ -0,0 +1,41 @@
+//! [compile-pass] late resources don't need to be `Send` if they are owned by `idle`
+
+#![no_main]
+#![no_std]
+
+use core::marker::PhantomData;
+
+use panic_halt as _;
+
+pub struct NotSend {
+ _0: PhantomData<*const ()>,
+}
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ use super::NotSend;
+
+ #[resources]
+ struct Resources {
+ x: NotSend,
+ #[init(None)]
+ y: Option<NotSend>,
+ }
+
+ #[init(resources = [y])]
+ fn init(c: init::Context) -> init::LateResources {
+ // equivalent to late resource initialization
+ *c.resources.y = Some(NotSend { _0: PhantomData });
+
+ init::LateResources {
+ x: NotSend { _0: PhantomData },
+ }
+ }
+
+ #[idle(resources = [x, y])]
+ fn idle(_: idle::Context) -> ! {
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+}
diff --git a/examples/t-resource.rs b/examples/t-resource.rs
new file mode 100644
index 0000000..91950d3
--- /dev/null
+++ b/examples/t-resource.rs
@@ -0,0 +1,92 @@
+//! [compile-pass] Check code generation of resources
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
+ struct Resources {
+ #[init(0)]
+ o1: u32, // init
+ #[init(0)]
+ o2: u32, // idle
+ #[init(0)]
+ o3: u32, // EXTI0
+ #[init(0)]
+ o4: u32, // idle
+ #[init(0)]
+ o5: u32, // EXTI1
+ #[init(0)]
+ o6: u32, // init
+ #[init(0)]
+ s1: u32, // idle & uart0
+ #[init(0)]
+ s2: u32, // uart0 & uart1
+ #[init(0)]
+ s3: u32, // idle & uart0
+ }
+
+ #[init(resources = [o1, o4, o5, o6, s3])]
+ fn init(c: init::Context) -> init::LateResources {
+ // owned by `init` == `&'static mut`
+ let _: &'static mut u32 = c.resources.o1;
+
+ // owned by `init` == `&'static` if read-only
+ let _: &'static u32 = c.resources.o6;
+
+ // `init` has exclusive access to all resources
+ let _: &mut u32 = c.resources.o4;
+ let _: &mut u32 = c.resources.o5;
+ let _: &mut u32 = c.resources.s3;
+
+ init::LateResources {}
+ }
+
+ #[idle(resources = [o2, &o4, s1, &s3])]
+ fn idle(mut c: idle::Context) -> ! {
+ // owned by `idle` == `&'static mut`
+ let _: &'static mut u32 = c.resources.o2;
+
+ // owned by `idle` == `&'static` if read-only
+ let _: &'static u32 = c.resources.o4;
+
+ // shared with `idle` == `Mutex`
+ c.resources.s1.lock(|_| {});
+
+ // `&` if read-only
+ let _: &u32 = c.resources.s3;
+
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+
+ #[task(binds = UART0, resources = [o3, s1, s2, &s3])]
+ fn uart0(c: uart0::Context) {
+ // owned by interrupt == `&mut`
+ let _: &mut u32 = c.resources.o3;
+
+ // no `Mutex` proxy when access from highest priority task
+ let _: &mut u32 = c.resources.s1;
+
+ // no `Mutex` proxy when co-owned by cooperative (same priority) tasks
+ let _: &mut u32 = c.resources.s2;
+
+ // `&` if read-only
+ let _: &u32 = c.resources.s3;
+ }
+
+ #[task(binds = UART1, resources = [s2, &o5])]
+ fn uart1(c: uart1::Context) {
+ // owned by interrupt == `&` if read-only
+ let _: &u32 = c.resources.o5;
+
+ // no `Mutex` proxy when co-owned by cooperative (same priority) tasks
+ let _: &mut u32 = c.resources.s2;
+ }
+}
diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs
new file mode 100644
index 0000000..d5a6d3f
--- /dev/null
+++ b/examples/t-schedule.rs
@@ -0,0 +1,66 @@
+//! [compile-pass] Check `schedule` code generation
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+use rtic::cyccnt::{Instant, U32Ext as _};
+
+#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
+ #[init(schedule = [foo, bar, baz])]
+ fn init(c: init::Context) -> init::LateResources {
+ let _: Result<(), ()> = c.schedule.foo(c.start + 10.cycles());
+ let _: Result<(), u32> = c.schedule.bar(c.start + 20.cycles(), 0);
+ let _: Result<(), (u32, u32)> = c.schedule.baz(c.start + 30.cycles(), 0, 1);
+
+ init::LateResources {}
+ }
+
+ #[idle(schedule = [foo, bar, baz])]
+ fn idle(c: idle::Context) -> ! {
+ let _: Result<(), ()> = c.schedule.foo(Instant::now() + 40.cycles());
+ let _: Result<(), u32> = c.schedule.bar(Instant::now() + 50.cycles(), 0);
+ let _: Result<(), (u32, u32)> = c.schedule.baz(Instant::now() + 60.cycles(), 0, 1);
+
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+
+ #[task(binds = SVCall, schedule = [foo, bar, baz])]
+ fn svcall(c: svcall::Context) {
+ let _: Result<(), ()> = c.schedule.foo(c.start + 70.cycles());
+ let _: Result<(), u32> = c.schedule.bar(c.start + 80.cycles(), 0);
+ let _: Result<(), (u32, u32)> = c.schedule.baz(c.start + 90.cycles(), 0, 1);
+ }
+
+ #[task(binds = UART0, schedule = [foo, bar, baz])]
+ fn uart0(c: uart0::Context) {
+ let _: Result<(), ()> = c.schedule.foo(c.start + 100.cycles());
+ let _: Result<(), u32> = c.schedule.bar(c.start + 110.cycles(), 0);
+ let _: Result<(), (u32, u32)> = c.schedule.baz(c.start + 120.cycles(), 0, 1);
+ }
+
+ #[task(schedule = [foo, bar, baz])]
+ fn foo(c: foo::Context) {
+ let _: Result<(), ()> = c.schedule.foo(c.scheduled + 130.cycles());
+ let _: Result<(), u32> = c.schedule.bar(c.scheduled + 140.cycles(), 0);
+ let _: Result<(), (u32, u32)> = c.schedule.baz(c.scheduled + 150.cycles(), 0, 1);
+ }
+
+ #[task]
+ fn bar(_: bar::Context, _x: u32) {}
+
+ #[task]
+ fn baz(_: baz::Context, _x: u32, _y: u32) {}
+
+ // 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();
+ }
+}
diff --git a/examples/t-spawn.rs b/examples/t-spawn.rs
new file mode 100644
index 0000000..efb748b
--- /dev/null
+++ b/examples/t-spawn.rs
@@ -0,0 +1,65 @@
+//! [compile-pass] Check code generation of `spawn`
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init(spawn = [foo, bar, baz])]
+ fn init(c: init::Context) -> init::LateResources {
+ let _: Result<(), ()> = c.spawn.foo();
+ let _: Result<(), u32> = c.spawn.bar(0);
+ let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1);
+
+ init::LateResources {}
+ }
+
+ #[idle(spawn = [foo, bar, baz])]
+ fn idle(c: idle::Context) -> ! {
+ let _: Result<(), ()> = c.spawn.foo();
+ let _: Result<(), u32> = c.spawn.bar(0);
+ let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1);
+
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+
+ #[task(binds = SVCall, spawn = [foo, bar, baz])]
+ fn svcall(c: svcall::Context) {
+ let _: Result<(), ()> = c.spawn.foo();
+ let _: Result<(), u32> = c.spawn.bar(0);
+ let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1);
+ }
+
+ #[task(binds = UART0, spawn = [foo, bar, baz])]
+ fn uart0(c: uart0::Context) {
+ let _: Result<(), ()> = c.spawn.foo();
+ let _: Result<(), u32> = c.spawn.bar(0);
+ let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1);
+ }
+
+ #[task(spawn = [foo, bar, baz])]
+ fn foo(c: foo::Context) {
+ let _: Result<(), ()> = c.spawn.foo();
+ let _: Result<(), u32> = c.spawn.bar(0);
+ let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1);
+ }
+
+ #[task]
+ fn bar(_: bar::Context, _x: u32) {}
+
+ #[task]
+ fn baz(_: baz::Context, _x: u32, _y: u32) {}
+
+ // 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();
+ }
+}
diff --git a/examples/t-stask-main.rs b/examples/t-stask-main.rs
new file mode 100644
index 0000000..74335c1
--- /dev/null
+++ b/examples/t-stask-main.rs
@@ -0,0 +1,29 @@
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::debug;
+use panic_semihosting as _;
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[init(spawn = [taskmain])]
+ fn init(cx: init::Context) -> init::LateResources {
+ cx.spawn.taskmain().ok();
+
+ init::LateResources {}
+ }
+
+ #[task]
+ fn taskmain(_: taskmain::Context) {
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+
+ // 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();
+ }
+}
diff --git a/examples/task.rs b/examples/task.rs
index 4f168bb..80a9c43 100644
--- a/examples/task.rs
+++ b/examples/task.rs
@@ -5,47 +5,53 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::{debug, hprintln};
-use rtfm::app;
+use panic_semihosting as _;
-#[app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
#[init(spawn = [foo])]
- fn init() {
- spawn.foo().unwrap();
+ fn init(c: init::Context) -> init::LateResources {
+ c.spawn.foo().unwrap();
+
+ init::LateResources {}
}
#[task(spawn = [bar, baz])]
- fn foo() {
- hprintln!("foo").unwrap();
+ fn foo(c: foo::Context) {
+ hprintln!("foo - start").unwrap();
// spawns `bar` onto the task scheduler
// `foo` and `bar` have the same priority so `bar` will not run until
// after `foo` terminates
- spawn.bar().unwrap();
+ c.spawn.bar().unwrap();
+
+ hprintln!("foo - middle").unwrap();
// spawns `baz` onto the task scheduler
// `baz` has higher priority than `foo` so it immediately preempts `foo`
- spawn.baz().unwrap();
+ c.spawn.baz().unwrap();
+
+ hprintln!("foo - end").unwrap();
}
#[task]
- fn bar() {
+ fn bar(_: bar::Context) {
hprintln!("bar").unwrap();
debug::exit(debug::EXIT_SUCCESS);
}
#[task(priority = 2)]
- fn baz() {
+ fn baz(_: baz::Context) {
hprintln!("baz").unwrap();
}
- // Interrupt handlers used to dispatch software tasks
+ // 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 UART0();
- fn UART1();
+ fn SSI0();
+ fn QEI0();
}
-};
+}
diff --git a/examples/types.rs b/examples/types.rs
index c1b8cd6..251d004 100644
--- a/examples/types.rs
+++ b/examples/types.rs
@@ -5,51 +5,62 @@
#![no_main]
#![no_std]
-extern crate panic_semihosting;
-
use cortex_m_semihosting::debug;
-use rtfm::{app, Exclusive, Instant};
+use panic_semihosting as _;
+use rtic::cyccnt;
-#[app(device = lm3s6965)]
-const APP: () = {
- static mut SHARED: u32 = 0;
+#[rtic::app(device = lm3s6965, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
+mod app {
+ #[resources]
+ struct Resources {
+ #[init(0)]
+ shared: u32,
+ }
#[init(schedule = [foo], spawn = [foo])]
- fn init() {
- let _: Instant = start;
- let _: rtfm::Peripherals = core;
- let _: lm3s6965::Peripherals = device;
- let _: init::Schedule = schedule;
- let _: init::Spawn = spawn;
+ fn init(cx: init::Context) -> init::LateResources {
+ let _: cyccnt::Instant = cx.start;
+ let _: rtic::Peripherals = cx.core;
+ let _: lm3s6965::Peripherals = cx.device;
+ let _: init::Schedule = cx.schedule;
+ let _: init::Spawn = cx.spawn;
debug::exit(debug::EXIT_SUCCESS);
+
+ init::LateResources {}
}
- #[exception(schedule = [foo], spawn = [foo])]
- fn SVCall() {
- let _: Instant = start;
- let _: SVCall::Schedule = schedule;
- let _: SVCall::Spawn = spawn;
+ #[idle(schedule = [foo], spawn = [foo])]
+ fn idle(cx: idle::Context) -> ! {
+ let _: idle::Schedule = cx.schedule;
+ let _: idle::Spawn = cx.spawn;
+
+ loop {
+ cortex_m::asm::nop();
+ }
}
- #[interrupt(resources = [SHARED], schedule = [foo], spawn = [foo])]
- fn UART0() {
- let _: Instant = start;
- let _: resources::SHARED = resources.SHARED;
- let _: UART0::Schedule = schedule;
- let _: UART0::Spawn = spawn;
+ #[task(binds = UART0, resources = [shared], schedule = [foo], spawn = [foo])]
+ fn uart0(cx: uart0::Context) {
+ let _: cyccnt::Instant = cx.start;
+ let _: resources::shared = cx.resources.shared;
+ let _: uart0::Schedule = cx.schedule;
+ let _: uart0::Spawn = cx.spawn;
}
- #[task(priority = 2, resources = [SHARED], schedule = [foo], spawn = [foo])]
- fn foo() {
- let _: Instant = scheduled;
- let _: Exclusive<u32> = resources.SHARED;
- let _: foo::Resources = resources;
- let _: foo::Schedule = schedule;
- let _: foo::Spawn = spawn;
+ #[task(priority = 2, resources = [shared], schedule = [foo], spawn = [foo])]
+ fn foo(cx: foo::Context) {
+ let _: cyccnt::Instant = cx.scheduled;
+ let _: &mut u32 = cx.resources.shared;
+ let _: foo::Resources = cx.resources;
+ let _: foo::Schedule = cx.schedule;
+ let _: foo::Spawn = cx.spawn;
}
+ // 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 UART1();
+ fn SSI0();
}
-};
+}