Skip to content

Commit 0ac9a54

Browse files
authored
Merge pull request #16 from hashmismatch/no_std_fixes
No_std fixes, heapless shared queue, timers on sub-machine states
2 parents 2f90268 + 42d88b6 commit 0ac9a54

File tree

6 files changed

+96
-20
lines changed

6 files changed

+96
-20
lines changed

finny/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ readme = "../README.md"
1414
derive_more = "0.99.11"
1515
finny_derive = { path = "../finny_derive", version = "0.2.0" }
1616
arraydeque = { version = "0.4", default-features = false }
17-
slog = { version = "2.7.0", optional = true }
18-
17+
slog = { version = "2.7.0", optional = true, default-features = false }
18+
heapless = { version = "0.7" }
1919

2020
[features]
2121
default = ["std", "inspect_slog", "timers_std"]
22-
std = ["arraydeque/std"]
22+
std = ["arraydeque/std", "timers_std", "slog/std", "finny_derive/std"]
2323
inspect_slog = ["slog"]
2424
timers_std = []
2525
generate_plantuml = ["finny_derive/generate_plantuml"]

finny/src/fsm/queue.rs

+80
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,79 @@ mod queue_array {
171171

172172
pub use self::queue_array::*;
173173

174+
175+
pub mod heapless_shared {
176+
//! A heapless queue with Clone and Arc support.
177+
178+
use core::sync::atomic::{AtomicUsize, Ordering};
179+
180+
use crate::FsmError;
181+
182+
use super::*;
183+
184+
extern crate alloc;
185+
use alloc::sync::Arc;
186+
use heapless::mpmc::Q64;
187+
188+
/// An unbound event queue that uses `VecDeque`.
189+
pub struct FsmEventQueueHeaplessShared<F: FsmBackend> {
190+
inner: Arc<Inner<F>>
191+
}
192+
193+
impl<F> Clone for FsmEventQueueHeaplessShared<F> where F: FsmBackend {
194+
fn clone(&self) -> Self {
195+
Self { inner: self.inner.clone() }
196+
}
197+
}
198+
199+
struct Inner<F: FsmBackend> {
200+
queue: Q64<<F as FsmBackend>::Events>,
201+
len: AtomicUsize
202+
}
203+
204+
impl<F: FsmBackend> FsmEventQueueHeaplessShared<F> {
205+
pub fn new() -> Self {
206+
let q = Q64::new();
207+
let inner = Inner {
208+
queue: q,
209+
len: AtomicUsize::new(0)
210+
};
211+
FsmEventQueueHeaplessShared {
212+
inner: Arc::new(inner)
213+
}
214+
}
215+
}
216+
217+
impl<F: FsmBackend> FsmEventQueue<F> for FsmEventQueueHeaplessShared<F> {
218+
fn dequeue(&mut self) -> Option<<F as FsmBackend>::Events> {
219+
match self.inner.queue.dequeue() {
220+
Some(e) => {
221+
self.inner.len.fetch_sub(1, Ordering::SeqCst);
222+
Some(e)
223+
},
224+
None => None
225+
}
226+
}
227+
228+
fn len(&self) -> usize {
229+
self.inner.len.load(Ordering::SeqCst)
230+
}
231+
}
232+
233+
impl<F: FsmBackend> FsmEventQueueSender<F> for FsmEventQueueHeaplessShared<F> {
234+
fn enqueue<E: Into<<F as FsmBackend>::Events>>(&mut self, event: E) -> FsmResult<()> {
235+
match self.inner.queue.enqueue(event.into()) {
236+
Ok(_) => {
237+
self.inner.len.fetch_add(1, Ordering::SeqCst);
238+
Ok(())
239+
},
240+
Err(_) => Err(FsmError::QueueOverCapacity)
241+
}
242+
}
243+
}
244+
245+
}
246+
174247
pub struct FsmEventQueueNull<F> {
175248
_ty: PhantomData<F>
176249
}
@@ -260,6 +333,13 @@ fn test_dequeue_vec_shared() {
260333
test_queue(queue);
261334
}
262335

336+
#[test]
337+
fn test_heapless_shared() {
338+
use self::heapless_shared::FsmEventQueueHeaplessShared;
339+
let queue = FsmEventQueueHeaplessShared::<TestFsm>::new();
340+
test_queue(queue);
341+
}
342+
263343
#[cfg(test)]
264344
fn test_queue<Q: FsmEventQueue<TestFsm>>(mut queue: Q) {
265345
use super::tests_fsm::{Events, EventA};

finny/src/inspect/slog.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
extern crate alloc;
2+
13
use slog::{info, o, error};
24
use crate::{FsmBackend, FsmBackendImpl, FsmEvent, Inspect, InspectEvent, InspectFsmEvent};
35
use crate::lib::*;
46
use AsRef;
57
use core::fmt::Debug;
68
use core::any::Any;
9+
use alloc::string::ToString;
10+
use alloc::format;
711

812
pub struct InspectSlog {
913
pub logger: slog::Logger

finny_derive/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ keywords = ["fsm", "state"]
1212
proc-macro = true
1313

1414
[features]
15-
default = []
15+
default = ["std"]
16+
std = []
1617
generate_plantuml = []
1718

1819
[dependencies]

finny_derive/src/codegen.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,10 @@ pub fn generate_fsm_code(fsm: &FsmFnInput, _attr: TokenStream, _input: TokenStre
544544
let mut timers_enter = TokenStream::new();
545545

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

576576
let state = match &transition.ty {
577-
FsmTransitionType::SelfTransition(FsmStateAction { state: FsmTransitionState::State(st @ FsmState { kind: FsmStateKind::Normal, .. }), .. }) => {
577+
FsmTransitionType::SelfTransition(FsmStateAction { state: FsmTransitionState::State(st @ FsmState { .. }), .. }) => {
578578
Some(st)
579579
},
580-
FsmTransitionType::StateTransition(FsmStateTransition { state_from: FsmTransitionState::State(st @ FsmState { kind: FsmStateKind::Normal, .. }), .. }) => {
580+
FsmTransitionType::StateTransition(FsmStateTransition { state_from: FsmTransitionState::State(st @ FsmState { .. }), .. }) => {
581581
Some(st)
582582
},
583583
_ => None

finny_nostd_tests/src/main.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
#![no_std]
2-
#![no_main]
1+
// disabling until no_std + alloc becomes stable
2+
// #![no_std]
33

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

8-
#[no_mangle]
9-
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
8+
pub fn main() {
109
// Since we are passing a C string the final null character is mandatory
1110
const HELLO: &'static str = "Hello, world!\n\0";
1211
unsafe {
@@ -21,16 +20,8 @@ pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
2120
let mut fsm = StateMachine::new_with(ctx, queue, inspect, timers).unwrap();
2221
fsm.start().unwrap();
2322
}
24-
25-
0
26-
}
27-
28-
#[panic_handler]
29-
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
30-
loop {}
3123
}
3224

33-
3425
///////////////////////////////////////////////////
3526

3627
#[derive(Debug, Default)]

0 commit comments

Comments
 (0)