Skip to content

Commit

Permalink
Merge pull request #16 from hashmismatch/no_std_fixes
Browse files Browse the repository at this point in the history
No_std fixes, heapless shared queue, timers on sub-machine states
  • Loading branch information
rudib authored Jan 24, 2022
2 parents 2f90268 + 42d88b6 commit 0ac9a54
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 20 deletions.
6 changes: 3 additions & 3 deletions finny/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ readme = "../README.md"
derive_more = "0.99.11"
finny_derive = { path = "../finny_derive", version = "0.2.0" }
arraydeque = { version = "0.4", default-features = false }
slog = { version = "2.7.0", optional = true }

slog = { version = "2.7.0", optional = true, default-features = false }
heapless = { version = "0.7" }

[features]
default = ["std", "inspect_slog", "timers_std"]
std = ["arraydeque/std"]
std = ["arraydeque/std", "timers_std", "slog/std", "finny_derive/std"]
inspect_slog = ["slog"]
timers_std = []
generate_plantuml = ["finny_derive/generate_plantuml"]
80 changes: 80 additions & 0 deletions finny/src/fsm/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,79 @@ mod queue_array {

pub use self::queue_array::*;


pub mod heapless_shared {
//! A heapless queue with Clone and Arc support.
use core::sync::atomic::{AtomicUsize, Ordering};

use crate::FsmError;

use super::*;

extern crate alloc;
use alloc::sync::Arc;
use heapless::mpmc::Q64;

/// An unbound event queue that uses `VecDeque`.
pub struct FsmEventQueueHeaplessShared<F: FsmBackend> {
inner: Arc<Inner<F>>
}

impl<F> Clone for FsmEventQueueHeaplessShared<F> where F: FsmBackend {
fn clone(&self) -> Self {
Self { inner: self.inner.clone() }
}
}

struct Inner<F: FsmBackend> {
queue: Q64<<F as FsmBackend>::Events>,
len: AtomicUsize
}

impl<F: FsmBackend> FsmEventQueueHeaplessShared<F> {
pub fn new() -> Self {
let q = Q64::new();
let inner = Inner {
queue: q,
len: AtomicUsize::new(0)
};
FsmEventQueueHeaplessShared {
inner: Arc::new(inner)
}
}
}

impl<F: FsmBackend> FsmEventQueue<F> for FsmEventQueueHeaplessShared<F> {
fn dequeue(&mut self) -> Option<<F as FsmBackend>::Events> {
match self.inner.queue.dequeue() {
Some(e) => {
self.inner.len.fetch_sub(1, Ordering::SeqCst);
Some(e)
},
None => None
}
}

fn len(&self) -> usize {
self.inner.len.load(Ordering::SeqCst)
}
}

impl<F: FsmBackend> FsmEventQueueSender<F> for FsmEventQueueHeaplessShared<F> {
fn enqueue<E: Into<<F as FsmBackend>::Events>>(&mut self, event: E) -> FsmResult<()> {
match self.inner.queue.enqueue(event.into()) {
Ok(_) => {
self.inner.len.fetch_add(1, Ordering::SeqCst);
Ok(())
},
Err(_) => Err(FsmError::QueueOverCapacity)
}
}
}

}

pub struct FsmEventQueueNull<F> {
_ty: PhantomData<F>
}
Expand Down Expand Up @@ -260,6 +333,13 @@ fn test_dequeue_vec_shared() {
test_queue(queue);
}

#[test]
fn test_heapless_shared() {
use self::heapless_shared::FsmEventQueueHeaplessShared;
let queue = FsmEventQueueHeaplessShared::<TestFsm>::new();
test_queue(queue);
}

#[cfg(test)]
fn test_queue<Q: FsmEventQueue<TestFsm>>(mut queue: Q) {
use super::tests_fsm::{Events, EventA};
Expand Down
4 changes: 4 additions & 0 deletions finny/src/inspect/slog.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
extern crate alloc;

use slog::{info, o, error};
use crate::{FsmBackend, FsmBackendImpl, FsmEvent, Inspect, InspectEvent, InspectFsmEvent};
use crate::lib::*;
use AsRef;
use core::fmt::Debug;
use core::any::Any;
use alloc::string::ToString;
use alloc::format;

pub struct InspectSlog {
pub logger: slog::Logger
Expand Down
3 changes: 2 additions & 1 deletion finny_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ keywords = ["fsm", "state"]
proc-macro = true

[features]
default = []
default = ["std"]
std = []
generate_plantuml = []

[dependencies]
Expand Down
8 changes: 4 additions & 4 deletions finny_derive/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,10 +544,10 @@ pub fn generate_fsm_code(fsm: &FsmFnInput, _attr: TokenStream, _input: TokenStre
let mut timers_enter = TokenStream::new();

let state = match &transition.ty {
FsmTransitionType::SelfTransition(FsmStateAction { state: FsmTransitionState::State(st @ FsmState { kind: FsmStateKind::Normal, .. }), .. }) => {
FsmTransitionType::SelfTransition(FsmStateAction { state: FsmTransitionState::State(st @ FsmState { .. }), .. }) => {
Some(st)
},
FsmTransitionType::StateTransition(FsmStateTransition { state_to: FsmTransitionState::State(st @ FsmState { kind: FsmStateKind::Normal, .. }), .. }) => {
FsmTransitionType::StateTransition(FsmStateTransition { state_to: FsmTransitionState::State(st @ FsmState { .. }), .. }) => {
Some(st)
},
_ => None
Expand All @@ -574,10 +574,10 @@ pub fn generate_fsm_code(fsm: &FsmFnInput, _attr: TokenStream, _input: TokenStre
let mut timers_exit = TokenStream::new();

let state = match &transition.ty {
FsmTransitionType::SelfTransition(FsmStateAction { state: FsmTransitionState::State(st @ FsmState { kind: FsmStateKind::Normal, .. }), .. }) => {
FsmTransitionType::SelfTransition(FsmStateAction { state: FsmTransitionState::State(st @ FsmState { .. }), .. }) => {
Some(st)
},
FsmTransitionType::StateTransition(FsmStateTransition { state_from: FsmTransitionState::State(st @ FsmState { kind: FsmStateKind::Normal, .. }), .. }) => {
FsmTransitionType::StateTransition(FsmStateTransition { state_from: FsmTransitionState::State(st @ FsmState { .. }), .. }) => {
Some(st)
},
_ => None
Expand Down
15 changes: 3 additions & 12 deletions finny_nostd_tests/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#![no_std]
#![no_main]
// disabling until no_std + alloc becomes stable
// #![no_std]

use finny::{finny_fsm, FsmFactory, FsmEventQueueArray, inspect::null::InspectNull, FsmTimersNull};
use finny::decl::{FsmBuilder, BuiltFsm};
use heapless::consts::*;

#[no_mangle]
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
pub fn main() {
// Since we are passing a C string the final null character is mandatory
const HELLO: &'static str = "Hello, world!\n\0";
unsafe {
Expand All @@ -21,16 +20,8 @@ pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
let mut fsm = StateMachine::new_with(ctx, queue, inspect, timers).unwrap();
fsm.start().unwrap();
}

0
}

#[panic_handler]
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}


///////////////////////////////////////////////////

#[derive(Debug, Default)]
Expand Down

0 comments on commit 0ac9a54

Please sign in to comment.