-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
see rtic-rs/rfcs#52 for details includes: core proposal and `#[init]` and `memory-watermark` extensions Co-authored-by: Jonas Schievink <[email protected]>
- Loading branch information
1 parent
58a4920
commit 00f09c8
Showing
27 changed files
with
1,098 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
edition = "2018" | ||
name = "rtic-actor-traits" | ||
version = "0.1.0" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#![no_std] | ||
|
||
pub trait Post<M> { | ||
fn post(&mut self, message: M) -> Result<(), M>; | ||
} | ||
|
||
pub trait Receive<M> { | ||
fn receive(&mut self, message: M); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#![no_main] | ||
#![no_std] | ||
|
||
use panic_semihosting as _; | ||
|
||
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] | ||
mod app { | ||
use core::sync::atomic::{AtomicU8, Ordering}; | ||
|
||
use cortex_m_semihosting::{debug, hprintln}; | ||
use rtic_actor_traits::Receive; | ||
|
||
struct Actor; | ||
|
||
struct Message; | ||
|
||
static CALL_COUNT: AtomicU8 = AtomicU8::new(0); | ||
|
||
impl Receive<Message> for Actor { | ||
fn receive(&mut self, _: Message) { | ||
hprintln!("Actor::receive was called").ok(); | ||
CALL_COUNT.store(CALL_COUNT.load(Ordering::Relaxed) + 1, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
#[actors] | ||
struct Actors { | ||
#[subscribe(Message, capacity = 2)] | ||
actor: Actor, | ||
} | ||
|
||
#[init] | ||
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics, Actors) { | ||
assert!(cx.poster.post(Message).is_ok()); | ||
assert!(cx.poster.post(Message).is_ok()); | ||
assert!(cx.poster.post(Message).is_err()); | ||
|
||
( | ||
Shared {}, | ||
Local {}, | ||
init::Monotonics(), | ||
Actors { actor: Actor }, | ||
) | ||
} | ||
|
||
#[idle] | ||
fn idle(_: idle::Context) -> ! { | ||
assert_eq!(2, CALL_COUNT.load(Ordering::Relaxed)); | ||
|
||
loop { | ||
debug::exit(debug::EXIT_SUCCESS); | ||
} | ||
} | ||
|
||
#[shared] | ||
struct Shared {} | ||
|
||
#[local] | ||
struct Local {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#![no_main] | ||
#![no_std] | ||
|
||
use panic_semihosting as _; | ||
|
||
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] | ||
mod app { | ||
use cortex_m_semihosting::{debug, hprintln}; | ||
use rtic_actor_traits::Receive; | ||
|
||
#[derive(Debug)] | ||
struct Actor { | ||
state: i32, | ||
} | ||
|
||
struct AssertActorWasInitialized; | ||
|
||
const INITIAL_STATE: i32 = 42; | ||
|
||
impl Receive<AssertActorWasInitialized> for Actor { | ||
fn receive(&mut self, _: AssertActorWasInitialized) { | ||
assert_eq!(INITIAL_STATE, self.state); | ||
hprintln!("OK").ok(); | ||
debug::exit(debug::EXIT_SUCCESS); | ||
} | ||
} | ||
|
||
#[actors] | ||
struct Actors { | ||
#[subscribe(AssertActorWasInitialized)] | ||
#[init(Actor { state: INITIAL_STATE })] | ||
actor: Actor, | ||
} | ||
|
||
#[init] | ||
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics, Actors) { | ||
cx.poster.post(AssertActorWasInitialized).ok(); | ||
|
||
(Shared {}, Local {}, init::Monotonics(), Actors {}) | ||
} | ||
|
||
#[shared] | ||
struct Shared {} | ||
|
||
#[local] | ||
struct Local {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#![no_main] | ||
#![no_std] | ||
|
||
use panic_semihosting as _; | ||
|
||
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] | ||
mod app { | ||
use core::sync::atomic::{AtomicBool, Ordering}; | ||
|
||
use cortex_m_semihosting::{debug, hprintln}; | ||
use rtic_actor_traits::Receive; | ||
|
||
struct Actor; | ||
|
||
const PAYLOAD: i32 = 42; | ||
|
||
struct Message { | ||
payload: i32, | ||
} | ||
|
||
static RECEIVE_WAS_CALLED: AtomicBool = AtomicBool::new(false); | ||
|
||
impl Receive<Message> for Actor { | ||
fn receive(&mut self, m: Message) { | ||
hprintln!("Actor::receive was called").ok(); | ||
|
||
RECEIVE_WAS_CALLED.store(true, Ordering::Relaxed); | ||
|
||
assert_eq!(PAYLOAD, m.payload); | ||
} | ||
} | ||
|
||
#[actors] | ||
struct Actors { | ||
#[subscribe(Message)] | ||
actor: Actor, | ||
} | ||
|
||
#[init] | ||
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics, Actors) { | ||
cx.poster.post(Message { payload: PAYLOAD }).ok(); | ||
|
||
// receive invocation withheld | ||
assert!(!RECEIVE_WAS_CALLED.load(Ordering::Relaxed)); | ||
|
||
( | ||
Shared {}, | ||
Local {}, | ||
init::Monotonics(), | ||
Actors { actor: Actor }, | ||
) | ||
} | ||
|
||
#[idle] | ||
fn idle(_: idle::Context) -> ! { | ||
// receive invocation must have executed by now | ||
assert!(RECEIVE_WAS_CALLED.load(Ordering::Relaxed)); | ||
|
||
loop { | ||
debug::exit(debug::EXIT_SUCCESS); | ||
} | ||
} | ||
|
||
#[shared] | ||
struct Shared {} | ||
|
||
#[local] | ||
struct Local {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#![no_main] | ||
#![no_std] | ||
|
||
use panic_semihosting as _; | ||
|
||
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA, GPIOB])] | ||
mod app { | ||
use core::sync::atomic::{AtomicBool, Ordering}; | ||
|
||
use cortex_m_semihosting::{debug, hprintln}; | ||
use rtic_actor_traits::Receive; | ||
|
||
struct A; | ||
struct B; | ||
|
||
#[derive(Default)] | ||
struct M { | ||
must_not_be_cloned: bool, | ||
} | ||
|
||
impl Clone for M { | ||
fn clone(&self) -> Self { | ||
assert!(!self.must_not_be_cloned); | ||
M { | ||
must_not_be_cloned: self.must_not_be_cloned, | ||
} | ||
} | ||
} | ||
|
||
impl Receive<M> for A { | ||
fn receive(&mut self, _: M) { | ||
static WAS_CALLED_EXACTLY_ONCE: AtomicBool = AtomicBool::new(false); | ||
hprintln!("A::receive was called").ok(); | ||
assert!(!WAS_CALLED_EXACTLY_ONCE.load(Ordering::Relaxed)); | ||
WAS_CALLED_EXACTLY_ONCE.store(true, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
impl Receive<M> for B { | ||
fn receive(&mut self, _: M) { | ||
static WAS_CALLED_EXACTLY_ONCE: AtomicBool = AtomicBool::new(false); | ||
hprintln!("B::receive was called").ok(); | ||
assert!(!WAS_CALLED_EXACTLY_ONCE.load(Ordering::Relaxed)); | ||
WAS_CALLED_EXACTLY_ONCE.store(true, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
#[actors] | ||
struct Actors { | ||
#[subscribe(M, capacity = 2)] | ||
#[init(A)] | ||
a: A, | ||
|
||
#[subscribe(M, capacity = 1)] | ||
#[init(B)] | ||
b: B, | ||
} | ||
|
||
#[init] | ||
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics, Actors) { | ||
let mut poster = cx.poster; | ||
assert!(poster.post(M::default()).is_ok()); | ||
|
||
// B's message queue is full so message must NOT be cloned | ||
// this must also NOT trigger task A even if it has capacity | ||
assert!(poster | ||
.post(M { | ||
must_not_be_cloned: true | ||
}) | ||
.is_err()); | ||
|
||
(Shared {}, Local {}, init::Monotonics(), Actors {}) | ||
} | ||
|
||
#[idle] | ||
fn idle(_: idle::Context) -> ! { | ||
loop { | ||
debug::exit(debug::EXIT_SUCCESS) | ||
} | ||
} | ||
|
||
#[local] | ||
struct Local {} | ||
|
||
#[shared] | ||
struct Shared {} | ||
} |
Oops, something went wrong.