diff options
| author | Emil Fresk <emil.fresk@gmail.com> | 2023-01-23 20:05:47 +0100 |
|---|---|---|
| committer | Henrik Tjäder <henrik@tjaders.com> | 2023-03-01 00:33:31 +0100 |
| commit | 306aa47170fd59369b7a184924e287dc3706d64d (patch) | |
| tree | 75a331a63a4021f078e330bf2ce4edb1228e2ecf /examples | |
| parent | b8b881f446a226d6f3c4a7db7c9174590b47dbf6 (diff) | |
Add rtic-timer (timerqueue + monotonic) and rtic-monotonics (systick-monotonic)
Diffstat (limited to 'examples')
52 files changed, 0 insertions, 3176 deletions
diff --git a/examples/async-delay.no_rs b/examples/async-delay.no_rs deleted file mode 100644 index fb478c3..0000000 --- a/examples/async-delay.no_rs +++ /dev/null @@ -1,63 +0,0 @@ -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; - - #[init] - fn init(cx: init::Context) -> (Shared, Local) { - hprintln!("init").unwrap(); - - foo::spawn().ok(); - bar::spawn().ok(); - baz::spawn().ok(); - - (Shared {}, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - // debug::exit(debug::EXIT_SUCCESS); - loop { - // hprintln!("idle"); - cortex_m::asm::wfi(); // put the MCU in sleep mode until interrupt occurs - } - } - - #[task] - async fn foo(_cx: foo::Context) { - hprintln!("hello from foo").ok(); - monotonics::delay(100.millis()).await; - hprintln!("bye from foo").ok(); - } - - #[task] - async fn bar(_cx: bar::Context) { - hprintln!("hello from bar").ok(); - monotonics::delay(200.millis()).await; - hprintln!("bye from bar").ok(); - } - - #[task] - async fn baz(_cx: baz::Context) { - hprintln!("hello from baz").ok(); - monotonics::delay(300.millis()).await; - hprintln!("bye from baz").ok(); - - debug::exit(debug::EXIT_SUCCESS); - } -} diff --git a/examples/async-infinite-loop.no_rs b/examples/async-infinite-loop.no_rs deleted file mode 100644 index a95f998..0000000 --- a/examples/async-infinite-loop.no_rs +++ /dev/null @@ -1,53 +0,0 @@ -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; - - #[init] - fn init(cx: init::Context) -> (Shared, Local) { - hprintln!("init").unwrap(); - - foo::spawn().ok(); - - (Shared {}, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - loop { - cortex_m::asm::wfi(); // put the MCU in sleep mode until interrupt occurs - } - } - - // Infinite loops are not allowed in RTIC, however in async tasks they are - if there is an - // await inside the loop. - #[task] - async fn foo(_cx: foo::Context) { - let mut i = 0; - loop { - if i == 5 { - debug::exit(debug::EXIT_SUCCESS); - } - - hprintln!("hello from async {}", i).ok(); - monotonics::delay(100.millis()).await; // This makes it okey! - - i += 1; - } - } -} diff --git a/examples/async-task-multiple-prios.rs b/examples/async-task-multiple-prios.rs deleted file mode 100644 index 5c9674d..0000000 --- a/examples/async-task-multiple-prios.rs +++ /dev/null @@ -1,92 +0,0 @@ -//! examples/async-task-multiple-prios.rs - -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] -#![deny(missing_docs)] - -use panic_semihosting as _; - -// NOTES: -// -// - Async tasks cannot have `#[lock_free]` resources, as they can interleave and each async -// task can have a mutable reference stored. -// - Spawning an async task equates to it being polled once. - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - a: u32, - b: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - hprintln!("init"); - - async_task1::spawn().ok(); - async_task2::spawn().ok(); - async_task3::spawn().ok(); - async_task4::spawn().ok(); - - (Shared { a: 0, b: 0 }, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - loop { - hprintln!("idle"); - debug::exit(debug::EXIT_SUCCESS); - } - } - - #[task(priority = 1, shared = [a, b])] - async fn async_task1(mut cx: async_task1::Context) { - hprintln!( - "hello from async 1 a {}", - cx.shared.a.lock(|a| { - *a += 1; - *a - }) - ); - } - - #[task(priority = 1, shared = [a, b])] - async fn async_task2(mut cx: async_task2::Context) { - hprintln!( - "hello from async 2 a {}", - cx.shared.a.lock(|a| { - *a += 1; - *a - }) - ); - } - - #[task(priority = 2, shared = [a, b])] - async fn async_task3(mut cx: async_task3::Context) { - hprintln!( - "hello from async 3 a {}", - cx.shared.a.lock(|a| { - *a += 1; - *a - }) - ); - } - - #[task(priority = 2, shared = [a, b])] - async fn async_task4(mut cx: async_task4::Context) { - hprintln!( - "hello from async 4 a {}", - cx.shared.a.lock(|a| { - *a += 1; - *a - }) - ); - } -} diff --git a/examples/async-task.rs b/examples/async-task.rs deleted file mode 100644 index 7730c54..0000000 --- a/examples/async-task.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! examples/async-task.rs - -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] -#![deny(missing_docs)] - -use panic_semihosting as _; - -// NOTES: -// -// - Async tasks cannot have `#[lock_free]` resources, as they can interleave and each async -// task can have a mutable reference stored. -// - Spawning an async task equates to it being polled once. - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - a: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_cx: init::Context) -> (Shared, Local) { - hprintln!("init"); - - async_task::spawn().unwrap(); - async_task_args::spawn(1, 2).unwrap(); - async_task2::spawn().unwrap(); - - (Shared { a: 0 }, Local {}) - } - - #[idle(shared = [a])] - fn idle(_: idle::Context) -> ! { - loop { - hprintln!("idle"); - debug::exit(debug::EXIT_SUCCESS); - cortex_m::asm::wfi(); // put the MCU in sleep mode until interrupt occurs - } - } - - #[task(binds = UART1, shared = [a])] - fn hw_task(cx: hw_task::Context) { - let hw_task::SharedResources { a: _, .. } = cx.shared; - hprintln!("hello from hw"); - } - - #[task(shared = [a])] - async fn async_task(cx: async_task::Context) { - let async_task::SharedResources { a: _, .. } = cx.shared; - hprintln!("hello from async"); - } - - #[task] - async fn async_task_args(_cx: async_task_args::Context, a: u32, b: i32) { - hprintln!("hello from async with args a: {}, b: {}", a, b); - } - - #[task(priority = 2, shared = [a])] - async fn async_task2(cx: async_task2::Context) { - let async_task2::SharedResources { a: _, .. } = cx.shared; - hprintln!("hello from async2"); - } -} diff --git a/examples/async-timeout.no_rs b/examples/async-timeout.no_rs deleted file mode 100644 index 3f68df7..0000000 --- a/examples/async-timeout.no_rs +++ /dev/null @@ -1,87 +0,0 @@ -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -// NOTES: -// -// - Async tasks cannot have `#[lock_free]` resources, as they can interleve and each async -// task can have a mutable reference stored. -// - Spawning an async task equates to it being polled once. - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)] -mod app { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll}, - }; - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - hprintln!("init").unwrap(); - - foo::spawn().ok(); - bar::spawn().ok(); - - ( - Shared {}, - Local {}, - init::Monotonics(Systick::new(cx.core.SYST, 12_000_000)), - ) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - loop { - cortex_m::asm::wfi(); // put the MCU in sleep mode until interrupt occurs - } - } - - #[task] - async fn foo(_cx: foo::Context) { - hprintln!("hello from foo").ok(); - - // This will not timeout - match monotonics::timeout_after(monotonics::delay(100.millis()), 200.millis()).await { - Ok(_) => hprintln!("foo no timeout").ok(), - Err(_) => hprintln!("foo timeout").ok(), - }; - } - - #[task] - async fn bar(_cx: bar::Context) { - hprintln!("hello from bar").ok(); - - // This will timeout - match monotonics::timeout_after(NeverEndingFuture {}, 300.millis()).await { - Ok(_) => hprintln!("bar no timeout").ok(), - Err(_) => hprintln!("bar timeout").ok(), - }; - - debug::exit(debug::EXIT_SUCCESS); - } - - pub struct NeverEndingFuture {} - - impl Future for NeverEndingFuture { - type Output = (); - - fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> { - // Never finish - Poll::Pending - } - } -} diff --git a/examples/big-struct-opt.rs b/examples/big-struct-opt.rs deleted file mode 100644 index 408a2de..0000000 --- a/examples/big-struct-opt.rs +++ /dev/null @@ -1,80 +0,0 @@ -//! examples/big-struct-opt.rs -//! -//! Example on how to initialize a large struct without needing to copy it via `LateResources`, -//! effectively saving stack space needed for the copies. - -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] -#![deny(missing_docs)] - -use panic_semihosting as _; - -/// Some big struct -pub struct BigStruct { - /// Big content - pub data: [u8; 2048], -} - -impl BigStruct { - fn new() -> Self { - BigStruct { data: [22; 2048] } - } -} - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use super::BigStruct; - use core::mem::MaybeUninit; - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared { - big_struct: &'static mut BigStruct, - } - - #[local] - struct Local {} - - #[init(local = [bs: MaybeUninit<BigStruct> = MaybeUninit::uninit()])] - fn init(cx: init::Context) -> (Shared, Local) { - let big_struct = unsafe { - // write directly into the static storage - cx.local.bs.as_mut_ptr().write(BigStruct::new()); - &mut *cx.local.bs.as_mut_ptr() - }; - - rtic::pend(Interrupt::UART0); - async_task::spawn().unwrap(); - ( - Shared { - // assign the reference so we can use the resource - big_struct, - }, - Local {}, - ) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - loop { - hprintln!("idle"); - debug::exit(debug::EXIT_SUCCESS); - } - } - - #[task(binds = UART0, shared = [big_struct])] - fn uart0(mut cx: uart0::Context) { - cx.shared - .big_struct - .lock(|b| hprintln!("uart0 data:{:?}", &b.data[0..5])); - } - - #[task(shared = [big_struct], priority = 2)] - async fn async_task(mut cx: async_task::Context) { - cx.shared - .big_struct - .lock(|b| hprintln!("async_task data:{:?}", &b.data[0..5])); - } -} diff --git a/examples/binds.rs b/examples/binds.rs deleted file mode 100644 index cf078ff..0000000 --- a/examples/binds.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! examples/binds.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] -#![deny(missing_docs)] - -use panic_semihosting as _; - -// `examples/interrupt.rs` rewritten to use `binds` -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - rtic::pend(Interrupt::UART0); - - hprintln!("init"); - - (Shared {}, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - hprintln!("idle"); - - rtic::pend(Interrupt::UART0); - - loop { - cortex_m::asm::nop(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - } - - #[task(binds = UART0, local = [times: u32 = 0])] - fn foo(cx: foo::Context) { - *cx.local.times += 1; - - hprintln!( - "foo called {} time{}", - *cx.local.times, - if *cx.local.times > 1 { "s" } else { "" } - ); - } -} diff --git a/examples/cancel-reschedule.no_rs b/examples/cancel-reschedule.no_rs deleted file mode 100644 index a38a9c4..0000000 --- a/examples/cancel-reschedule.no_rs +++ /dev/null @@ -1,73 +0,0 @@ -//! examples/cancel-reschedule.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - - hprintln!("init").ok(); - - // Schedule `foo` to run 1 second in the future - foo::spawn_after(1.secs()).unwrap(); - - ( - Shared {}, - Local {}, - init::Monotonics(mono), // Give the monotonic to RTIC - ) - } - - #[task] - fn foo(_: foo::Context) { - hprintln!("foo").ok(); - - // Schedule `bar` to run 2 seconds in the future (1 second after foo runs) - let spawn_handle = baz::spawn_after(2.secs()).unwrap(); - bar::spawn_after(1.secs(), spawn_handle, false).unwrap(); // Change to true - } - - #[task] - fn bar(_: bar::Context, baz_handle: baz::SpawnHandle, do_reschedule: bool) { - hprintln!("bar").ok(); - - if do_reschedule { - // Reschedule baz 2 seconds from now, instead of the original 1 second - // from now. - baz_handle.reschedule_after(2.secs()).unwrap(); - // Or baz_handle.reschedule_at(/* time */) - } else { - // Or cancel it - baz_handle.cancel().unwrap(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - } - - #[task] - fn baz(_: baz::Context) { - hprintln!("baz").ok(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/capacity.no_rs b/examples/capacity.no_rs deleted file mode 100644 index a617269..0000000 --- a/examples/capacity.no_rs +++ /dev/null @@ -1,49 +0,0 @@ -//! examples/capacity.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - rtic::pend(Interrupt::UART0); - - (Shared {}, Local {}, init::Monotonics()) - } - - #[task(binds = UART0)] - fn uart0(_: uart0::Context) { - foo::spawn(0).unwrap(); - foo::spawn(1).unwrap(); - foo::spawn(2).unwrap(); - foo::spawn(3).unwrap(); - - bar::spawn().unwrap(); - } - - #[task(capacity = 4)] - fn foo(_: foo::Context, x: u32) { - hprintln!("foo({})", x).unwrap(); - } - - #[task] - fn bar(_: bar::Context) { - hprintln!("bar").unwrap(); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/cfg-monotonic.rs b/examples/cfg-monotonic.rs deleted file mode 100644 index 88c0d6f..0000000 --- a/examples/cfg-monotonic.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! examples/cfg-monotonic.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; // Implements the `Monotonic` trait - - // A monotonic timer to enable scheduling in RTIC - #[cfg(feature = "killmono")] - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - // Not allowed by current rtic-syntax: - // error: `#[monotonic(...)]` on a specific type must appear at most once - // --> examples/cfg-monotonic.rs:23:10 - // | - // 23 | type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - // | ^^^^^^ - // #[monotonic(binds = SysTick, default = true)] - // type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - // Not allowed by current rtic-syntax: - // error: this interrupt is already bound - // --> examples/cfg-monotonic.rs:31:25 - // | - // 31 | #[monotonic(binds = SysTick, default = true)] - // | ^^^^^^^ - // #[monotonic(binds = SysTick, default = true)] - // type MyMono2 = DwtSystick<100>; // 100 Hz / 10 ms granularity - - // Resources shared between tasks - #[shared] - struct Shared { - s1: u32, - s2: i32, - } - - // Local resources to specific tasks (cannot be shared) - #[local] - struct Local { - l1: u8, - l2: i8, - } - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let _systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - #[cfg(feature = "killmono")] - let mono = Systick::new(systick, 12_000_000); - - // Spawn the task `foo` directly after `init` finishes - foo::spawn().unwrap(); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - ( - // Initialization of shared resources - Shared { s1: 0, s2: 1 }, - // Initialization of task local resources - Local { l1: 2, l2: 3 }, - // Move the monotonic timer to the RTIC run-time, this enables - // scheduling - #[cfg(feature = "killmono")] - init::Monotonics(mono), - init::Monotonics(), - ) - } - - // Background task, runs whenever no other tasks are running - #[idle] - fn idle(_: idle::Context) -> ! { - loop { - continue; - } - } - - // Software task, not bound to a hardware interrupt. - // This task takes the task local resource `l1` - // The resources `s1` and `s2` are shared between all other tasks. - #[task(shared = [s1, s2], local = [l1])] - fn foo(_: foo::Context) { - // This task is only spawned once in `init`, hence this task will run - // only once - - hprintln!("foo"); - } - - // Software task, also not bound to a hardware interrupt - // This task takes the task local resource `l2` - // The resources `s1` and `s2` are shared between all other tasks. - #[task(shared = [s1, s2], local = [l2])] - fn bar(_: bar::Context) { - hprintln!("bar"); - - // Run `bar` once per second - // bar::spawn_after(1.secs()).unwrap(); - } - - // Hardware task, bound to a hardware interrupt - // The resources `s1` and `s2` are shared between all other tasks. - #[task(binds = UART0, priority = 3, shared = [s1, s2])] - fn uart0_interrupt(_: uart0_interrupt::Context) { - // This task is bound to the interrupt `UART0` and will run - // whenever the interrupt fires - - // Note that RTIC does NOT clear the interrupt flag, this is up to the - // user - - hprintln!("UART0 interrupt!"); - } -} diff --git a/examples/cfg-whole-task.no_rs b/examples/cfg-whole-task.no_rs deleted file mode 100644 index f41866d..0000000 --- a/examples/cfg-whole-task.no_rs +++ /dev/null @@ -1,94 +0,0 @@ -//! examples/cfg-whole-task.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use cortex_m_semihosting::debug; - #[cfg(debug_assertions)] - use cortex_m_semihosting::hprintln; - - #[shared] - struct Shared { - count: u32, - #[cfg(never)] - unused: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - foo::spawn().unwrap(); - foo::spawn().unwrap(); - - ( - Shared { - count: 0, - #[cfg(never)] - unused: 1, - }, - Local {}, - init::Monotonics(), - ) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - loop { - cortex_m::asm::nop(); - } - } - - #[task(capacity = 2, shared = [count])] - fn foo(mut _cx: foo::Context) { - #[cfg(debug_assertions)] - { - _cx.shared.count.lock(|count| *count += 1); - - log::spawn(_cx.shared.count.lock(|count| *count)).unwrap(); - } - - // this wouldn't compile in `release` mode - // *_cx.shared.count += 1; - - // .. - } - - // The whole task should disappear, - // currently still present in the Tasks enum - #[cfg(never)] - #[task(capacity = 2, shared = [count])] - fn foo2(mut _cx: foo2::Context) { - #[cfg(debug_assertions)] - { - _cx.shared.count.lock(|count| *count += 10); - - log::spawn(_cx.shared.count.lock(|count| *count)).unwrap(); - } - - // this wouldn't compile in `release` mode - // *_cx.shared.count += 1; - - // .. - } - - #[cfg(debug_assertions)] - #[task(capacity = 2)] - fn log(_: log::Context, n: u32) { - hprintln!( - "foo has been called {} time{}", - n, - if n == 1 { "" } else { "s" } - ) - .ok(); - } -} diff --git a/examples/common.no_rs b/examples/common.no_rs deleted file mode 100644 index 1fe671e..0000000 --- a/examples/common.no_rs +++ /dev/null @@ -1,102 +0,0 @@ -//! examples/common.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; // Implements the `Monotonic` trait - - // A monotonic timer to enable scheduling in RTIC - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - // Resources shared between tasks - #[shared] - struct Shared { - s1: u32, - s2: i32, - } - - // Local resources to specific tasks (cannot be shared) - #[local] - struct Local { - l1: u8, - l2: i8, - } - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - - // Spawn the task `foo` directly after `init` finishes - foo::spawn().unwrap(); - - // Spawn the task `bar` 1 second after `init` finishes, this is enabled - // by the `#[monotonic(..)]` above - bar::spawn_after(1.secs()).unwrap(); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - ( - // Initialization of shared resources - Shared { s1: 0, s2: 1 }, - // Initialization of task local resources - Local { l1: 2, l2: 3 }, - // Move the monotonic timer to the RTIC run-time, this enables - // scheduling - init::Monotonics(mono), - ) - } - - // Background task, runs whenever no other tasks are running - #[idle] - fn idle(_: idle::Context) -> ! { - loop { - continue; - } - } - - // Software task, not bound to a hardware interrupt. - // This task takes the task local resource `l1` - // The resources `s1` and `s2` are shared between all other tasks. - #[task(shared = [s1, s2], local = [l1])] - fn foo(_: foo::Context) { - // This task is only spawned once in `init`, hence this task will run - // only once - - hprintln!("foo").ok(); - } - - // Software task, also not bound to a hardware interrupt - // This task takes the task local resource `l2` - // The resources `s1` and `s2` are shared between all other tasks. - #[task(shared = [s1, s2], local = [l2])] - fn bar(_: bar::Context) { - hprintln!("bar").ok(); - - // Run `bar` once per second - bar::spawn_after(1.secs()).unwrap(); - } - - // Hardware task, bound to a hardware interrupt - // The resources `s1` and `s2` are shared between all other tasks. - #[task(binds = UART0, priority = 3, shared = [s1, s2])] - fn uart0_interrupt(_: uart0_interrupt::Context) { - // This task is bound to the interrupt `UART0` and will run - // whenever the interrupt fires - - // Note that RTIC does NOT clear the interrupt flag, this is up to the - // user - - hprintln!("UART0 interrupt!").ok(); - } -} diff --git a/examples/complex.rs b/examples/complex.rs deleted file mode 100644 index c1e9c6c..0000000 --- a/examples/complex.rs +++ /dev/null @@ -1,129 +0,0 @@ -//! examples/complex.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared { - s2: u32, // shared with ceiling 2 - s3: u32, // shared with ceiling 3 - s4: u32, // shared with ceiling 4 - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - hprintln!("init"); - - ( - Shared { - s2: 0, - s3: 0, - s4: 0, - }, - Local {}, - ) - } - - #[idle(shared = [s2, s3])] - fn idle(mut cx: idle::Context) -> ! { - hprintln!("idle p0 started"); - rtic::pend(Interrupt::GPIOC); - cx.shared.s3.lock(|s| { - hprintln!("idle enter lock s3 {}", s); - hprintln!("idle pend t0"); - rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 3 - hprintln!("idle pend t1"); - rtic::pend(Interrupt::GPIOB); // t1 p3, with shared ceiling 3 - hprintln!("idle pend t2"); - rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing - hprintln!("idle still in lock s3 {}", s); - }); - hprintln!("\nback in idle"); - - cx.shared.s2.lock(|s| { - hprintln!("enter lock s2 {}", s); - hprintln!("idle pend t0"); - rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2 - hprintln!("idle pend t1"); - rtic::pend(Interrupt::GPIOB); // t1 p3, no sharing - hprintln!("idle pend t2"); - rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing - hprintln!("idle still in lock s2 {}", s); - }); - hprintln!("\nidle exit"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - loop { - cortex_m::asm::nop(); - } - } - - #[task(binds = GPIOA, priority = 2, local = [times: u32 = 0], shared = [s2, s3])] - fn t0(cx: t0::Context) { - // Safe access to local `static mut` variable - *cx.local.times += 1; - - hprintln!( - "t0 p2 called {} time{}", - *cx.local.times, - if *cx.local.times > 1 { "s" } else { "" } - ); - hprintln!("t0 p2 exit"); - } - - #[task(binds = GPIOB, priority = 3, local = [times: u32 = 0], shared = [s3, s4])] - fn t1(mut cx: t1::Context) { - // Safe access to local `static mut` variable - *cx.local.times += 1; - - hprintln!( - "t1 p3 called {} time{}", - *cx.local.times, - if *cx.local.times > 1 { "s" } else { "" } - ); - - cx.shared.s4.lock(|s| { - hprintln!("t1 enter lock s4 {}", s); - hprintln!("t1 pend t0"); - rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2 - hprintln!("t1 pend t2"); - rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing - hprintln!("t1 still in lock s4 {}", s); - }); - - hprintln!("t1 p3 exit"); - } - - #[task(binds = GPIOC, priority = 4, local = [times: u32 = 0], shared = [s4])] - fn t2(mut cx: t2::Context) { - // Safe access to local `static mut` variable - *cx.local.times += 1; - - hprintln!( - "t2 p4 called {} time{}", - *cx.local.times, - if *cx.local.times > 1 { "s" } else { "" } - ); - - cx.shared.s4.lock(|s| { - hprintln!("enter lock s4 {}", s); - *s += 1; - }); - hprintln!("t3 p4 exit"); - } -} diff --git a/examples/declared_locals.rs b/examples/declared_locals.rs deleted file mode 100644 index c845191..0000000 --- a/examples/declared_locals.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! examples/declared_locals.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init(local = [a: u32 = 0])] - fn init(cx: init::Context) -> (Shared, Local) { - // Locals in `#[init]` have 'static lifetime - let _a: &'static mut u32 = cx.local.a; - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}) - } - - #[idle(local = [a: u32 = 0])] - fn idle(cx: idle::Context) -> ! { - // Locals in `#[idle]` have 'static lifetime - let _a: &'static mut u32 = cx.local.a; - - loop {} - } - - #[task(binds = UART0, local = [a: u32 = 0])] - fn foo(cx: foo::Context) { - // Locals in `#[task]`s have a local lifetime - let _a: &mut u32 = cx.local.a; - - // error: explicit lifetime required in the type of `cx` - // let _a: &'static mut u32 = cx.local.a; - } -} diff --git a/examples/destructure.rs b/examples/destructure.rs deleted file mode 100644 index 81eff3b..0000000 --- a/examples/destructure.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! examples/destructure.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [UART0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - a: u32, - b: u32, - c: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - bar::spawn().unwrap(); - - (Shared { a: 0, b: 1, c: 2 }, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop {} - } - - // Direct destructure - #[task(shared = [&a, &b, &c])] - async fn foo(cx: foo::Context) { - let a = cx.shared.a; - let b = cx.shared.b; - let c = cx.shared.c; - - hprintln!("foo: a = {}, b = {}, c = {}", a, b, c); - } - - // De-structure-ing syntax - #[task(shared = [&a, &b, &c])] - async fn bar(cx: bar::Context) { - let bar::SharedResources { a, b, c, .. } = cx.shared; - - hprintln!("bar: a = {}, b = {}, c = {}", a, b, c); - } -} diff --git a/examples/extern_binds.rs b/examples/extern_binds.rs deleted file mode 100644 index 142a11d..0000000 --- a/examples/extern_binds.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! examples/extern_binds.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use cortex_m_semihosting::hprintln; -use panic_semihosting as _; - -// Free function implementing the interrupt bound task `foo`. -fn foo(_: app::foo::Context) { - hprintln!("foo called"); -} - -#[rtic::app(device = lm3s6965)] -mod app { - use crate::foo; - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - rtic::pend(Interrupt::UART0); - - hprintln!("init"); - - (Shared {}, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - hprintln!("idle"); - - rtic::pend(Interrupt::UART0); - - loop { - cortex_m::asm::nop(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - } - - extern "Rust" { - #[task(binds = UART0)] - fn foo(_: foo::Context); - } -} diff --git a/examples/extern_spawn.rs b/examples/extern_spawn.rs deleted file mode 100644 index b2b95b9..0000000 --- a/examples/extern_spawn.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! examples/extern_spawn.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use cortex_m_semihosting::{debug, hprintln}; -use panic_semihosting as _; - -// Free function implementing the spawnable task `foo`. -// Notice, you need to indicate an anonymous lifetime <'a_> -async fn foo(_c: app::foo::Context<'_>) { - hprintln!("foo"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator -} - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use crate::foo; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - - (Shared {}, Local {}) - } - - extern "Rust" { - #[task()] - async fn foo(_c: foo::Context); - } -} diff --git a/examples/generics.rs b/examples/generics.rs deleted file mode 100644 index 2f23cce..0000000 --- a/examples/generics.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! examples/generics.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use cortex_m_semihosting::hprintln; -use panic_semihosting as _; -use rtic::Mutex; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared { - shared: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - rtic::pend(Interrupt::UART0); - rtic::pend(Interrupt::UART1); - - (Shared { shared: 0 }, Local {}) - } - - #[task(binds = UART0, shared = [shared], local = [state: u32 = 0])] - fn uart0(c: uart0::Context) { - hprintln!("UART0(STATE = {})", *c.local.state); - - // second argument has type `shared::shared` - super::advance(c.local.state, c.shared.shared); - - rtic::pend(Interrupt::UART1); - - cortex_m::asm::nop(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - #[task(binds = UART1, priority = 2, shared = [shared], local = [state: u32 = 0])] - fn uart1(c: uart1::Context) { - hprintln!("UART1(STATE = {})", *c.local.state); - - // second argument has type `shared::shared` - super::advance(c.local.state, c.shared.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: &mut u32| { - let old = *shared; - *shared += *state; - (old, *shared) - }); - - hprintln!("shared: {} -> {}", old, new); -} diff --git a/examples/hardware.rs b/examples/hardware.rs deleted file mode 100644 index 62ae0d6..0000000 --- a/examples/hardware.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! examples/hardware.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - // Pends the UART0 interrupt but its handler won't run until *after* - // `init` returns because interrupts are disabled - rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend - - hprintln!("init"); - - (Shared {}, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - // interrupts are enabled again; the `UART0` handler runs at this point - - hprintln!("idle"); - - rtic::pend(Interrupt::UART0); - - loop { - cortex_m::asm::nop(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - } - - #[task(binds = UART0, local = [times: u32 = 0])] - fn uart0(cx: uart0::Context) { - // Safe access to local `static mut` variable - *cx.local.times += 1; - - hprintln!( - "UART0 called {} time{}", - *cx.local.times, - if *cx.local.times > 1 { "s" } else { "" } - ); - } -} diff --git a/examples/idle-wfi.rs b/examples/idle-wfi.rs deleted file mode 100644 index 8134ce3..0000000 --- a/examples/idle-wfi.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! examples/idle-wfi.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(mut cx: init::Context) -> (Shared, Local) { - hprintln!("init"); - - // Set the ARM SLEEPONEXIT bit to go to sleep after handling interrupts - // See https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit - cx.core.SCB.set_sleepdeep(); - - (Shared {}, Local {}) - } - - #[idle(local = [x: u32 = 0])] - fn idle(cx: idle::Context) -> ! { - // Locals in idle have lifetime 'static - let _x: &'static mut u32 = cx.local.x; - - hprintln!("idle"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - loop { - // Now Wait For Interrupt is used instead of a busy-wait loop - // to allow MCU to sleep between interrupts - // https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/WFI - rtic::export::wfi() - } - } -} diff --git a/examples/idle.rs b/examples/idle.rs deleted file mode 100644 index 0c4bd04..0000000 --- a/examples/idle.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! examples/idle.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - hprintln!("init"); - - (Shared {}, Local {}) - } - - #[idle(local = [x: u32 = 0])] - fn idle(cx: idle::Context) -> ! { - // Locals in idle have lifetime 'static - let _x: &'static mut u32 = cx.local.x; - - hprintln!("idle"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - loop { - cortex_m::asm::nop(); - } - } -} diff --git a/examples/init.rs b/examples/init.rs deleted file mode 100644 index c3081bf..0000000 --- a/examples/init.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! examples/init.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, peripherals = true)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init(local = [x: u32 = 0])] - fn init(cx: init::Context) -> (Shared, Local) { - // Cortex-M peripherals - let _core: cortex_m::Peripherals = cx.core; - - // Device specific peripherals - let _device: lm3s6965::Peripherals = cx.device; - - // Locals in `init` have 'static lifetime - let _x: &'static mut u32 = cx.local.x; - - // Access to the critical section token, - // to indicate that this is a critical section - let _cs_token: bare_metal::CriticalSection = cx.cs; - - hprintln!("init"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}) - } -} diff --git a/examples/locals.rs b/examples/locals.rs deleted file mode 100644 index ec3d59d..0000000 --- a/examples/locals.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! examples/locals.rs - -#![feature(type_alias_impl_trait)] -#![deny(unsafe_code)] -#![deny(missing_docs)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local { - local_to_foo: i64, - local_to_bar: i64, - local_to_idle: i64, - } - - // `#[init]` cannot access locals from the `#[local]` struct as they are initialized here. - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - bar::spawn().unwrap(); - - ( - Shared {}, - // initial values for the `#[local]` resources - Local { - local_to_foo: 0, - local_to_bar: 0, - local_to_idle: 0, - }, - ) - } - - // `local_to_idle` can only be accessed from this context - #[idle(local = [local_to_idle])] - fn idle(cx: idle::Context) -> ! { - let local_to_idle = cx.local.local_to_idle; - *local_to_idle += 1; - - hprintln!("idle: local_to_idle = {}", local_to_idle); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - // error: no `local_to_foo` field in `idle::LocalResources` - // _cx.local.local_to_foo += 1; - - // error: no `local_to_bar` field in `idle::LocalResources` - // _cx.local.local_to_bar += 1; - - loop { - cortex_m::asm::nop(); - } - } - - // `local_to_foo` can only be accessed from this context - #[task(local = [local_to_foo])] - async fn foo(cx: foo::Context) { - let local_to_foo = cx.local.local_to_foo; - *local_to_foo += 1; - - // error: no `local_to_bar` field in `foo::LocalResources` - // cx.local.local_to_bar += 1; - - hprintln!("foo: local_to_foo = {}", local_to_foo); - } - - // `local_to_bar` can only be accessed from this context - #[task(local = [local_to_bar])] - async fn bar(cx: bar::Context) { - let local_to_bar = cx.local.local_to_bar; - *local_to_bar += 1; - - // error: no `local_to_foo` field in `bar::LocalResources` - // cx.local.local_to_foo += 1; - - hprintln!("bar: local_to_bar = {}", local_to_bar); - } -} diff --git a/examples/lock-free.no_rs b/examples/lock-free.no_rs deleted file mode 100644 index 053307c..0000000 --- a/examples/lock-free.no_rs +++ /dev/null @@ -1,50 +0,0 @@ -//! examples/lock-free.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - #[lock_free] // <- lock-free shared resource - counter: u64, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - - (Shared { counter: 0 }, Local {}) - } - - #[task(shared = [counter])] // <- same priority - async fn foo(c: foo::Context) { - bar::spawn().unwrap(); - - *c.shared.counter += 1; // <- no lock API required - let counter = *c.shared.counter; - hprintln!(" foo = {}", counter).unwrap(); - } - - #[task(shared = [counter])] // <- same priority - async fn bar(c: bar::Context) { - foo::spawn().unwrap(); - - *c.shared.counter += 1; // <- no lock API required - let counter = *c.shared.counter; - hprintln!(" bar = {}", counter).unwrap(); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/lock.rs b/examples/lock.rs deleted file mode 100644 index 203ae6f..0000000 --- a/examples/lock.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! examples/lock.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [GPIOA, GPIOB, GPIOC])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - shared: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - - (Shared { shared: 0 }, Local {}) - } - - // when omitted priority is assumed to be `1` - #[task(shared = [shared])] - async fn foo(mut c: foo::Context) { - hprintln!("A"); - - // the lower priority task requires a critical section to access the data - c.shared.shared.lock(|shared| { - // data can only be modified within this critical section (closure) - *shared += 1; - - // bar will *not* run right now due to the critical section - bar::spawn().unwrap(); - - hprintln!("B - shared = {}", *shared); - - // baz does not contend for `shared` so it's allowed to run now - baz::spawn().unwrap(); - }); - - // critical section is over: bar can now start - - hprintln!("E"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - #[task(priority = 2, shared = [shared])] - async fn bar(mut c: bar::Context) { - // the higher priority task does still need a critical section - let shared = c.shared.shared.lock(|shared| { - *shared += 1; - - *shared - }); - - hprintln!("D - shared = {}", shared); - } - - #[task(priority = 3)] - async fn baz(_: baz::Context) { - hprintln!("C"); - } -} diff --git a/examples/message.no_rs b/examples/message.no_rs deleted file mode 100644 index 76c5675..0000000 --- a/examples/message.no_rs +++ /dev/null @@ -1,52 +0,0 @@ -//! examples/message.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - foo::spawn(/* no message */).unwrap(); - - (Shared {}, Local {}, init::Monotonics()) - } - - #[task(local = [count: u32 = 0])] - fn foo(cx: foo::Context) { - hprintln!("foo").unwrap(); - - bar::spawn(*cx.local.count).unwrap(); - *cx.local.count += 1; - } - - #[task] - fn bar(_: bar::Context, x: u32) { - hprintln!("bar({})", x).unwrap(); - - baz::spawn(x + 1, x + 2).unwrap(); - } - - #[task] - fn baz(_: baz::Context, x: u32, y: u32) { - hprintln!("baz({}, {})", x, y).unwrap(); - - if x + y > 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - foo::spawn().unwrap(); - } -} diff --git a/examples/message_passing.no_rs b/examples/message_passing.no_rs deleted file mode 100644 index ffa9537..0000000 --- a/examples/message_passing.no_rs +++ /dev/null @@ -1,37 +0,0 @@ -//! examples/message_passing.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - foo::spawn(1, 1).unwrap(); - foo::spawn(1, 2).unwrap(); - foo::spawn(2, 3).unwrap(); - assert!(foo::spawn(1, 4).is_err()); // The capacity of `foo` is reached - - (Shared {}, Local {}, init::Monotonics()) - } - - #[task(capacity = 3)] - fn foo(_c: foo::Context, x: i32, y: u32) { - hprintln!("foo {}, {}", x, y).unwrap(); - if x == 2 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - } -} diff --git a/examples/multilock.rs b/examples/multilock.rs deleted file mode 100644 index 6208cac..0000000 --- a/examples/multilock.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! examples/mutlilock.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - shared1: u32, - shared2: u32, - shared3: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - locks::spawn().unwrap(); - - ( - Shared { - shared1: 0, - shared2: 0, - shared3: 0, - }, - Local {}, - ) - } - - // when omitted priority is assumed to be `1` - #[task(shared = [shared1, shared2, shared3])] - async fn locks(c: locks::Context) { - let s1 = c.shared.shared1; - let s2 = c.shared.shared2; - let s3 = c.shared.shared3; - - (s1, s2, s3).lock(|s1, s2, s3| { - *s1 += 1; - *s2 += 1; - *s3 += 1; - - hprintln!("Multiple locks, s1: {}, s2: {}, s3: {}", *s1, *s2, *s3); - }); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/not-sync.rs b/examples/not-sync.rs deleted file mode 100644 index 6d1ddae..0000000 --- a/examples/not-sync.rs +++ /dev/null @@ -1,69 +0,0 @@ -//! `examples/not-sync.rs` - -// #![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use core::marker::PhantomData; -use panic_semihosting as _; - -/// Not sync -pub struct NotSync { - _0: PhantomData<*const ()>, - data: u32, -} - -unsafe impl Send for NotSync {} - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use super::NotSync; - use core::marker::PhantomData; - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - shared: NotSync, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - hprintln!("init"); - - foo::spawn().unwrap(); - bar::spawn().unwrap(); - ( - Shared { - shared: NotSync { - _0: PhantomData, - data: 13, - }, - }, - Local {}, - ) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop {} - } - - #[task(shared = [&shared])] - async fn foo(c: foo::Context) { - let shared: &NotSync = c.shared.shared; - hprintln!("foo a {}", shared.data); - } - - #[task(shared = [&shared])] - async fn bar(c: bar::Context) { - let shared: &NotSync = c.shared.shared; - hprintln!("bar a {}", shared.data); - } -} diff --git a/examples/only-shared-access.rs b/examples/only-shared-access.rs deleted file mode 100644 index 1d006e6..0000000 --- a/examples/only-shared-access.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! examples/only-shared-access.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - key: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - bar::spawn().unwrap(); - - (Shared { key: 0xdeadbeef }, Local {}) - } - - #[task(shared = [&key])] - async fn foo(cx: foo::Context) { - let key: &u32 = cx.shared.key; - hprintln!("foo(key = {:#x})", key); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - #[task(priority = 2, shared = [&key])] - async fn bar(cx: bar::Context) { - hprintln!("bar(key = {:#x})", cx.shared.key); - } -} diff --git a/examples/periodic-at.no_rs b/examples/periodic-at.no_rs deleted file mode 100644 index ca68ed5..0000000 --- a/examples/periodic-at.no_rs +++ /dev/null @@ -1,49 +0,0 @@ -//! examples/periodic-at.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mut mono = Systick::new(systick, 12_000_000); - - foo::spawn_after(1.secs(), mono.now()).unwrap(); - - (Shared {}, Local {}, init::Monotonics(mono)) - } - - #[task(local = [cnt: u32 = 0])] - fn foo(cx: foo::Context, instant: fugit::TimerInstantU64<100>) { - hprintln!("foo {:?}", instant).ok(); - *cx.local.cnt += 1; - - if *cx.local.cnt == 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - // Periodic every 100 milliseconds - let next_instant = instant + 100.millis(); - foo::spawn_at(next_instant, next_instant).unwrap(); - } -} diff --git a/examples/periodic-at2.no_rs b/examples/periodic-at2.no_rs deleted file mode 100644 index ec9adcc..0000000 --- a/examples/periodic-at2.no_rs +++ /dev/null @@ -1,61 +0,0 @@ -//! examples/periodic-at2.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mut mono = Systick::new(systick, 12_000_000); - - foo::spawn_after(200.millis(), mono.now()).unwrap(); - - (Shared {}, Local {}, init::Monotonics(mono)) - } - - // Using the explicit type of the timer implementation - #[task(local = [cnt: u32 = 0])] - fn foo(cx: foo::Context, instant: fugit::TimerInstantU64<100>) { - hprintln!("foo {:?}", instant).ok(); - *cx.local.cnt += 1; - - if *cx.local.cnt == 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - // Spawn a new message with 100 ms offset to spawned time - let next_instant = instant + 100.millis(); - bar::spawn_at(next_instant, next_instant).unwrap(); - } - - // Using the Instant from the Monotonic trait - // This remains agnostic to the timer implementation - #[task(local = [cnt: u32 = 0])] - fn bar(_cx: bar::Context, instant: <MyMono as rtic_monotonic::Monotonic>::Instant) { - hprintln!("bar {:?}", instant).ok(); - - // Spawn a new message with 200ms offset to spawned time - let next_instant = instant + 200.millis(); - foo::spawn_at(next_instant, next_instant).unwrap(); - } -} diff --git a/examples/periodic.no_rs b/examples/periodic.no_rs deleted file mode 100644 index 2f9e8e6..0000000 --- a/examples/periodic.no_rs +++ /dev/null @@ -1,48 +0,0 @@ -//! examples/periodic.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - - foo::spawn_after(100.millis()).unwrap(); - - (Shared {}, Local {}, init::Monotonics(mono)) - } - - #[task(local = [cnt: u32 = 0])] - fn foo(cx: foo::Context) { - hprintln!("foo").ok(); - *cx.local.cnt += 1; - - if *cx.local.cnt == 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - // Periodic every 100ms - foo::spawn_after(100.millis()).unwrap(); - } -} diff --git a/examples/peripherals-taken.rs b/examples/peripherals-taken.rs deleted file mode 100644 index 2f710e9..0000000 --- a/examples/peripherals-taken.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! examples/peripherals-taken.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - assert!(cortex_m::Peripherals::take().is_none()); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}) - } -} diff --git a/examples/pool.no_rs b/examples/pool.no_rs deleted file mode 100644 index fb8589a..0000000 --- a/examples/pool.no_rs +++ /dev/null @@ -1,70 +0,0 @@ -//! examples/pool.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use heapless::{ - pool, - pool::singleton::{Box, Pool}, -}; -use panic_semihosting as _; -use rtic::app; - -// Declare a pool of 128-byte memory blocks -pool!(P: [u8; 128]); - -#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use crate::{Box, Pool}; - use cortex_m_semihosting::debug; - use lm3s6965::Interrupt; - - // Import the memory pool into scope - use super::P; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init(local = [memory: [u8; 512] = [0; 512]])] - fn init(cx: init::Context) -> (Shared, Local) { - // Increase the capacity of the memory pool by ~4 - P::grow(cx.local.memory); - - rtic::pend(Interrupt::I2C0); - - (Shared {}, Local {}) - } - - #[task(binds = I2C0, priority = 2)] - async fn i2c0(_: i2c0::Context) { - // claim a memory block, initialize it and .. - let x = P::alloc().unwrap().init([0u8; 128]); - - // .. send it to the `foo` task - foo::spawn(x).ok().unwrap(); - - // send another block to the task `bar` - bar::spawn(P::alloc().unwrap().init([0u8; 128])) - .ok() - .unwrap(); - } - - #[task] - async fn foo(_: foo::Context, _x: Box<P>) { - // explicitly return the block to the pool - drop(_x); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - #[task(priority = 2)] - async fn bar(_: bar::Context, _x: Box<P>) { - // this is done automatically so we can omit the call to `drop` - // drop(_x); - } -} diff --git a/examples/preempt.rs b/examples/preempt.rs deleted file mode 100644 index 4b11907..0000000 --- a/examples/preempt.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! examples/preempt.rs - -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] -#![deny(missing_docs)] - -use panic_semihosting as _; -use rtic::app; - -#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - - (Shared {}, Local {}) - } - - #[task(priority = 1)] - async fn foo(_: foo::Context) { - hprintln!("foo - start"); - baz::spawn().unwrap(); - hprintln!("foo - end"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - #[task(priority = 2)] - async fn bar(_: bar::Context) { - hprintln!(" bar"); - } - - #[task(priority = 2)] - async fn baz(_: baz::Context) { - hprintln!(" baz - start"); - bar::spawn().unwrap(); - hprintln!(" baz - end"); - } -} diff --git a/examples/ramfunc.rs b/examples/ramfunc.rs deleted file mode 100644 index e2e7f67..0000000 --- a/examples/ramfunc.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! examples/ramfunc.rs - -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app( - device = lm3s6965, - dispatchers = [ - UART0, - #[link_section = ".data.UART1"] - UART1 - ]) -] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - - (Shared {}, Local {}) - } - - #[inline(never)] - #[task] - async fn foo(_: foo::Context) { - hprintln!("foo"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - // run this task from RAM - #[inline(never)] - #[link_section = ".data.bar"] - #[task(priority = 2)] - async fn bar(_: bar::Context) { - foo::spawn().unwrap(); - } -} diff --git a/examples/resource-user-struct.rs b/examples/resource-user-struct.rs deleted file mode 100644 index fcbacae..0000000 --- a/examples/resource-user-struct.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! examples/resource.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared { - // A resource - shared: u32, - } - - // Should not collide with the struct above - #[allow(dead_code)] - struct Shared2 { - // A resource - shared: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - rtic::pend(Interrupt::UART0); - rtic::pend(Interrupt::UART1); - - (Shared { shared: 0 }, Local {}) - } - - // `shared` cannot be accessed from this context - #[idle] - fn idle(_cx: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - // error: no `shared` field in `idle::Context` - // _cx.shared.shared += 1; - - loop {} - } - - // `shared` can be accessed from this context - #[task(binds = UART0, shared = [shared])] - fn uart0(mut cx: uart0::Context) { - let shared = cx.shared.shared.lock(|shared| { - *shared += 1; - *shared - }); - - hprintln!("UART0: shared = {}", shared); - } - - // `shared` can be accessed from this context - #[task(binds = UART1, shared = [shared])] - fn uart1(mut cx: uart1::Context) { - let shared = cx.shared.shared.lock(|shared| { - *shared += 1; - *shared - }); - - hprintln!("UART1: shared = {}", shared); - } -} diff --git a/examples/schedule.no_rs b/examples/schedule.no_rs deleted file mode 100644 index 5bad5a3..0000000 --- a/examples/schedule.no_rs +++ /dev/null @@ -1,64 +0,0 @@ -//! examples/schedule.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use systick_monotonic::*; - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - - hprintln!("init").ok(); - - // Schedule `foo` to run 1 second in the future - foo::spawn_after(1.secs()).unwrap(); - - ( - Shared {}, - Local {}, - init::Monotonics(mono), // Give the monotonic to RTIC - ) - } - - #[task] - fn foo(_: foo::Context) { - hprintln!("foo").ok(); - - // Schedule `bar` to run 2 seconds in the future (1 second after foo runs) - bar::spawn_after(1.secs()).unwrap(); - } - - #[task] - fn bar(_: bar::Context) { - hprintln!("bar").ok(); - - // Schedule `baz` to run 1 seconds from now, but with a specific time instant. - baz::spawn_at(monotonics::now() + 1.secs()).unwrap(); - } - - #[task] - fn baz(_: baz::Context) { - hprintln!("baz").ok(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/shared.rs b/examples/shared.rs deleted file mode 100644 index d0633fb..0000000 --- a/examples/shared.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! examples/late.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use heapless::spsc::{Consumer, Producer, Queue}; - use lm3s6965::Interrupt; - - #[shared] - struct Shared { - p: Producer<'static, u32, 5>, - c: Consumer<'static, u32, 5>, - } - - #[local] - struct Local {} - - #[init(local = [q: Queue<u32, 5> = Queue::new()])] - fn init(cx: init::Context) -> (Shared, Local) { - let (p, c) = cx.local.q.split(); - - // Initialization of shared resources - (Shared { p, c }, Local {}) - } - - #[idle(shared = [c])] - fn idle(mut c: idle::Context) -> ! { - loop { - if let Some(byte) = c.shared.c.lock(|c| c.dequeue()) { - hprintln!("received message: {}", byte); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } else { - rtic::pend(Interrupt::UART0); - } - } - } - - #[task(binds = UART0, shared = [p])] - fn uart0(mut c: uart0::Context) { - c.shared.p.lock(|p| p.enqueue(42).unwrap()); - } -} diff --git a/examples/smallest.rs b/examples/smallest.rs deleted file mode 100644 index e54ae44..0000000 --- a/examples/smallest.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! examples/smallest.rs - -#![no_main] -#![no_std] -#![deny(missing_docs)] - -use panic_semihosting as _; // panic handler -use rtic::app; - -#[app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - (Shared {}, Local {}) - } -} diff --git a/examples/spawn.rs b/examples/spawn.rs deleted file mode 100644 index d30ecf1..0000000 --- a/examples/spawn.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! examples/spawn.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - hprintln!("init"); - foo::spawn().unwrap(); - - (Shared {}, Local {}) - } - - #[task] - async fn foo(_: foo::Context) { - hprintln!("foo"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/static.rs b/examples/static.rs deleted file mode 100644 index 7f656f4..0000000 --- a/examples/static.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! examples/static.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [UART0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use heapless::spsc::{Consumer, Producer, Queue}; - - #[shared] - struct Shared {} - - #[local] - struct Local { - p: Producer<'static, u32, 5>, - c: Consumer<'static, u32, 5>, - } - - #[init(local = [q: Queue<u32, 5> = Queue::new()])] - fn init(cx: init::Context) -> (Shared, Local) { - // q has 'static life-time so after the split and return of `init` - // it will continue to exist and be allocated - let (p, c) = cx.local.q.split(); - - foo::spawn().unwrap(); - - (Shared {}, Local { p, c }) - } - - #[idle(local = [c])] - fn idle(c: idle::Context) -> ! { - loop { - // Lock-free access to the same underlying queue! - if let Some(data) = c.local.c.dequeue() { - hprintln!("received message: {}", data); - - // Run foo until data - if data == 3 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } else { - foo::spawn().unwrap(); - } - } - } - } - - #[task(local = [p, state: u32 = 0])] - async fn foo(c: foo::Context) { - *c.local.state += 1; - - // Lock-free access to the same underlying queue! - c.local.p.enqueue(*c.local.state).unwrap(); - } -} diff --git a/examples/t-binds.rs b/examples/t-binds.rs deleted file mode 100644 index bdeb391..0000000 --- a/examples/t-binds.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! [compile-pass] Check that `binds` works as advertised - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}) - } - - // Cortex-M exception - #[task(binds = SVCall)] - fn foo(c: foo::Context) { - crate::foo_trampoline(c) - } - - // LM3S6965 interrupt - #[task(binds = UART0)] - fn bar(c: bar::Context) { - crate::bar_trampoline(c) - } -} - -#[allow(dead_code)] -fn foo_trampoline(_: app::foo::Context) {} - -#[allow(dead_code)] -fn bar_trampoline(_: app::bar::Context) {} diff --git a/examples/t-cfg-resources.rs b/examples/t-cfg-resources.rs deleted file mode 100644 index 0328700..0000000 --- a/examples/t-cfg-resources.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! [compile-pass] check that `#[cfg]` attributes applied on resources work - -#![no_main] -#![no_std] -#![deny(missing_docs)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared { - // A conditionally compiled resource behind feature_x - #[cfg(feature = "feature_x")] - x: u32, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - ( - Shared { - #[cfg(feature = "feature_x")] - x: 0, - }, - Local {}, - ) - } - - #[idle] - fn idle(_cx: idle::Context) -> ! { - loop { - cortex_m::asm::nop(); - } - } -} diff --git a/examples/t-htask-main.rs b/examples/t-htask-main.rs deleted file mode 100644 index 8f885bc..0000000 --- a/examples/t-htask-main.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! examples/h-task-main.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - rtic::pend(lm3s6965::Interrupt::UART0); - - (Shared {}, Local {}) - } - - #[task(binds = UART0)] - fn taskmain(_: taskmain::Context) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} diff --git a/examples/t-idle-main.rs b/examples/t-idle-main.rs deleted file mode 100644 index 43215cf..0000000 --- a/examples/t-idle-main.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! examples/t-idle-main.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965)] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - (Shared {}, Local {}) - } - - #[idle] - fn taskmain(_: taskmain::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop { - cortex_m::asm::nop(); - } - } -} diff --git a/examples/t-late-not-send.rs b/examples/t-late-not-send.rs deleted file mode 100644 index 44d1d85..0000000 --- a/examples/t-late-not-send.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! [compile-pass] shared resources don't need to be `Send` if they are owned by `idle` - -#![no_main] -#![no_std] -#![deny(missing_docs)] - -use core::marker::PhantomData; -use panic_semihosting as _; - -/// Not send -pub struct NotSend { - _0: PhantomData<*const ()>, -} - -#[rtic::app(device = lm3s6965)] -mod app { - use super::NotSend; - use core::marker::PhantomData; - use cortex_m_semihosting::debug; - - #[shared] - struct Shared { - x: NotSend, - y: Option<NotSend>, - } - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - ( - Shared { - x: NotSend { _0: PhantomData }, - y: None, - }, - Local {}, - ) - } - - #[idle(shared = [x, y])] - fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop { - cortex_m::asm::nop(); - } - } -} diff --git a/examples/t-schedule.no_rs b/examples/t-schedule.no_rs deleted file mode 100644 index 5ec4208..0000000 --- a/examples/t-schedule.no_rs +++ /dev/null @@ -1,136 +0,0 @@ -//! [compile-pass] Check `schedule` code generation - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::debug; - use systick_monotonic::*; - - #[monotonic(binds = SysTick, default = true)] - type MyMono = Systick<100>; // 100 Hz / 10 ms granularity - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}, init::Monotonics(mono)) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - // Task without message passing - - // Not default - let _: Result<foo::MyMono::SpawnHandle, ()> = - foo::MyMono::spawn_at(monotonics::MyMono::now()); - let handle: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_after(1.secs()); - let _: Result<foo::MyMono::SpawnHandle, ()> = handle.unwrap().reschedule_after(1.secs()); - - let handle: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_after(1.secs()); - let _: Result<foo::MyMono::SpawnHandle, ()> = - handle.unwrap().reschedule_at(monotonics::MyMono::now()); - - let handle: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_after(1.secs()); - let _: Result<(), ()> = handle.unwrap().cancel(); - - // Using default - let _: Result<foo::SpawnHandle, ()> = foo::spawn_at(monotonics::now()); - let handle: Result<foo::SpawnHandle, ()> = foo::spawn_after(1.secs()); - let _: Result<foo::SpawnHandle, ()> = handle.unwrap().reschedule_after(1.secs()); - - let handle: Result<foo::SpawnHandle, ()> = foo::spawn_after(1.secs()); - let _: Result<foo::SpawnHandle, ()> = - handle.unwrap().reschedule_at(monotonics::MyMono::now()); - - let handle: Result<foo::SpawnHandle, ()> = foo::spawn_after(1.secs()); - let _: Result<(), ()> = handle.unwrap().cancel(); - - // Task with single message passing - - // Not default - let _: Result<bar::MyMono::SpawnHandle, u32> = - bar::MyMono::spawn_at(monotonics::MyMono::now(), 0); - let handle: Result<bar::MyMono::SpawnHandle, u32> = bar::MyMono::spawn_after(1.secs(), 1); - let _: Result<bar::MyMono::SpawnHandle, ()> = handle.unwrap().reschedule_after(1.secs()); - - let handle: Result<bar::MyMono::SpawnHandle, u32> = bar::MyMono::spawn_after(1.secs(), 1); - let _: Result<bar::MyMono::SpawnHandle, ()> = - handle.unwrap().reschedule_at(monotonics::MyMono::now()); - - let handle: Result<bar::MyMono::SpawnHandle, u32> = bar::MyMono::spawn_after(1.secs(), 1); - let _: Result<u32, ()> = handle.unwrap().cancel(); - - // Using default - let _: Result<bar::SpawnHandle, u32> = bar::spawn_at(monotonics::MyMono::now(), 0); - let handle: Result<bar::SpawnHandle, u32> = bar::spawn_after(1.secs(), 1); - let _: Result<bar::SpawnHandle, ()> = handle.unwrap().reschedule_after(1.secs()); - - let handle: Result<bar::SpawnHandle, u32> = bar::spawn_after(1.secs(), 1); - let _: Result<bar::SpawnHandle, ()> = - handle.unwrap().reschedule_at(monotonics::MyMono::now()); - - let handle: Result<bar::SpawnHandle, u32> = bar::spawn_after(1.secs(), 1); - let _: Result<u32, ()> = handle.unwrap().cancel(); - - // Task with multiple message passing - - // Not default - let _: Result<baz::MyMono::SpawnHandle, (u32, u32)> = - baz::MyMono::spawn_at(monotonics::MyMono::now(), 0, 1); - let handle: Result<baz::MyMono::SpawnHandle, (u32, u32)> = - baz::MyMono::spawn_after(1.secs(), 1, 2); - let _: Result<baz::MyMono::SpawnHandle, ()> = handle.unwrap().reschedule_after(1.secs()); - - let handle: Result<baz::MyMono::SpawnHandle, (u32, u32)> = - baz::MyMono::spawn_after(1.secs(), 1, 2); - let _: Result<baz::MyMono::SpawnHandle, ()> = - handle.unwrap().reschedule_at(monotonics::MyMono::now()); - - let handle: Result<baz::MyMono::SpawnHandle, (u32, u32)> = - baz::MyMono::spawn_after(1.secs(), 1, 2); - let _: Result<(u32, u32), ()> = handle.unwrap().cancel(); - - // Using default - let _: Result<baz::SpawnHandle, (u32, u32)> = - baz::spawn_at(monotonics::MyMono::now(), 0, 1); - let handle: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_after(1.secs(), 1, 2); - let _: Result<baz::SpawnHandle, ()> = handle.unwrap().reschedule_after(1.secs()); - - let handle: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_after(1.secs(), 1, 2); - let _: Result<baz::SpawnHandle, ()> = - handle.unwrap().reschedule_at(monotonics::MyMono::now()); - - let handle: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_after(1.secs(), 1, 2); - let _: Result<(u32, u32), ()> = handle.unwrap().cancel(); - - loop { - cortex_m::asm::nop(); - } - } - - #[task] - fn foo(_: foo::Context) {} - - #[task] - fn bar(_: bar::Context, _x: u32) {} - - #[task] - fn baz(_: baz::Context, _x: u32, _y: u32) {} -} diff --git a/examples/t-spawn.no_rs b/examples/t-spawn.no_rs deleted file mode 100644 index dad0c83..0000000 --- a/examples/t-spawn.no_rs +++ /dev/null @@ -1,69 +0,0 @@ -//! [compile-pass] Check code generation of `spawn` - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::debug; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - let _: Result<(), ()> = foo::spawn(); - let _: Result<(), u32> = bar::spawn(0); - let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}) - } - - #[idle] - fn idle(_: idle::Context) -> ! { - let _: Result<(), ()> = foo::spawn(); - let _: Result<(), u32> = bar::spawn(0); - let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - - loop { - cortex_m::asm::nop(); - } - } - - #[task(binds = SVCall)] - fn svcall(_: svcall::Context) { - let _: Result<(), ()> = foo::spawn(); - let _: Result<(), u32> = bar::spawn(0); - let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - } - - #[task(binds = UART0)] - fn uart0(_: uart0::Context) { - let _: Result<(), ()> = foo::spawn(); - let _: Result<(), u32> = bar::spawn(0); - let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - } - - #[task] - async fn foo(_: foo::Context) { - let _: Result<(), ()> = foo::spawn(); - let _: Result<(), u32> = bar::spawn(0); - let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - } - - #[task] - async fn bar(_: bar::Context, _x: u32) {} - - #[task] - async fn baz(_: baz::Context, _x: u32, _y: u32) {} -} diff --git a/examples/task.rs b/examples/task.rs deleted file mode 100644 index ab6a1e0..0000000 --- a/examples/task.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! examples/task.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![deny(missing_docs)] -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] - -use panic_semihosting as _; - -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared {} - - #[local] - struct Local {} - - #[init] - fn init(_: init::Context) -> (Shared, Local) { - foo::spawn().unwrap(); - - (Shared {}, Local {}) - } - - #[task] - async fn foo(_: foo::Context) { - hprintln!("foo - start"); - - // spawns `bar` onto the task scheduler - // `foo` and `bar` have the same priority so `bar` will not run until - // after `foo` terminates - bar::spawn().unwrap(); - - hprintln!("foo - middle"); - - // spawns `baz` onto the task scheduler - // `baz` has higher priority than `foo` so it immediately preempts `foo` - baz::spawn().unwrap(); - - hprintln!("foo - end"); - } - - #[task] - async fn bar(_: bar::Context) { - hprintln!("bar"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } - - #[task(priority = 2)] - async fn baz(_: baz::Context) { - hprintln!("baz"); - } -} diff --git a/examples/zero-prio-task.rs b/examples/zero-prio-task.rs deleted file mode 100644 index c810e8f..0000000 --- a/examples/zero-prio-task.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! examples/zero-prio-task.rs - -#![no_main] -#![no_std] -#![feature(type_alias_impl_trait)] -#![deny(missing_docs)] - -use core::marker::PhantomData; -use panic_semihosting as _; - -/// Does not impl send -pub struct NotSend { - _0: PhantomData<*const ()>, -} - -#[rtic::app(device = lm3s6965, peripherals = true)] -mod app { - use super::NotSend; - use core::marker::PhantomData; - use cortex_m_semihosting::{debug, hprintln}; - - #[shared] - struct Shared { - x: NotSend, - } - - #[local] - struct Local { - y: NotSend, - } - - #[init] - fn init(_cx: init::Context) -> (Shared, Local) { - hprintln!("init"); - - async_task::spawn().unwrap(); - async_task2::spawn().unwrap(); - - ( - Shared { - x: NotSend { _0: PhantomData }, - }, - Local { - y: NotSend { _0: PhantomData }, - }, - ) - } - - #[task(priority = 0, shared = [x], local = [y])] - async fn async_task(_: async_task::Context) { - hprintln!("hello from async"); - } - - #[task(priority = 0, shared = [x])] - async fn async_task2(_: async_task2::Context) { - hprintln!("hello from async2"); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - } -} |
